通用版本分离
@@ -1,51 +1,32 @@
|
||||
{
|
||||
"polyfillFiles": [
|
||||
"static/chunks/polyfills-42372ed130431b0a.js"
|
||||
"static/chunks/polyfills.js"
|
||||
],
|
||||
"devFiles": [
|
||||
"static/chunks/react-refresh.js"
|
||||
],
|
||||
"devFiles": [],
|
||||
"ampDevFiles": [],
|
||||
"lowPriorityFiles": [
|
||||
"static/zp_R9VejXXm602bhOE99x/_buildManifest.js",
|
||||
"static/zp_R9VejXXm602bhOE99x/_ssgManifest.js"
|
||||
"static/development/_buildManifest.js",
|
||||
"static/development/_ssgManifest.js"
|
||||
],
|
||||
"rootMainFiles": [],
|
||||
"rootMainFilesTree": {},
|
||||
"pages": {
|
||||
"/": [
|
||||
"static/chunks/webpack-85639080fe6da7fb.js",
|
||||
"static/chunks/framework-f1b08387a9bb780e.js",
|
||||
"static/chunks/main-9fed3c39146aca70.js",
|
||||
"static/chunks/3611-aba9696611e4bba8.js",
|
||||
"static/chunks/5122-d345d8239db9d5cc.js",
|
||||
"static/chunks/pages/index-72ddf8a6f948c01e.js"
|
||||
"static/chunks/webpack.js",
|
||||
"static/chunks/main.js",
|
||||
"static/chunks/pages/index.js"
|
||||
],
|
||||
"/_app": [
|
||||
"static/chunks/webpack-85639080fe6da7fb.js",
|
||||
"static/chunks/framework-f1b08387a9bb780e.js",
|
||||
"static/chunks/main-9fed3c39146aca70.js",
|
||||
"static/css/fdb8ca89ae8c8315.css",
|
||||
"static/chunks/pages/_app-1e358084c521d942.js"
|
||||
"static/chunks/webpack.js",
|
||||
"static/chunks/main.js",
|
||||
"static/chunks/pages/_app.js"
|
||||
],
|
||||
"/_error": [
|
||||
"static/chunks/webpack-85639080fe6da7fb.js",
|
||||
"static/chunks/framework-f1b08387a9bb780e.js",
|
||||
"static/chunks/main-9fed3c39146aca70.js",
|
||||
"static/chunks/pages/_error-8fefcd2acbf46e83.js"
|
||||
],
|
||||
"/admin": [
|
||||
"static/chunks/webpack-85639080fe6da7fb.js",
|
||||
"static/chunks/framework-f1b08387a9bb780e.js",
|
||||
"static/chunks/main-9fed3c39146aca70.js",
|
||||
"static/chunks/2389-26601e748f907bec.js",
|
||||
"static/chunks/5122-d345d8239db9d5cc.js",
|
||||
"static/chunks/pages/admin-6e1ae52f9958b681.js"
|
||||
],
|
||||
"/competition": [
|
||||
"static/chunks/webpack-85639080fe6da7fb.js",
|
||||
"static/chunks/framework-f1b08387a9bb780e.js",
|
||||
"static/chunks/main-9fed3c39146aca70.js",
|
||||
"static/chunks/2389-26601e748f907bec.js",
|
||||
"static/chunks/pages/competition-350b6c7d8f0e43b6.js"
|
||||
"static/chunks/webpack.js",
|
||||
"static/chunks/main.js",
|
||||
"static/chunks/pages/_error.js"
|
||||
]
|
||||
},
|
||||
"ampFirstPages": []
|
||||
|
||||
2
.next/cache/.rscinfo
vendored
@@ -1 +1 @@
|
||||
{"encryption.key":"V7SM3BShqYxwraIfypRWETV13ZjjFRkm3ZvO6m947zc=","encryption.expire_at":1764040040301}
|
||||
{"encryption.key":"AxmjrhnEIlWTqaOj84DDbm8NSadx1bBdyyMc77kaHFY=","encryption.expire_at":1766739099583}
|
||||
BIN
.next/cache/webpack/client-development/0.pack.gz
vendored
BIN
.next/cache/webpack/client-development/1.pack.gz
vendored
BIN
.next/cache/webpack/client-development/index.pack.gz
vendored
BIN
.next/cache/webpack/server-development/0.pack.gz
vendored
BIN
.next/cache/webpack/server-development/index.pack.gz
vendored
@@ -1,15 +1,8 @@
|
||||
{
|
||||
"components/JsPlumbInit.js -> jsplumb": {
|
||||
"id": 4642,
|
||||
"id": "components/JsPlumbInit.js -> jsplumb",
|
||||
"files": [
|
||||
"static/chunks/7d858763.1ed868aae9d215d8.js"
|
||||
]
|
||||
},
|
||||
"pages/competition.js -> xlsx": {
|
||||
"id": 2770,
|
||||
"files": [
|
||||
"static/chunks/6f31d389.fcd7f714d97c3d7d.js",
|
||||
"static/chunks/8436.5162d571d476a371.js"
|
||||
"static/chunks/_pages-dir-browser_node_modules_jsplumb_dist_js_jsplumb_js.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
self.__INTERCEPTION_ROUTE_REWRITE_MANIFEST="[]";
|
||||
self.__INTERCEPTION_ROUTE_REWRITE_MANIFEST="[]"
|
||||
@@ -1 +1,35 @@
|
||||
globalThis.__BUILD_MANIFEST={polyfillFiles:["static/chunks/polyfills-42372ed130431b0a.js"],devFiles:[],ampDevFiles:[],lowPriorityFiles:[],rootMainFiles:[],rootMainFilesTree:{},pages:{"/":["static/chunks/webpack-85639080fe6da7fb.js","static/chunks/framework-f1b08387a9bb780e.js","static/chunks/main-9fed3c39146aca70.js","static/chunks/3611-aba9696611e4bba8.js","static/chunks/5122-d345d8239db9d5cc.js","static/chunks/pages/index-72ddf8a6f948c01e.js"],"/_app":["static/chunks/webpack-85639080fe6da7fb.js","static/chunks/framework-f1b08387a9bb780e.js","static/chunks/main-9fed3c39146aca70.js","static/css/fdb8ca89ae8c8315.css","static/chunks/pages/_app-1e358084c521d942.js"],"/_error":["static/chunks/webpack-85639080fe6da7fb.js","static/chunks/framework-f1b08387a9bb780e.js","static/chunks/main-9fed3c39146aca70.js","static/chunks/pages/_error-8fefcd2acbf46e83.js"],"/admin":["static/chunks/webpack-85639080fe6da7fb.js","static/chunks/framework-f1b08387a9bb780e.js","static/chunks/main-9fed3c39146aca70.js","static/chunks/2389-26601e748f907bec.js","static/chunks/5122-d345d8239db9d5cc.js","static/chunks/pages/admin-6e1ae52f9958b681.js"],"/competition":["static/chunks/webpack-85639080fe6da7fb.js","static/chunks/framework-f1b08387a9bb780e.js","static/chunks/main-9fed3c39146aca70.js","static/chunks/2389-26601e748f907bec.js","static/chunks/pages/competition-350b6c7d8f0e43b6.js"]},ampFirstPages:[]},globalThis.__BUILD_MANIFEST.lowPriorityFiles=["/static/"+process.env.__NEXT_BUILD_ID+"/_buildManifest.js",,"/static/"+process.env.__NEXT_BUILD_ID+"/_ssgManifest.js"];
|
||||
globalThis.__BUILD_MANIFEST = {
|
||||
"polyfillFiles": [
|
||||
"static/chunks/polyfills.js"
|
||||
],
|
||||
"devFiles": [
|
||||
"static/chunks/react-refresh.js"
|
||||
],
|
||||
"ampDevFiles": [],
|
||||
"lowPriorityFiles": [],
|
||||
"rootMainFiles": [],
|
||||
"rootMainFilesTree": {},
|
||||
"pages": {
|
||||
"/": [
|
||||
"static/chunks/webpack.js",
|
||||
"static/chunks/main.js",
|
||||
"static/chunks/pages/index.js"
|
||||
],
|
||||
"/_app": [
|
||||
"static/chunks/webpack.js",
|
||||
"static/chunks/main.js",
|
||||
"static/chunks/pages/_app.js"
|
||||
],
|
||||
"/_error": [
|
||||
"static/chunks/webpack.js",
|
||||
"static/chunks/main.js",
|
||||
"static/chunks/pages/_error.js"
|
||||
]
|
||||
},
|
||||
"ampFirstPages": []
|
||||
};
|
||||
globalThis.__BUILD_MANIFEST.lowPriorityFiles = [
|
||||
"/static/" + process.env.__NEXT_BUILD_ID + "/_buildManifest.js",
|
||||
,"/static/" + process.env.__NEXT_BUILD_ID + "/_ssgManifest.js",
|
||||
|
||||
];
|
||||
@@ -1 +1 @@
|
||||
self.__REACT_LOADABLE_MANIFEST='{"components/JsPlumbInit.js -> jsplumb":{"id":4642,"files":["static/chunks/7d858763.1ed868aae9d215d8.js"]},"pages/competition.js -> xlsx":{"id":2770,"files":["static/chunks/6f31d389.fcd7f714d97c3d7d.js","static/chunks/8436.5162d571d476a371.js"]}}';
|
||||
self.__REACT_LOADABLE_MANIFEST="{\"components/JsPlumbInit.js -> jsplumb\":{\"id\":\"components/JsPlumbInit.js -> jsplumb\",\"files\":[\"static/chunks/_pages-dir-browser_node_modules_jsplumb_dist_js_jsplumb_js.js\"]}}"
|
||||
@@ -1 +1 @@
|
||||
self.__NEXT_FONT_MANIFEST='{"pages":{},"app":{},"appUsingSizeAdjust":false,"pagesUsingSizeAdjust":false}';
|
||||
self.__NEXT_FONT_MANIFEST="{\"pages\":{},\"app\":{},\"appUsingSizeAdjust\":false,\"pagesUsingSizeAdjust\":false}"
|
||||
@@ -1,9 +1,6 @@
|
||||
{
|
||||
"/_app": "pages/_app.js",
|
||||
"/_document": "pages/_document.js",
|
||||
"/admin": "pages/admin.html",
|
||||
"/competition": "pages/competition.html",
|
||||
"/_error": "pages/_error.js",
|
||||
"/": "pages/index.html",
|
||||
"/404": "pages/404.html"
|
||||
"/_document": "pages/_document.js",
|
||||
"/": "pages/index.js"
|
||||
}
|
||||
@@ -1 +1,86 @@
|
||||
"use strict";(()=>{var e={};e.id=3220,e.ids=[3220],e.modules={361:e=>{e.exports=require("next/dist/compiled/next-server/pages.runtime.prod.js")},2015:e=>{e.exports=require("react")},3873:e=>{e.exports=require("path")},5425:(e,r,s)=>{s.r(r),s.d(r,{default:()=>a});var t=s(8732),i=s(2341);function a(){return(0,t.jsxs)(i.Html,{lang:"en",children:[(0,t.jsx)(i.Head,{}),(0,t.jsxs)("body",{className:"antialiased",children:[(0,t.jsx)(i.Main,{}),(0,t.jsx)(i.NextScript,{})]})]})}},8732:e=>{e.exports=require("react/jsx-runtime")}};var r=require("../webpack-runtime.js");r.C(e);var s=e=>r(r.s=e),t=r.X(0,[2341],()=>s(5425));module.exports=t})();
|
||||
"use strict";
|
||||
/*
|
||||
* ATTENTION: An "eval-source-map" devtool has been used.
|
||||
* This devtool is neither made for production nor for readable output files.
|
||||
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
||||
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||
* or disable the default devtool with "devtool: false".
|
||||
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||
*/
|
||||
(() => {
|
||||
var exports = {};
|
||||
exports.id = "pages/_document";
|
||||
exports.ids = ["pages/_document"];
|
||||
exports.modules = {
|
||||
|
||||
/***/ "(pages-dir-node)/./src/pages/_document.js":
|
||||
/*!********************************!*\
|
||||
!*** ./src/pages/_document.js ***!
|
||||
\********************************/
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ Document)\n/* harmony export */ });\n/* harmony import */ var react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react/jsx-dev-runtime */ \"react/jsx-dev-runtime\");\n/* harmony import */ var react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var next_document__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! next/document */ \"(pages-dir-node)/./node_modules/next/document.js\");\n/* harmony import */ var next_document__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(next_document__WEBPACK_IMPORTED_MODULE_1__);\n\n\nfunction Document() {\n return /*#__PURE__*/ (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxDEV)(next_document__WEBPACK_IMPORTED_MODULE_1__.Html, {\n lang: \"en\",\n children: [\n /*#__PURE__*/ (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxDEV)(next_document__WEBPACK_IMPORTED_MODULE_1__.Head, {}, void 0, false, {\n fileName: \"/opt/dev/est-dsx/src/pages/_document.js\",\n lineNumber: 6,\n columnNumber: 7\n }, this),\n /*#__PURE__*/ (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxDEV)(\"body\", {\n className: \"antialiased\",\n children: [\n /*#__PURE__*/ (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxDEV)(next_document__WEBPACK_IMPORTED_MODULE_1__.Main, {}, void 0, false, {\n fileName: \"/opt/dev/est-dsx/src/pages/_document.js\",\n lineNumber: 8,\n columnNumber: 9\n }, this),\n /*#__PURE__*/ (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxDEV)(next_document__WEBPACK_IMPORTED_MODULE_1__.NextScript, {}, void 0, false, {\n fileName: \"/opt/dev/est-dsx/src/pages/_document.js\",\n lineNumber: 9,\n columnNumber: 9\n }, this)\n ]\n }, void 0, true, {\n fileName: \"/opt/dev/est-dsx/src/pages/_document.js\",\n lineNumber: 7,\n columnNumber: 7\n }, this)\n ]\n }, void 0, true, {\n fileName: \"/opt/dev/est-dsx/src/pages/_document.js\",\n lineNumber: 5,\n columnNumber: 5\n }, this);\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHBhZ2VzLWRpci1ub2RlKS8uL3NyYy9wYWdlcy9fZG9jdW1lbnQuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQTZEO0FBRTlDLFNBQVNJO0lBQ3RCLHFCQUNFLDhEQUFDSiwrQ0FBSUE7UUFBQ0ssTUFBSzs7MEJBQ1QsOERBQUNKLCtDQUFJQTs7Ozs7MEJBQ0wsOERBQUNLO2dCQUFLQyxXQUFVOztrQ0FDZCw4REFBQ0wsK0NBQUlBOzs7OztrQ0FDTCw4REFBQ0MscURBQVVBOzs7Ozs7Ozs7Ozs7Ozs7OztBQUluQiIsInNvdXJjZXMiOlsiL29wdC9kZXYvZXN0LWRzeC9zcmMvcGFnZXMvX2RvY3VtZW50LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEh0bWwsIEhlYWQsIE1haW4sIE5leHRTY3JpcHQgfSBmcm9tIFwibmV4dC9kb2N1bWVudFwiO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBEb2N1bWVudCgpIHtcbiAgcmV0dXJuIChcbiAgICA8SHRtbCBsYW5nPVwiZW5cIj5cbiAgICAgIDxIZWFkIC8+XG4gICAgICA8Ym9keSBjbGFzc05hbWU9XCJhbnRpYWxpYXNlZFwiPlxuICAgICAgICA8TWFpbiAvPlxuICAgICAgICA8TmV4dFNjcmlwdCAvPlxuICAgICAgPC9ib2R5PlxuICAgIDwvSHRtbD5cbiAgKTtcbn1cbiJdLCJuYW1lcyI6WyJIdG1sIiwiSGVhZCIsIk1haW4iLCJOZXh0U2NyaXB0IiwiRG9jdW1lbnQiLCJsYW5nIiwiYm9keSIsImNsYXNzTmFtZSJdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///(pages-dir-node)/./src/pages/_document.js\n");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "next/dist/compiled/next-server/pages.runtime.dev.js":
|
||||
/*!**********************************************************************!*\
|
||||
!*** external "next/dist/compiled/next-server/pages.runtime.dev.js" ***!
|
||||
\**********************************************************************/
|
||||
/***/ ((module) => {
|
||||
|
||||
module.exports = require("next/dist/compiled/next-server/pages.runtime.dev.js");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "path":
|
||||
/*!***********************!*\
|
||||
!*** external "path" ***!
|
||||
\***********************/
|
||||
/***/ ((module) => {
|
||||
|
||||
module.exports = require("path");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "react":
|
||||
/*!************************!*\
|
||||
!*** external "react" ***!
|
||||
\************************/
|
||||
/***/ ((module) => {
|
||||
|
||||
module.exports = require("react");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "react/jsx-dev-runtime":
|
||||
/*!****************************************!*\
|
||||
!*** external "react/jsx-dev-runtime" ***!
|
||||
\****************************************/
|
||||
/***/ ((module) => {
|
||||
|
||||
module.exports = require("react/jsx-dev-runtime");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "react/jsx-runtime":
|
||||
/*!************************************!*\
|
||||
!*** external "react/jsx-runtime" ***!
|
||||
\************************************/
|
||||
/***/ ((module) => {
|
||||
|
||||
module.exports = require("react/jsx-runtime");
|
||||
|
||||
/***/ })
|
||||
|
||||
};
|
||||
;
|
||||
|
||||
// load runtime
|
||||
var __webpack_require__ = require("../webpack-runtime.js");
|
||||
__webpack_require__.C(exports);
|
||||
var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
|
||||
var __webpack_exports__ = __webpack_require__.X(0, ["vendor-chunks/next"], () => (__webpack_exec__("(pages-dir-node)/./src/pages/_document.js")));
|
||||
module.exports = __webpack_exports__;
|
||||
|
||||
})();
|
||||
@@ -1 +1,267 @@
|
||||
(()=>{"use strict";var e={},r={};function t(o){var a=r[o];if(void 0!==a)return a.exports;var n=r[o]={exports:{}},u=!0;try{e[o](n,n.exports,t),u=!1}finally{u&&delete r[o]}return n.exports}t.m=e,(()=>{var e="function"==typeof Symbol?Symbol("webpack queues"):"__webpack_queues__",r="function"==typeof Symbol?Symbol("webpack exports"):"__webpack_exports__",o="function"==typeof Symbol?Symbol("webpack error"):"__webpack_error__",a=e=>{e&&e.d<1&&(e.d=1,e.forEach(e=>e.r--),e.forEach(e=>e.r--?e.r++:e()))},n=t=>t.map(t=>{if(null!==t&&"object"==typeof t){if(t[e])return t;if(t.then){var n=[];n.d=0,t.then(e=>{u[r]=e,a(n)},e=>{u[o]=e,a(n)});var u={};return u[e]=e=>e(n),u}}var f={};return f[e]=e=>{},f[r]=t,f});t.a=(t,u,f)=>{f&&((p=[]).d=-1);var p,c,l,i,d=new Set,s=t.exports,b=new Promise((e,r)=>{i=r,l=e});b[r]=s,b[e]=e=>(p&&e(p),d.forEach(e),b.catch(e=>{})),t.exports=b,u(t=>{c=n(t);var a,u=()=>c.map(e=>{if(e[o])throw e[o];return e[r]}),f=new Promise(r=>{(a=()=>r(u)).r=0;var t=e=>e!==p&&!d.has(e)&&(d.add(e),e&&!e.d&&(a.r++,e.push(a)));c.map(r=>r[e](t))});return a.r?f:u()},e=>(e?i(b[o]=e):l(s),a(p))),p&&p.d<0&&(p.d=0)}})(),t.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return t.d(r,{a:r}),r},(()=>{var e,r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;t.t=function(o,a){if(1&a&&(o=this(o)),8&a||"object"==typeof o&&o&&(4&a&&o.__esModule||16&a&&"function"==typeof o.then))return o;var n=Object.create(null);t.r(n);var u={};e=e||[null,r({}),r([]),r(r)];for(var f=2&a&&o;"object"==typeof f&&!~e.indexOf(f);f=r(f))Object.getOwnPropertyNames(f).forEach(e=>u[e]=()=>o[e]);return u.default=()=>o,t.d(n,u),n}})(),t.d=(e,r)=>{for(var o in r)t.o(r,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:r[o]})},t.f={},t.e=e=>Promise.all(Object.keys(t.f).reduce((r,o)=>(t.f[o](e,r),r),[])),t.u=e=>""+e+".js",t.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),t.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.X=(e,r,o)=>{var a=r;o||(r=e,o=()=>t(t.s=a)),r.map(t.e,t);var n=o();return void 0===n?e:n},(()=>{var e={7311:1},r=r=>{var o=r.modules,a=r.ids,n=r.runtime;for(var u in o)t.o(o,u)&&(t.m[u]=o[u]);n&&n(t);for(var f=0;f<a.length;f++)e[a[f]]=1};t.f.require=(o,a)=>{e[o]||(7311!=o?r(require("./chunks/"+t.u(o))):e[o]=1)},module.exports=t,t.C=r})()})();
|
||||
/*
|
||||
* ATTENTION: An "eval-source-map" devtool has been used.
|
||||
* This devtool is neither made for production nor for readable output files.
|
||||
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
||||
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||
* or disable the default devtool with "devtool: false".
|
||||
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||
*/
|
||||
/******/ (() => { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
/******/ var __webpack_modules__ = ({});
|
||||
/************************************************************************/
|
||||
/******/ // The module cache
|
||||
/******/ var __webpack_module_cache__ = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/ // Check if module is in cache
|
||||
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||||
/******/ if (cachedModule !== undefined) {
|
||||
/******/ return cachedModule.exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||||
/******/ // no module.id needed
|
||||
/******/ // no module.loaded needed
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ var threw = true;
|
||||
/******/ try {
|
||||
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||
/******/ threw = false;
|
||||
/******/ } finally {
|
||||
/******/ if(threw) delete __webpack_module_cache__[moduleId];
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = __webpack_modules__;
|
||||
/******/
|
||||
/************************************************************************/
|
||||
/******/ /* webpack/runtime/async module */
|
||||
/******/ (() => {
|
||||
/******/ var webpackQueues = typeof Symbol === "function" ? Symbol("webpack queues") : "__webpack_queues__";
|
||||
/******/ var webpackExports = typeof Symbol === "function" ? Symbol("webpack exports") : "__webpack_exports__";
|
||||
/******/ var webpackError = typeof Symbol === "function" ? Symbol("webpack error") : "__webpack_error__";
|
||||
/******/ var resolveQueue = (queue) => {
|
||||
/******/ if(queue && queue.d < 1) {
|
||||
/******/ queue.d = 1;
|
||||
/******/ queue.forEach((fn) => (fn.r--));
|
||||
/******/ queue.forEach((fn) => (fn.r-- ? fn.r++ : fn()));
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ var wrapDeps = (deps) => (deps.map((dep) => {
|
||||
/******/ if(dep !== null && typeof dep === "object") {
|
||||
/******/ if(dep[webpackQueues]) return dep;
|
||||
/******/ if(dep.then) {
|
||||
/******/ var queue = [];
|
||||
/******/ queue.d = 0;
|
||||
/******/ dep.then((r) => {
|
||||
/******/ obj[webpackExports] = r;
|
||||
/******/ resolveQueue(queue);
|
||||
/******/ }, (e) => {
|
||||
/******/ obj[webpackError] = e;
|
||||
/******/ resolveQueue(queue);
|
||||
/******/ });
|
||||
/******/ var obj = {};
|
||||
/******/ obj[webpackQueues] = (fn) => (fn(queue));
|
||||
/******/ return obj;
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ var ret = {};
|
||||
/******/ ret[webpackQueues] = x => {};
|
||||
/******/ ret[webpackExports] = dep;
|
||||
/******/ return ret;
|
||||
/******/ }));
|
||||
/******/ __webpack_require__.a = (module, body, hasAwait) => {
|
||||
/******/ var queue;
|
||||
/******/ hasAwait && ((queue = []).d = -1);
|
||||
/******/ var depQueues = new Set();
|
||||
/******/ var exports = module.exports;
|
||||
/******/ var currentDeps;
|
||||
/******/ var outerResolve;
|
||||
/******/ var reject;
|
||||
/******/ var promise = new Promise((resolve, rej) => {
|
||||
/******/ reject = rej;
|
||||
/******/ outerResolve = resolve;
|
||||
/******/ });
|
||||
/******/ promise[webpackExports] = exports;
|
||||
/******/ promise[webpackQueues] = (fn) => (queue && fn(queue), depQueues.forEach(fn), promise["catch"](x => {}));
|
||||
/******/ module.exports = promise;
|
||||
/******/ body((deps) => {
|
||||
/******/ currentDeps = wrapDeps(deps);
|
||||
/******/ var fn;
|
||||
/******/ var getResult = () => (currentDeps.map((d) => {
|
||||
/******/ if(d[webpackError]) throw d[webpackError];
|
||||
/******/ return d[webpackExports];
|
||||
/******/ }))
|
||||
/******/ var promise = new Promise((resolve) => {
|
||||
/******/ fn = () => (resolve(getResult));
|
||||
/******/ fn.r = 0;
|
||||
/******/ var fnQueue = (q) => (q !== queue && !depQueues.has(q) && (depQueues.add(q), q && !q.d && (fn.r++, q.push(fn))));
|
||||
/******/ currentDeps.map((dep) => (dep[webpackQueues](fnQueue)));
|
||||
/******/ });
|
||||
/******/ return fn.r ? promise : getResult();
|
||||
/******/ }, (err) => ((err ? reject(promise[webpackError] = err) : outerResolve(exports)), resolveQueue(queue)));
|
||||
/******/ queue && queue.d < 0 && (queue.d = 0);
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/compat get default export */
|
||||
/******/ (() => {
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = (module) => {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ () => (module['default']) :
|
||||
/******/ () => (module);
|
||||
/******/ __webpack_require__.d(getter, { a: getter });
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/create fake namespace object */
|
||||
/******/ (() => {
|
||||
/******/ var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__);
|
||||
/******/ var leafPrototypes;
|
||||
/******/ // create a fake namespace object
|
||||
/******/ // mode & 1: value is a module id, require it
|
||||
/******/ // mode & 2: merge all properties of value into the ns
|
||||
/******/ // mode & 4: return value when already ns object
|
||||
/******/ // mode & 16: return value when it's Promise-like
|
||||
/******/ // mode & 8|1: behave like require
|
||||
/******/ __webpack_require__.t = function(value, mode) {
|
||||
/******/ if(mode & 1) value = this(value);
|
||||
/******/ if(mode & 8) return value;
|
||||
/******/ if(typeof value === 'object' && value) {
|
||||
/******/ if((mode & 4) && value.__esModule) return value;
|
||||
/******/ if((mode & 16) && typeof value.then === 'function') return value;
|
||||
/******/ }
|
||||
/******/ var ns = Object.create(null);
|
||||
/******/ __webpack_require__.r(ns);
|
||||
/******/ var def = {};
|
||||
/******/ leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)];
|
||||
/******/ for(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) {
|
||||
/******/ Object.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key])));
|
||||
/******/ }
|
||||
/******/ def['default'] = () => (value);
|
||||
/******/ __webpack_require__.d(ns, def);
|
||||
/******/ return ns;
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/define property getters */
|
||||
/******/ (() => {
|
||||
/******/ // define getter functions for harmony exports
|
||||
/******/ __webpack_require__.d = (exports, definition) => {
|
||||
/******/ for(var key in definition) {
|
||||
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
||||
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/ensure chunk */
|
||||
/******/ (() => {
|
||||
/******/ __webpack_require__.f = {};
|
||||
/******/ // This file contains only the entry chunk.
|
||||
/******/ // The chunk loading function for additional chunks
|
||||
/******/ __webpack_require__.e = (chunkId) => {
|
||||
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
|
||||
/******/ __webpack_require__.f[key](chunkId, promises);
|
||||
/******/ return promises;
|
||||
/******/ }, []));
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/get javascript chunk filename */
|
||||
/******/ (() => {
|
||||
/******/ // This function allow to reference async chunks and sibling chunks for the entrypoint
|
||||
/******/ __webpack_require__.u = (chunkId) => {
|
||||
/******/ // return url for filenames based on template
|
||||
/******/ return "" + chunkId + ".js";
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
||||
/******/ (() => {
|
||||
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/make namespace object */
|
||||
/******/ (() => {
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = (exports) => {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/startup entrypoint */
|
||||
/******/ (() => {
|
||||
/******/ __webpack_require__.X = (result, chunkIds, fn) => {
|
||||
/******/ // arguments: chunkIds, moduleId are deprecated
|
||||
/******/ var moduleId = chunkIds;
|
||||
/******/ if(!fn) chunkIds = result, fn = () => (__webpack_require__(__webpack_require__.s = moduleId));
|
||||
/******/ chunkIds.map(__webpack_require__.e, __webpack_require__)
|
||||
/******/ var r = fn();
|
||||
/******/ return r === undefined ? result : r;
|
||||
/******/ }
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/require chunk loading */
|
||||
/******/ (() => {
|
||||
/******/ // no baseURI
|
||||
/******/
|
||||
/******/ // object to store loaded chunks
|
||||
/******/ // "1" means "loaded", otherwise not loaded yet
|
||||
/******/ var installedChunks = {
|
||||
/******/ "webpack-runtime": 1
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // no on chunks loaded
|
||||
/******/
|
||||
/******/ var installChunk = (chunk) => {
|
||||
/******/ var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;
|
||||
/******/ for(var moduleId in moreModules) {
|
||||
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
|
||||
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ if(runtime) runtime(__webpack_require__);
|
||||
/******/ for(var i = 0; i < chunkIds.length; i++)
|
||||
/******/ installedChunks[chunkIds[i]] = 1;
|
||||
/******/
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // require() chunk loading for javascript
|
||||
/******/ __webpack_require__.f.require = (chunkId, promises) => {
|
||||
/******/ // "1" is the signal for "already loaded"
|
||||
/******/ if(!installedChunks[chunkId]) {
|
||||
/******/ if("webpack-runtime" != chunkId) {
|
||||
/******/ installChunk(require("./" + __webpack_require__.u(chunkId)));
|
||||
/******/ } else installedChunks[chunkId] = 1;
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ module.exports = __webpack_require__;
|
||||
/******/ __webpack_require__.C = installChunk;
|
||||
/******/
|
||||
/******/ // no HMR
|
||||
/******/
|
||||
/******/ // no HMR manifest
|
||||
/******/ })();
|
||||
/******/
|
||||
/************************************************************************/
|
||||
/******/
|
||||
/******/
|
||||
/******/ })()
|
||||
;
|
||||
30
.next/trace
|
Before Width: | Height: | Size: 383 KiB After Width: | Height: | Size: 383 KiB |
|
Before Width: | Height: | Size: 215 KiB After Width: | Height: | Size: 219 KiB |
|
Before Width: | Height: | Size: 236 KiB After Width: | Height: | Size: 236 KiB |
|
Before Width: | Height: | Size: 214 KiB After Width: | Height: | Size: 219 KiB |
BIN
public/general/benchmark-copperanalyer.png
Normal file
|
After Width: | Height: | Size: 168 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 109 KiB |
@@ -1,5 +1,4 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
import React from 'react';
|
||||
import { HomePage, Project, Operators, CableId, Tools, Result, TestConfig, MenuList, Testing, ResultInfo, CopperPerformance } from '@/components/dsxpage';
|
||||
import Toast from '../lib/Toast';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
@@ -46,11 +45,7 @@ export default function DSXDisplay() {
|
||||
};
|
||||
|
||||
const handleClick = () => {
|
||||
if (touchSound) {
|
||||
touchSound.currentTime = 0;
|
||||
touchSound.play();
|
||||
play('keyClick');
|
||||
}
|
||||
play('keyClick');
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -146,7 +146,7 @@ const LineChart = ({ title, x, y, y2 = null, accent = '#12f7ff', accent2 = '#f28
|
||||
// 独立的 EST-Analyzer 页面内容组件(不复用现有标题/状态栏/图表组件)
|
||||
// 父容器尺寸为 w-[480px] h-[640px],本组件内部使用响应式布局,不溢出
|
||||
export default function EstAnalyzerDisplay() {
|
||||
const { cableParams, mainUnitModules, updateReports, reports, connectionPaths } = useDeviceStore();
|
||||
const { cableParams, mainUnitModules, updateReports, reports, connectionPaths,hasBenchmarkModule } = useDeviceStore();
|
||||
|
||||
// 页面步骤:config -> benchmark -> progress -> result -> save -> saved
|
||||
const [step, setStep] = useState('config');
|
||||
@@ -297,8 +297,16 @@ export default function EstAnalyzerDisplay() {
|
||||
aluminum: 1.68
|
||||
};
|
||||
|
||||
// 频谱(用于曲线展示)——1MHz 采样:1,2,...,500
|
||||
const frequencies = useMemo(() => Array.from({ length: 500 }, (_, i) => i + 1), []);
|
||||
// maxFrequencyMHz 最大频率(MHz)
|
||||
const maxFrequencyMHz = useMemo(() => {
|
||||
const t = (config?.cableType || '').toLowerCase();
|
||||
if (t.includes('6a')) return 500;
|
||||
if (t.includes('5e')) return 100;
|
||||
if (t.includes('6')) return 250;
|
||||
return 500;
|
||||
}, [config.cableType]);
|
||||
// 频谱(用于曲线展示)
|
||||
const frequencies = useMemo(() => Array.from({ length: maxFrequencyMHz }, (_, i) => i + 1), [maxFrequencyMHz]);
|
||||
|
||||
// 基于 cableParams 和 config.frequency 计算摘要与曲线
|
||||
const { summary, curves } = useMemo(() => {
|
||||
@@ -334,13 +342,13 @@ export default function EstAnalyzerDisplay() {
|
||||
const Z0Scale = Math.min(1.06, Math.max(0.94, Z0TwistAdj * Z0EpsAdj));
|
||||
Z0 *= Z0Scale;
|
||||
|
||||
// 插入损耗 IL 曲线:按 1–500MHz 从 ILData 采样
|
||||
// 插入损耗 IL 曲线:按 1–maxFrequencyMHzMHz 从 ILData 采样
|
||||
const sampleIL = (f) => {
|
||||
const fi = Math.round(Math.max(1, Math.min(500, f)));
|
||||
const fi = Math.round(Math.max(1, Math.min(maxFrequencyMHz, f)));
|
||||
const v = ILData[fi];
|
||||
return typeof v === 'number' ? v : 0;
|
||||
};
|
||||
// IL 基线(1-500MHz)
|
||||
// IL 基线(1-maxFrequencyMHzMHz)
|
||||
const IL_base = frequencies.map(f => sampleIL(f));
|
||||
// 物理影响参数(以 20m、pe、twistPitch=10mm、coreDia=0.51mm 为参考)
|
||||
const L0 = 20; // m,基线长度
|
||||
@@ -378,7 +386,7 @@ export default function EstAnalyzerDisplay() {
|
||||
let val = vLen + addSqrt * wSqrt(f) + addLinF * wLinF(f);
|
||||
// 噪声(随频率略增)
|
||||
const sigma0 = 0.02, sigma1 = 0.06; // dB
|
||||
const noiseAmp = sigma0 + sigma1 * (f / 500);
|
||||
const noiseAmp = sigma0 + sigma1 * (f / maxFrequencyMHz);
|
||||
const r = Math.sin((idx + 1) * 37.7 + (lenScale + tightness) * 11.3) * 0.5 + Math.cos((idx + 1) * 19.1) * 0.5;
|
||||
val += r * noiseAmp;
|
||||
return Math.max(0, val);
|
||||
@@ -397,20 +405,20 @@ export default function EstAnalyzerDisplay() {
|
||||
const n = (prng(seedBase * 0.83 + i * 5.21) - 0.5) * 2; // [-1,1]
|
||||
const ripple = (prng(seedBase * 0.67 + i * 2.19) - 0.5) * 2 * 1.2; // ±1.2MHz
|
||||
const df = phaseStrength * f * (1 - Math.exp(-f / Math.max(f0, 1))) * n + ripple;
|
||||
return Math.max(1, Math.min(500, f + df));
|
||||
return Math.max(1, Math.min(maxFrequencyMHz, f + df));
|
||||
};
|
||||
IL2 = frequencies.map((f, i) => {
|
||||
// 频轴挪动后线性插值 IL
|
||||
const f2 = warp(f, i);
|
||||
const fi0 = Math.floor(f2);
|
||||
const fi1 = Math.min(500, fi0 + 1);
|
||||
const fi1 = Math.min(maxFrequencyMHz, fi0 + 1);
|
||||
const t = f2 - fi0;
|
||||
const vWarp = ((IL[fi0 - 1] ?? IL_base[fi0 - 1] ?? 0) * (1 - t)) + ((IL[fi1 - 1] ?? IL_base[fi1 - 1] ?? 0) * t);
|
||||
// 幅度偏置
|
||||
const n1 = (prng(seedBase + i * 13.37) - 0.5) * 2; // [-1,1]
|
||||
const n2 = (prng(seedBase + i * 7.11) - 0.5); // [-0.5,0.5]
|
||||
const pos = 0.15 + 0.20 * (f / 500); // +0.15→+0.35 dB
|
||||
const neg = 0.10 + 0.10 * (f / 500); // -0.10→-0.20 dB
|
||||
const pos = 0.15 + 0.20 * (f / maxFrequencyMHz); // +0.15→+0.35 dB
|
||||
const neg = 0.10 + 0.10 * (f / maxFrequencyMHz); // -0.10→-0.20 dB
|
||||
const rel = 0.02; // ±2% 相对偏移
|
||||
const add = (n1 >= 0 ? (n1 * pos) : (n1 * neg));
|
||||
const val = Math.max(0, vWarp * (1 + rel * n1) + (n2 * 0.18) + add);
|
||||
@@ -418,11 +426,11 @@ export default function EstAnalyzerDisplay() {
|
||||
});
|
||||
}
|
||||
|
||||
// 基准回波损耗 RL 曲线:直接使用 RLData(1–500MHz 的基准值)
|
||||
// 基准回波损耗 RL 曲线:直接使用 RLData(1–maxFrequencyMHzMHz 的基准值)
|
||||
const Zref = 100; // 供 TDR 使用
|
||||
const lenLog = Math.max(0, Math.log1p(lengthM || 0)); // 供 TDR 使用
|
||||
const sampleRL = (f) => {
|
||||
const fi = Math.round(Math.max(1, Math.min(500, f)));
|
||||
const fi = Math.round(Math.max(1, Math.min(maxFrequencyMHz, f)));
|
||||
const v = RLData[fi];
|
||||
return typeof v === 'number' ? v : 0;
|
||||
};
|
||||
@@ -445,7 +453,7 @@ export default function EstAnalyzerDisplay() {
|
||||
let val = v - fall + ripple;
|
||||
// 噪声
|
||||
const sigma0 = 0.08, sigma1 = 0.12;
|
||||
const noiseAmp = sigma0 + sigma1 * (f / 500);
|
||||
const noiseAmp = sigma0 + sigma1 * (f / maxFrequencyMHz);
|
||||
const r = Math.sin((idx + 1) * 23.4 + phi * 0.5) * 0.5 + Math.cos((idx + 1) * 9.7) * 0.5;
|
||||
val += r * noiseAmp;
|
||||
// 边界:允许为负值,仅限制上限以避免不现实的大值
|
||||
@@ -464,27 +472,27 @@ export default function EstAnalyzerDisplay() {
|
||||
const n = (prng2(seed2 * 0.77 + i * 3.91) - 0.5) * 2;
|
||||
const ripple = (prng2(seed2 * 0.55 + i * 2.41) - 0.5) * 2 * 1.0; // ±1.0MHz
|
||||
const df = phaseStrength * f * (1 - Math.exp(-f / Math.max(f0, 1))) * n + ripple;
|
||||
return Math.max(1, Math.min(500, f + df));
|
||||
return Math.max(1, Math.min(maxFrequencyMHz, f + df));
|
||||
};
|
||||
RL2 = frequencies.map((f, i) => {
|
||||
const f2 = warp(f, i);
|
||||
const fi0 = Math.floor(f2);
|
||||
const fi1 = Math.min(500, fi0 + 1);
|
||||
const fi1 = Math.min(maxFrequencyMHz, fi0 + 1);
|
||||
const t = f2 - fi0;
|
||||
const vWarp = ((RL[fi0 - 1] ?? RL_base[fi0 - 1] ?? 0) * (1 - t)) + ((RL[fi1 - 1] ?? RL_base[fi1 - 1] ?? 0) * t);
|
||||
const n1 = (prng2(seed2 + i * 17.3) - 0.5) * 2; // [-1,1]
|
||||
const n2 = (prng2(seed2 + i * 5.9) - 0.5); // [-0.5,0.5]
|
||||
const pos = 0.20 + 0.40 * (f / 500); // +0.2→+0.6 dB
|
||||
const neg = 0.40 + 0.80 * (f / 500); // -0.4→-1.2 dB
|
||||
const pos = 0.20 + 0.40 * (f / maxFrequencyMHz); // +0.2→+0.6 dB
|
||||
const neg = 0.40 + 0.80 * (f / maxFrequencyMHz); // -0.4→-1.2 dB
|
||||
const add = (n1 >= 0 ? (n1 * pos) : (n1 * neg));
|
||||
const val = vWarp + (n2 * 1.2) + add;
|
||||
return Math.min(100, val);
|
||||
});
|
||||
}
|
||||
|
||||
// NEXT 曲线:按 1–500MHz 从 NEXTData 采样
|
||||
// NEXT 曲线:按 1–maxFrequencyMHzMHz 从 NEXTData 采样
|
||||
const sampleNEXT = (f) => {
|
||||
const fi = Math.round(Math.max(1, Math.min(500, f)));
|
||||
const fi = Math.round(Math.max(1, Math.min(maxFrequencyMHz, f)));
|
||||
const v = NEXTData[fi];
|
||||
return typeof v === 'number' ? v : 0;
|
||||
};
|
||||
@@ -512,7 +520,7 @@ export default function EstAnalyzerDisplay() {
|
||||
let val = v + (-h_len * lenDelta * w) - (h_twist_bad * pitchBadness * w) + (h_diff * ratioImprove * w);
|
||||
// 噪声
|
||||
const sigma0 = 0.06, sigma1 = 0.10;
|
||||
const noiseAmp = sigma0 + sigma1 * (f / 500);
|
||||
const noiseAmp = sigma0 + sigma1 * (f / maxFrequencyMHz);
|
||||
const r = Math.sin((idx + 1) * 13.9 + twistDiff * 5.7) * 0.5 + Math.cos((idx + 1) * 7.3) * 0.5;
|
||||
val += r * noiseAmp;
|
||||
// 边界夹限
|
||||
@@ -531,7 +539,7 @@ export default function EstAnalyzerDisplay() {
|
||||
const n = (prng3(seed3 * 0.93 + i * 4.29) - 0.5) * 2;
|
||||
const ripple = (prng3(seed3 * 0.69 + i * 2.11) - 0.5) * 2 * 1.0;
|
||||
const df = phaseStrength * f * (1 - Math.exp(-f / Math.max(f0, 1))) * n + ripple;
|
||||
return Math.max(1, Math.min(500, f + df));
|
||||
return Math.max(1, Math.min(maxFrequencyMHz, f + df));
|
||||
};
|
||||
// 次曲线也应受绞距与节距比影响(轻度,但可见)
|
||||
const k_tw2 = 0.55; // 次曲线绞距劣化权重(弱于主曲线)
|
||||
@@ -539,13 +547,13 @@ export default function EstAnalyzerDisplay() {
|
||||
NEXT2 = frequencies.map((f, i) => {
|
||||
const f2 = warp(f, i);
|
||||
const fi0 = Math.floor(f2);
|
||||
const fi1 = Math.min(500, fi0 + 1);
|
||||
const fi1 = Math.min(maxFrequencyMHz, fi0 + 1);
|
||||
const t = f2 - fi0;
|
||||
const vWarp = ((NEXT[fi0 - 1] ?? NEXT_base[fi0 - 1] ?? 0) * (1 - t)) + ((NEXT[fi1 - 1] ?? NEXT_base[fi1 - 1] ?? 0) * t);
|
||||
const n1 = (prng3(seed3 + i * 11.9) - 0.5) * 2; // [-1,1]
|
||||
const n2 = (prng3(seed3 + i * 3.7) - 0.5); // [-0.5,0.5]
|
||||
const pos = 0.15 + 0.35 * (f / 500); // +0.15→+0.50 dB
|
||||
const neg = 0.30 + 0.50 * (f / 500); // -0.30→-0.80 dB
|
||||
const pos = 0.15 + 0.35 * (f / maxFrequencyMHz); // +0.15→+0.50 dB
|
||||
const neg = 0.30 + 0.50 * (f / maxFrequencyMHz); // -0.30→-0.80 dB
|
||||
const add = (n1 >= 0 ? (n1 * pos) : (n1 * neg));
|
||||
const w2 = W(f);
|
||||
const shift = (-k_tw2 * pitchBadness * w2) + (k_df2 * ratioImprove * w2);
|
||||
@@ -802,9 +810,9 @@ export default function EstAnalyzerDisplay() {
|
||||
<input
|
||||
type="range"
|
||||
min={1}
|
||||
max={500}
|
||||
max={maxFrequencyMHz}
|
||||
step={1}
|
||||
value={config.frequency}
|
||||
value={Math.min(config.frequency || 1, maxFrequencyMHz)}
|
||||
onChange={e => setConfig({ ...config, frequency: parseInt(e.target.value) })}
|
||||
className="w-full h-2 bg-[#12f7ff]/20 rounded appearance-none cursor-pointer" style={{ accentColor: '#12f7ff' }}
|
||||
/>
|
||||
@@ -814,7 +822,12 @@ export default function EstAnalyzerDisplay() {
|
||||
<label className="text-[12px] text-[#7bdbe3]">线缆类型</label>
|
||||
<select
|
||||
value={config.cableType}
|
||||
onChange={e => setConfig({ ...config, cableType: e.target.value })}
|
||||
onChange={e => {
|
||||
const v = e.target.value;
|
||||
const t = (v || '').toLowerCase();
|
||||
const m = t.includes('6a') ? 500 : (t.includes('5e') ? 100 : (t.includes('6') ? 250 : 500));
|
||||
setConfig(prev => ({ ...prev, cableType: v, frequency: Math.min(prev.frequency || 1, m) }));
|
||||
}}
|
||||
className="w-full p-2 rounded bg-[#0c1319] text-[#c9f9ff] border border-[#12f7ff]/20 text-[13px]"
|
||||
>
|
||||
<option>Cat6A U/UTP</option>
|
||||
@@ -875,10 +888,10 @@ export default function EstAnalyzerDisplay() {
|
||||
<div className="flex flex-col items-center gap-3 py-2">
|
||||
<div className="text-[13px] text-[#c9f9ff]">请将主机与远端分别连接到 基准适配器 </div>
|
||||
<div className="text-[12px] text-[#7bdbe3]">连接完成后将出现“完成基准设置”按钮</div>
|
||||
<img src={getAssetUrl('/benchmark-ref.png')} alt="benchmark" className="w-[200px] h-[200px] object-contain" />
|
||||
<img src={getAssetUrl('/benchmark-ref.png')} alt="benchmark" className="w-[80%] object-contain" />
|
||||
</div>
|
||||
</Card>
|
||||
{canCompleteBenchmark && (
|
||||
{hasBenchmarkModule && (
|
||||
<div className="flex justify-center">
|
||||
<button
|
||||
className="h-[32px] px-4 rounded bg-[#12f7ff]/20 text-[#12f7ff] text-[13px] hover:bg-[#12f7ff]/30"
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import StatusBar from '@/components/lib//StatusBar';
|
||||
import ResultTitleBar from '@/components/lib//ResultTitleBar';
|
||||
import StatusBar from '@/components/lib/StatusBar';
|
||||
import ResultTitleBar from '@/components/lib/ResultTitleBar';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
import FrequencyChart from '@/components/lib//FrequencyChart';
|
||||
import HDTDChart from '@/components/lib//HDTDChart';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
import FrequencyChart from '@/components/lib/FrequencyChart';
|
||||
import HDTDChart from '@/components/lib/HDTDChart';
|
||||
|
||||
export default function CopperPerformance( ) {
|
||||
const { estmodel } = useDeviceStore();
|
||||
const { navigation, navigateTo,goBack } = useDisplayStore();
|
||||
const { view } = navigation.current;
|
||||
const curtitle = navigation.current.params.curtitle;
|
||||
const testResult = navigation.current.params.testResult;
|
||||
const CopperResultStatus = testResult.CopperResultStatus;
|
||||
const limitValue = testResult.testconfig.params.limitValue;
|
||||
const [limitdata, setLimitdata] = useState(null);
|
||||
const wireOrder = testResult?.testconfig?.params?.wireOrder;
|
||||
@@ -37,6 +40,26 @@ export default function CopperPerformance( ) {
|
||||
|
||||
const [poeTab, setPoeTab] = useState('回路');
|
||||
|
||||
const getDisplayTitle = (key) => {
|
||||
const map = {
|
||||
'长度': '长度',
|
||||
'电阻': '电阻',
|
||||
'插入损耗': '插入损耗',
|
||||
'回波损耗': '回波损耗',
|
||||
'NEXT': '近端串音',
|
||||
'PS NEXT': '近端串音功率和',
|
||||
'ACR-N': '衰减近端串音比',
|
||||
'PS ACR-N': '衰减近端串音比功率和',
|
||||
'ACR-F': '衰减远端串音比',
|
||||
'PS ACR-F': '衰减远端串音比功率和',
|
||||
'CDNEXT': '共模转差模近端串音',
|
||||
'CMRL': '共模回波损耗',
|
||||
'TCL': '横向转换损耗',
|
||||
'ELTCTL': '两端等效横向转换损耗'
|
||||
};
|
||||
return map[key] || key;
|
||||
};
|
||||
|
||||
const renderResultTitleBar = () => {
|
||||
const handleBack = () => {
|
||||
goBack();
|
||||
@@ -56,7 +79,7 @@ export default function CopperPerformance( ) {
|
||||
title = '图表';
|
||||
break;
|
||||
};
|
||||
return <ResultTitleBar title={curtitle} onBack={handleBack} />;
|
||||
return <ResultTitleBar title={getDisplayTitle(curtitle)} onBack={handleBack} />;
|
||||
};
|
||||
|
||||
const renderContent = () => {
|
||||
@@ -303,9 +326,11 @@ export default function CopperPerformance( ) {
|
||||
{limitdata && (
|
||||
<FrequencyChart
|
||||
curtitle={curtitle}
|
||||
displayTitle={getDisplayTitle(curtitle)}
|
||||
limitValue={limitValue}
|
||||
limitdata={limitdata}
|
||||
wireOrder={wireOrder}
|
||||
CopperResultStatus={CopperResultStatus}
|
||||
data={testResult?.resultdata?.performance?.data}
|
||||
/>
|
||||
)}
|
||||
@@ -331,9 +356,27 @@ export default function CopperPerformance( ) {
|
||||
};
|
||||
|
||||
const renderFooter = () => {
|
||||
const showHDTDR = estmodel === 'general' && testResult?.CopperResultStatus === 'fail' && view === 'DRAW' && curtitle === '回波损耗';
|
||||
const showHDTDX = estmodel === 'general' && testResult?.CopperResultStatus === 'fail' && view === 'DRAW' && curtitle === 'NEXT';
|
||||
console.log(estmodel, CopperResultStatus, view, curtitle, showHDTDR, showHDTDX);
|
||||
return (
|
||||
<div className="h-[60px] bg-[#132843] flex items-center justify-end px-8">
|
||||
|
||||
<div className="h-[60px] bg-[#132843] flex items-center justify-end px-8 gap-4">
|
||||
{showHDTDR && (
|
||||
<button
|
||||
className="px-4 h-[40px] bg-gradient-to-b from-[#b6dae7] to-[#65dfff] transition-colors duration-200 rounded-lg flex items-center justify-center text-black font-bold shadow-lg"
|
||||
onClick={() => navigateTo('copperperformance', 'HDTD', { testResult, curtitle: 'HDTDR' })}
|
||||
>
|
||||
时域反射分析
|
||||
</button>
|
||||
)}
|
||||
{showHDTDX && (
|
||||
<button
|
||||
className="px-4 h-[40px] bg-gradient-to-b from-[#b6dae7] to-[#65dfff] transition-colors duration-200 rounded-lg flex items-center justify-center text-black font-bold shadow-lg"
|
||||
onClick={() => navigateTo('copperperformance', 'HDTD', { testResult, curtitle: 'HDTDX' })}
|
||||
>
|
||||
时域串音分析
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import Image from 'next/image';
|
||||
import { FolderIcon, SwatchIcon, TagIcon, UserIcon, PuzzlePieceIcon } from '@heroicons/react/24/solid';
|
||||
import StatusBar from '@/components/lib//StatusBar';
|
||||
import TitleBar from '@/components/lib//TitleBar';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
@@ -114,7 +115,7 @@ export default function HomePage() {
|
||||
case 'cfp':
|
||||
return (
|
||||
<div className="flex flex-col justify-center h-full space-y-0.2 text-sm">
|
||||
<div className="text-black text-sm">智能远端</div>
|
||||
<div className="text-black text-sm">光纤损耗测试</div>
|
||||
<div className="text-black text-sm">{currentConfig.params.limitValue}</div>
|
||||
<div className="text-black text-sm">{currentConfig.params.cableType}</div>
|
||||
<div className="text-black text-sm">{currentConfig.params.refJumper} 跳线参照</div>
|
||||
@@ -152,19 +153,19 @@ export default function HomePage() {
|
||||
<div className="flex justify-between items-start">
|
||||
{mainUnitModules?.[0]?.id === '8000' ? (
|
||||
<div>
|
||||
<div className="text-lg font-bold text-[#132843] ">当前安装模块:铜缆分析模块</div>
|
||||
<div className=" font-bold text-[#132843] flex items-center gap-1"><PuzzlePieceIcon className="w-5 h-5 text-[#132843]" />当前安装模块:铜缆分析模块</div>
|
||||
</div>
|
||||
) : mainUnitModules?.[0]?.id === 'cfp' ? (
|
||||
<div>
|
||||
<div className="text-lg font-bold text-[#132843]">当前安装模块:光纤损耗模块</div>
|
||||
<div className=" font-bold text-[#132843] flex items-center gap-1"><PuzzlePieceIcon className="w-5 h-5 text-[#132843]" />当前安装模块:光纤损耗模块</div>
|
||||
</div>
|
||||
) : mainUnitModules?.[0]?.id === 'ofp' ? (
|
||||
<div>
|
||||
<div className="text-lg font-bold text-[#132843]">当前安装模块:光时域反射模块</div>
|
||||
<div className=" font-bold text-[#132843] flex items-center gap-1"><PuzzlePieceIcon className="w-5 h-5 text-[#132843]" />当前安装模块:光时域反射模块</div>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<div className="text-lg font-bold text-[#132843]">请安装模块</div>
|
||||
<div className=" font-bold text-[#132843] flex items-center gap-1"><PuzzlePieceIcon className="w-5 h-5 text-[#132843]" /> 请安装模块</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -174,7 +175,7 @@ export default function HomePage() {
|
||||
<div className="bg-[#F8F6F7] rounded-lg p-4 shadow-md hover:shadow-lg transition-shadow duration-200 cursor-pointer"
|
||||
onClick={handleProjectClick}>
|
||||
|
||||
<div className="text-[#132843] font-bold mb-1">项目</div>
|
||||
<div className="text-[#132843] font-bold mb-1 flex items-center gap-1"><FolderIcon className="w-4 h-4 text-[#132843]" /> 项目</div>
|
||||
<div className="flex justify-between items-start">
|
||||
<div>
|
||||
<div className="text-[#132843] text-sm pt-2">{currentProject?.name}</div>
|
||||
@@ -224,7 +225,7 @@ export default function HomePage() {
|
||||
onClick={() => navigateTo('testConfig', 'main')}
|
||||
>
|
||||
<div className="flex flex-col">
|
||||
<div className="text-[#132843] font-bold mb-1">测试极限值</div>
|
||||
<div className="text-[#132843] font-bold mb-1 flex items-center gap-1"><SwatchIcon className="w-4 h-4 text-[#132843]" /> 测试极限值</div>
|
||||
|
||||
<div className="flex-1">{renderTestConfigContent()}</div>
|
||||
</div>
|
||||
@@ -252,7 +253,7 @@ export default function HomePage() {
|
||||
>
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="flex flex-col">
|
||||
<div className="text-[#132843] font-bold mb-1">下一条记录</div>
|
||||
<div className="text-[#132843] font-bold mb-1 flex items-center gap-1"><TagIcon className="w-4 h-4 text-[#132843]" /> 下一条记录</div>
|
||||
{currentConfig?.moduleType === 'cfp' ? (
|
||||
<>
|
||||
<div className="text-[#132843] text-sm">输入:<span className="font-medium">{currentCableId?.name || ''}</span></div>
|
||||
@@ -283,7 +284,7 @@ export default function HomePage() {
|
||||
>
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="flex flex-col">
|
||||
<div className="text-[#132843] font-bold mb-1">操作员</div>
|
||||
<div className="text-[#132843] font-bold mb-1 flex items-center gap-1"><UserIcon className="w-4 h-4 text-[#132843]" /> 操作员</div>
|
||||
<div className="text-[#132843] text-sm">
|
||||
<span className="font-medium">{currentOperator?.name || ''}</span>
|
||||
</div>
|
||||
|
||||
@@ -18,222 +18,204 @@ const menuData = {
|
||||
title: '电缆类型',
|
||||
subTitle: '电缆类型',
|
||||
items: [
|
||||
{ value: 'custom', label: '定制', disabled: true },
|
||||
{
|
||||
value: 'general',
|
||||
label: '通用',
|
||||
children: [
|
||||
// { value: 'Cat8 S/FTP', label: 'Cat8 S/FTP' },
|
||||
// { value: 'Cat7A S/FTP', label: 'Cat7A S/FTP' },
|
||||
// { value: 'Cat7 S/FTP', label: 'Cat7 S/FTP' },
|
||||
// { value: 'Cat6A S/FTP', label: 'Cat6A S/FTP' },
|
||||
{ value: 'Cat6A U/UTP', label: 'Cat6A U/UTP' },
|
||||
{ value: 'Cat6A F/UTP', label: 'Cat6A F/UTP' },
|
||||
{ value: 'Cat6 U/UTP', label: 'Cat6 U/UTP' },
|
||||
{ value: 'Cat6 F/UTP', label: 'Cat6 F/UTP' },
|
||||
// { value: 'Cat6 U/FTP', label: 'Cat6 U/FTP' },
|
||||
{ value: 'Cat5e U/UTP', label: 'Cat5e U/UTP' },
|
||||
{ value: 'Cat5e F/UTP', label: 'Cat5e F/UTP' },
|
||||
// { value: 'Cat5 U/UTP', label: 'Cat5 U/UTP' },
|
||||
// { value: 'Cat5 F/UTP', label: 'Cat5 F/UTP' }
|
||||
]
|
||||
},
|
||||
{ value: 'coaxial', label: '通用同轴电缆', disabled: true },
|
||||
{ value: 'manufacturer', label: '制造商', disabled: true }
|
||||
]
|
||||
},
|
||||
LIMIT_VALUE: {
|
||||
title: '测试极限值',
|
||||
subTitle: '极限值组',
|
||||
items: [
|
||||
// {
|
||||
// value: 'TIA',
|
||||
// label: 'TIA',
|
||||
// children: {
|
||||
// // Cat8: {
|
||||
// // label: 'Cat8',
|
||||
// // children: [
|
||||
// // { value: 'TIA Cat 8 Perm.Link', label: 'TIA Cat 8 Perm.Link' },
|
||||
// // { value: 'TIA Cat 8 Perm.Link (+ALL)', label: 'TIA Cat 8 Perm.Link (+ALL)' },
|
||||
// // { value: 'TIA Cat 8 Perm.Link (+PoE)', label: 'TIA Cat 8 Perm.Link (+PoE)' },
|
||||
// // { value: 'TIA Cat 8 Channel', label: 'TIA Cat 8 Channel' },
|
||||
// // { value: 'TIA Cat 8 Channel (+ALL)', label: 'TIA Cat 8 Channel (+ALL)' },
|
||||
// // { value: 'TIA Cat 8 Channel (+PoE)', label: 'TIA Cat 8 Channel (+PoE)' }
|
||||
// // ]
|
||||
// // },
|
||||
// Cat6A: {
|
||||
// label: 'Cat6A',
|
||||
// children: [
|
||||
// { value: 'TIA Cat 6A Perm.Link', label: 'TIA Cat 6A Perm.Link' },
|
||||
// { value: 'TIA Cat 6A Perm.Link (+ALL)', label: 'TIA Cat 6A Perm.Link (+ALL)' },
|
||||
// { value: 'TIA Cat 6A Perm.Link (+PoE)', label: 'TIA Cat 6A Perm.Link (+PoE)' },
|
||||
// { value: 'TIA Cat 6A Channel', label: 'TIA Cat 6A Channel' },
|
||||
// { value: 'TIA Cat 6A Channel (+ALL)', label: 'TIA Cat 6A Channel (+ALL)' },
|
||||
// { value: 'TIA Cat 6A Channel (+PoE)', label: 'TIA Cat 6A Channel (+PoE)' },
|
||||
// { value: 'TIA Cat 6A MPTL', label: 'TIA Cat 6A MPTL' },
|
||||
// { value: 'TIA Cat 6A MPTL (+PoE)', label: 'TIA Cat 6A MPTL (+PoE)' },
|
||||
// // { value: 'TIA 1005 Cat 6A Perm.Link', label: 'TIA 1005 Cat 6A Perm.Link' },
|
||||
// // { value: 'TIA 1005 Cat 6A Channel', label: 'TIA 1005 Cat 6A Channel' },
|
||||
// { value: 'TIA 1005 Cat 6A Channel E1 (+ALL)', label: 'TIA 1005 Cat 6A Channel E1 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 6A Channel E1 (+PoE)', label: 'TIA 1005 Cat 6A Channel E1 (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 6A Channel E2 (+ALL)', label: 'TIA 1005 Cat 6A Channel E2 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 6A Channel E2 (+PoE)', label: 'TIA 1005 Cat 6A Channel E2 (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 6A Channel E3 (+ALL)', label: 'TIA 1005 Cat 6A Channel E3 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 6A Channel E3 (+PoE)', label: 'TIA 1005 Cat 6A Channel E3 (+PoE)' }
|
||||
// ]
|
||||
// },
|
||||
// Cat6: {
|
||||
// label: 'Cat6',
|
||||
// children: [
|
||||
// { value: 'TIA Cat 6 Perm.Link', label: 'TIA Cat 6 Perm.Link' },
|
||||
// { value: 'TIA Cat 6 Perm.Link (+ALL)', label: 'TIA Cat 6 Perm.Link (+ALL)' },
|
||||
// { value: 'TIA Cat 6 Perm.Link (+PoE)', label: 'TIA Cat 6 Perm.Link (+PoE)' },
|
||||
// { value: 'TIA Cat 6 Channel', label: 'TIA Cat 6 Channel' },
|
||||
// { value: 'TIA Cat 6 Channel (+ALL)', label: 'TIA Cat 6 Channel (+ALL)' },
|
||||
// { value: 'TIA Cat 6 Channel (+PoE)', label: 'TIA Cat 6 Channel (+PoE)' },
|
||||
// { value: 'TIA Cat 6 MPTL', label: 'TIA Cat 6 MPTL' },
|
||||
// { value: 'TIA Cat 6 MPTL (+PoE)', label: 'TIA Cat 6 MPTL (+PoE)' },
|
||||
// // { value: 'TIA 1005 Cat 6 Perm.Link', label: 'TIA 1005 Cat 6 Perm.Link' },
|
||||
// // { value: 'TIA 1005 Cat 6 Channel', label: 'TIA 1005 Cat 6 Channel' },
|
||||
// // { value: 'TIA 1005 Cat 6 Channel (+ALL)', label: 'TIA 1005 Cat 6 Channel (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 6 Channel (+PoE)', label: 'TIA 1005 Cat 6 Channel (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel E1 (+ALL)', label: 'TIA 1005 Cat 6 Channel E1 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 6 Channel E1 (+PoE)', label: 'TIA 1005 Cat 6 Channel E1 (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel E2 (+ALL)', label: 'TIA 1005 Cat 6 Channel E2 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 6 Channel E2 (+PoE)', label: 'TIA 1005 Cat 6 Channel E2 (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel E3 (+ALL)', label: 'TIA 1005 Cat 6 Channel E3 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 6 Channel E3 (+PoE)', label: 'TIA 1005 Cat 6 Channel E3 (+PoE)' }
|
||||
// ]
|
||||
// },
|
||||
// Cat5e: {
|
||||
// label: 'Cat5e',
|
||||
// children: [
|
||||
// { value: 'TIA Cat 5e Perm.Link', label: 'TIA Cat 5e Perm.Link' },
|
||||
// { value: 'TIA Cat 5e Perm.Link (+ALL)', label: 'TIA Cat 5e Perm.Link (+ALL)' },
|
||||
// { value: 'TIA Cat 5e Perm.Link (+PoE)', label: 'TIA Cat 5e Perm.Link (+PoE)' },
|
||||
// { value: 'TIA Cat 5e Channel', label: 'TIA Cat 5e Channel' },
|
||||
// { value: 'TIA Cat 5e Channel (+ALL)', label: 'TIA Cat 5e Channel (+ALL)' },
|
||||
// { value: 'TIA Cat 5e Channel (+PoE)', label: 'TIA Cat 5e Channel (+PoE)' },
|
||||
// { value: 'TIA Cat 5e MPTL', label: 'TIA Cat 5e MPTL' },
|
||||
// { value: 'TIA Cat 5e MPTL (+PoE)', label: 'TIA Cat 5e MPTL (+PoE)' },
|
||||
// // { value: 'TIA 1005 Cat 5e Perm.Link', label: 'TIA 1005 Cat 5e Perm.Link' },
|
||||
// // { value: 'TIA 1005 Cat 5e Channel', label: 'TIA 1005 Cat 5e Channel' },
|
||||
// // { value: 'TIA 1005 Cat 5e Channel (+ALL)', label: 'TIA 1005 Cat 5e Channel (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 5e Channel (+PoE)', label: 'TIA 1005 Cat 5e Channel (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel E1 (+ALL)', label: 'TIA 1005 Cat 5e Channel E1 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 5e Channel E1 (+PoE)', label: 'TIA 1005 Cat 5e Channel E1 (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel E2 (+ALL)', label: 'TIA 1005 Cat 5e Channel E2 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 5e Channel E2 (+PoE)', label: 'TIA 1005 Cat 5e Channel E2 (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel E3 (+ALL)', label: 'TIA 1005 Cat 5e Channel E3 (+ALL)' },
|
||||
// // { value: 'TIA 1005 Cat 5e Channel E3 (+PoE)', label: 'TIA 1005 Cat 5e Channel E3 (+PoE)' }
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// value: 'ISO',
|
||||
// label: 'ISO',
|
||||
// children: {
|
||||
// // 'Class Ⅱ': {
|
||||
// // label: 'Class Ⅱ',
|
||||
// // children: [
|
||||
// // { value: 'ISO11801 PL Class Ⅱ', label: 'ISO11801 PL Class Ⅱ' },
|
||||
// // { value: 'ISO11801 PL Class Ⅱ (+ALL)', label: 'ISO11801 PL Class Ⅱ (+ALL)' },
|
||||
// // { value: 'ISO11801 PL Class Ⅱ (+PoE)', label: 'ISO11801 PL Class Ⅱ (+PoE)' },
|
||||
// // { value: 'ISO11801 Channel Class Ⅱ', label: 'ISO11801 Channel Class Ⅱ' },
|
||||
// // { value: 'ISO11801 Channel Class Ⅱ (+ALL)', label: 'ISO11801 Channel Class Ⅱ (+ALL)' },
|
||||
// // { value: 'ISO11801 Channel Class Ⅱ (+PoE)', label: 'ISO11801 Channel Class Ⅱ (+PoE)' }
|
||||
// // ],
|
||||
// // disabled: true
|
||||
// // },
|
||||
// // 'Class Ⅰ': {
|
||||
// // label: 'Class Ⅰ',
|
||||
// // children: [
|
||||
// // { value: 'ISO11801 PL Class Ⅰ', label: 'ISO11801 PL Class Ⅰ' },
|
||||
// // { value: 'ISO11801 PL Class Ⅰ (+ALL)', label: 'ISO11801 PL Class Ⅰ (+ALL)' },
|
||||
// // { value: 'ISO11801 PL Class Ⅰ (+PoE)', label: 'ISO11801 PL Class Ⅰ (+PoE)' },
|
||||
// // { value: 'ISO11801 Channel Class Ⅰ', label: 'ISO11801 Channel Class Ⅰ' },
|
||||
// // { value: 'ISO11801 Channel Class Ⅰ (+ALL)', label: 'ISO11801 Channel Class Ⅰ (+ALL)' },
|
||||
// // { value: 'ISO11801 Channel Class Ⅰ (+PoE)', label: 'ISO11801 Channel Class Ⅰ (+PoE)' }
|
||||
// // ],
|
||||
// // disabled: true
|
||||
// // },
|
||||
// // 'Class Fa': {
|
||||
// // label: 'Class Fa',
|
||||
// // children: [
|
||||
// // { value: 'ISO11801 PL2 Class Fa', label: 'ISO11801 PL2 Class Fa' },
|
||||
// // { value: 'ISO11801 PL2 Class Fa (+ALL)', label: 'ISO11801 PL2 Class Fa (+ALL)' },
|
||||
// // { value: 'ISO11801 PL2 Class Fa (+PoE)', label: 'ISO11801 PL2 Class Fa (+PoE)' },
|
||||
// // { value: 'ISO11801 PL3 Class Fa', label: 'ISO11801 PL3 Class Fa' },
|
||||
// // { value: 'ISO11801 PL3 Class Fa (+ALL)', label: 'ISO11801 PL3 Class Fa (+ALL)' },
|
||||
// // { value: 'ISO11801 PL3 Class Fa (+PoE)', label: 'ISO11801 PL3 Class Fa (+PoE)' },
|
||||
// // { value: 'ISO11801 Channel Class Fa', label: 'ISO11801 Channel Class Fa' },
|
||||
// // { value: 'ISO11801 Channel Class Fa (+ALL)', label: 'ISO11801 Channel Class Fa (+ALL)' },
|
||||
// // { value: 'ISO11801 Channel Class Fa (+PoE)', label: 'ISO11801 Channel Class Fa (+PoE)' }
|
||||
// // ],
|
||||
// // disabled: true
|
||||
// // },
|
||||
// // 'Class F': {
|
||||
// // label: 'Class F',
|
||||
// // children: [
|
||||
// // { value: 'ISO11801 PL Class F', label: 'ISO11801 PL Class F' },
|
||||
// // { value: 'ISO11801 PL Class F (+ALL)', label: 'ISO11801 PL Class F (+ALL)' },
|
||||
// // { value: 'ISO11801 PL Class F (+PoE)', label: 'ISO11801 PL Class F (+PoE)' },
|
||||
// // { value: 'ISO11801 Channel Class F', label: 'ISO11801 Channel Class F' },
|
||||
// // { value: 'ISO11801 Channel Class F (+ALL)', label: 'ISO11801 Channel Class F (+ALL)' },
|
||||
// // { value: 'ISO11801 Channel Class F (+PoE)', label: 'ISO11801 Channel Class F (+PoE)' }
|
||||
// // ],
|
||||
// // disabled: true
|
||||
// // },
|
||||
// 'Class Ea': {
|
||||
// label: 'Class Ea',
|
||||
// children: [
|
||||
// { value: 'ISO11801 PL2 Class Ea', label: 'ISO11801 PL2 Class Ea' },
|
||||
// { value: 'ISO11801 PL2 Class Ea (+ALL)', label: 'ISO11801 PL2 Class Ea (+ALL)' },
|
||||
// { value: 'ISO11801 PL2 Class Ea (+PoE)', label: 'ISO11801 PL2 Class Ea (+PoE)' },
|
||||
// { value: 'ISO11801 PL3 Class Ea', label: 'ISO11801 PL3 Class Ea' },
|
||||
// { value: 'ISO11801 PL3 Class Ea (+ALL)', label: 'ISO11801 PL3 Class Ea (+ALL)' },
|
||||
// { value: 'ISO11801 PL3 Class Ea (+PoE)', label: 'ISO11801 PL3 Class Ea (+PoE)' },
|
||||
// { value: 'ISO11801 Channel Class Ea', label: 'ISO11801 Channel Class Ea' },
|
||||
// { value: 'ISO11801 Channel Class Ea (+ALL)', label: 'ISO11801 Channel Class Ea (+ALL)' },
|
||||
// { value: 'ISO11801 Channel Class Ea (+PoE)', label: 'ISO11801 Channel Class Ea (+PoE)' },
|
||||
// { value: 'ISO MPTL Class Ea', label: 'ISO MPTL Class Ea' },
|
||||
// { value: 'ISO MPTL Class Ea (+PoE)', label: 'ISO MPTL Class Ea (+PoE)' }
|
||||
// ]
|
||||
// },
|
||||
// 'Class E': {
|
||||
// label: 'Class E',
|
||||
// children: [
|
||||
// { value: 'ISO11801 PL Class E', label: 'ISO11801 PL Class E' },
|
||||
// { value: 'ISO11801 PL Class E (+ALL)', label: 'ISO11801 PL Class E (+ALL)' },
|
||||
// { value: 'ISO11801 PL Class E (+PoE)', label: 'ISO11801 PL Class E (+PoE)' },
|
||||
// { value: 'ISO11801 Channel Class E', label: 'ISO11801 Channel Class E' },
|
||||
// { value: 'ISO11801 Channel Class E (+ALL)', label: 'ISO11801 Channel Class E (+ALL)' },
|
||||
// { value: 'ISO11801 Channel Class E (+PoE)', label: 'ISO11801 Channel Class E (+PoE)' },
|
||||
// { value: 'ISO MPTL Class E', label: 'ISO MPTL Class E' },
|
||||
// { value: 'ISO MPTL Class E (+PoE)', label: 'ISO MPTL Class E (+PoE)' }
|
||||
// ]
|
||||
// },
|
||||
// 'Class D': {
|
||||
// label: 'Class D',
|
||||
// children: [
|
||||
// { value: 'ISO11801 PL Class D', label: 'ISO11801 PL Class D' },
|
||||
// { value: 'ISO11801 PL Class D (+ALL)', label: 'ISO11801 PL Class D (+ALL)' },
|
||||
// { value: 'ISO11801 PL Class D (+PoE)', label: 'ISO11801 PL Class D (+PoE)' },
|
||||
// { value: 'ISO11801 Channel Class D', label: 'ISO11801 Channel Class D' },
|
||||
// { value: 'ISO11801 Channel Class D (+ALL)', label: 'ISO11801 Channel Class D (+ALL)' },
|
||||
// { value: 'ISO11801 Channel Class D (+PoE)', label: 'ISO11801 Channel Class D (+PoE)' },
|
||||
// { value: 'ISO MPTL Class D', label: 'ISO MPTL Class D' },
|
||||
// { value: 'ISO MPTL Class D (+PoE)', label: 'ISO MPTL Class D (+PoE)' }
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
{
|
||||
value: 'TIA',
|
||||
label: 'TIA',
|
||||
children: {
|
||||
// Cat8: {
|
||||
// label: 'Cat8',
|
||||
// children: [
|
||||
// { value: 'TIA Cat 8 Perm.Link', label: 'TIA Cat 8 Perm.Link' },
|
||||
// { value: 'TIA Cat 8 Perm.Link (+ALL)', label: 'TIA Cat 8 Perm.Link (+ALL)' },
|
||||
// { value: 'TIA Cat 8 Perm.Link (+PoE)', label: 'TIA Cat 8 Perm.Link (+PoE)' },
|
||||
// { value: 'TIA Cat 8 Channel', label: 'TIA Cat 8 Channel' },
|
||||
// { value: 'TIA Cat 8 Channel (+ALL)', label: 'TIA Cat 8 Channel (+ALL)' },
|
||||
// { value: 'TIA Cat 8 Channel (+PoE)', label: 'TIA Cat 8 Channel (+PoE)' }
|
||||
// ]
|
||||
// },
|
||||
Cat6A: {
|
||||
label: 'Cat6A',
|
||||
children: [
|
||||
{ value: 'TIA Cat 6A Perm.Link', label: 'TIA Cat 6A Perm.Link' },
|
||||
{ value: 'TIA Cat 6A Perm.Link (+ALL)', label: 'TIA Cat 6A Perm.Link (+ALL)' },
|
||||
{ value: 'TIA Cat 6A Perm.Link (+PoE)', label: 'TIA Cat 6A Perm.Link (+PoE)' },
|
||||
{ value: 'TIA Cat 6A Channel', label: 'TIA Cat 6A Channel' },
|
||||
{ value: 'TIA Cat 6A Channel (+ALL)', label: 'TIA Cat 6A Channel (+ALL)' },
|
||||
{ value: 'TIA Cat 6A Channel (+PoE)', label: 'TIA Cat 6A Channel (+PoE)' },
|
||||
{ value: 'TIA Cat 6A MPTL', label: 'TIA Cat 6A MPTL' },
|
||||
{ value: 'TIA Cat 6A MPTL (+PoE)', label: 'TIA Cat 6A MPTL (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 6A Perm.Link', label: 'TIA 1005 Cat 6A Perm.Link' },
|
||||
// { value: 'TIA 1005 Cat 6A Channel', label: 'TIA 1005 Cat 6A Channel' },
|
||||
{ value: 'TIA 1005 Cat 6A Channel E1 (+ALL)', label: 'TIA 1005 Cat 6A Channel E1 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 6A Channel E1 (+PoE)', label: 'TIA 1005 Cat 6A Channel E1 (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 6A Channel E2 (+ALL)', label: 'TIA 1005 Cat 6A Channel E2 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 6A Channel E2 (+PoE)', label: 'TIA 1005 Cat 6A Channel E2 (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 6A Channel E3 (+ALL)', label: 'TIA 1005 Cat 6A Channel E3 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 6A Channel E3 (+PoE)', label: 'TIA 1005 Cat 6A Channel E3 (+PoE)' }
|
||||
]
|
||||
},
|
||||
Cat6: {
|
||||
label: 'Cat6',
|
||||
children: [
|
||||
{ value: 'TIA Cat 6 Perm.Link', label: 'TIA Cat 6 Perm.Link' },
|
||||
{ value: 'TIA Cat 6 Perm.Link (+ALL)', label: 'TIA Cat 6 Perm.Link (+ALL)' },
|
||||
{ value: 'TIA Cat 6 Perm.Link (+PoE)', label: 'TIA Cat 6 Perm.Link (+PoE)' },
|
||||
{ value: 'TIA Cat 6 Channel', label: 'TIA Cat 6 Channel' },
|
||||
{ value: 'TIA Cat 6 Channel (+ALL)', label: 'TIA Cat 6 Channel (+ALL)' },
|
||||
{ value: 'TIA Cat 6 Channel (+PoE)', label: 'TIA Cat 6 Channel (+PoE)' },
|
||||
{ value: 'TIA Cat 6 MPTL', label: 'TIA Cat 6 MPTL' },
|
||||
{ value: 'TIA Cat 6 MPTL (+PoE)', label: 'TIA Cat 6 MPTL (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 6 Perm.Link', label: 'TIA 1005 Cat 6 Perm.Link' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel', label: 'TIA 1005 Cat 6 Channel' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel (+ALL)', label: 'TIA 1005 Cat 6 Channel (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel (+PoE)', label: 'TIA 1005 Cat 6 Channel (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 6 Channel E1 (+ALL)', label: 'TIA 1005 Cat 6 Channel E1 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel E1 (+PoE)', label: 'TIA 1005 Cat 6 Channel E1 (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 6 Channel E2 (+ALL)', label: 'TIA 1005 Cat 6 Channel E2 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel E2 (+PoE)', label: 'TIA 1005 Cat 6 Channel E2 (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 6 Channel E3 (+ALL)', label: 'TIA 1005 Cat 6 Channel E3 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 6 Channel E3 (+PoE)', label: 'TIA 1005 Cat 6 Channel E3 (+PoE)' }
|
||||
]
|
||||
},
|
||||
Cat5e: {
|
||||
label: 'Cat5e',
|
||||
children: [
|
||||
{ value: 'TIA Cat 5e Perm.Link', label: 'TIA Cat 5e Perm.Link' },
|
||||
{ value: 'TIA Cat 5e Perm.Link (+ALL)', label: 'TIA Cat 5e Perm.Link (+ALL)' },
|
||||
{ value: 'TIA Cat 5e Perm.Link (+PoE)', label: 'TIA Cat 5e Perm.Link (+PoE)' },
|
||||
{ value: 'TIA Cat 5e Channel', label: 'TIA Cat 5e Channel' },
|
||||
{ value: 'TIA Cat 5e Channel (+ALL)', label: 'TIA Cat 5e Channel (+ALL)' },
|
||||
{ value: 'TIA Cat 5e Channel (+PoE)', label: 'TIA Cat 5e Channel (+PoE)' },
|
||||
{ value: 'TIA Cat 5e MPTL', label: 'TIA Cat 5e MPTL' },
|
||||
{ value: 'TIA Cat 5e MPTL (+PoE)', label: 'TIA Cat 5e MPTL (+PoE)' },
|
||||
// { value: 'TIA 1005 Cat 5e Perm.Link', label: 'TIA 1005 Cat 5e Perm.Link' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel', label: 'TIA 1005 Cat 5e Channel' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel (+ALL)', label: 'TIA 1005 Cat 5e Channel (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel (+PoE)', label: 'TIA 1005 Cat 5e Channel (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 5e Channel E1 (+ALL)', label: 'TIA 1005 Cat 5e Channel E1 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel E1 (+PoE)', label: 'TIA 1005 Cat 5e Channel E1 (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 5e Channel E2 (+ALL)', label: 'TIA 1005 Cat 5e Channel E2 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel E2 (+PoE)', label: 'TIA 1005 Cat 5e Channel E2 (+PoE)' },
|
||||
{ value: 'TIA 1005 Cat 5e Channel E3 (+ALL)', label: 'TIA 1005 Cat 5e Channel E3 (+ALL)' },
|
||||
// { value: 'TIA 1005 Cat 5e Channel E3 (+PoE)', label: 'TIA 1005 Cat 5e Channel E3 (+PoE)' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 'ISO',
|
||||
label: 'ISO',
|
||||
children: {
|
||||
// 'Class Ⅱ': {
|
||||
// label: 'Class Ⅱ',
|
||||
// children: [
|
||||
// { value: 'ISO11801 PL Class Ⅱ', label: 'ISO11801 PL Class Ⅱ' },
|
||||
// { value: 'ISO11801 PL Class Ⅱ (+ALL)', label: 'ISO11801 PL Class Ⅱ (+ALL)' },
|
||||
// { value: 'ISO11801 PL Class Ⅱ (+PoE)', label: 'ISO11801 PL Class Ⅱ (+PoE)' },
|
||||
// { value: 'ISO11801 Channel Class Ⅱ', label: 'ISO11801 Channel Class Ⅱ' },
|
||||
// { value: 'ISO11801 Channel Class Ⅱ (+ALL)', label: 'ISO11801 Channel Class Ⅱ (+ALL)' },
|
||||
// { value: 'ISO11801 Channel Class Ⅱ (+PoE)', label: 'ISO11801 Channel Class Ⅱ (+PoE)' }
|
||||
// ],
|
||||
// disabled: true
|
||||
// },
|
||||
// 'Class Ⅰ': {
|
||||
// label: 'Class Ⅰ',
|
||||
// children: [
|
||||
// { value: 'ISO11801 PL Class Ⅰ', label: 'ISO11801 PL Class Ⅰ' },
|
||||
// { value: 'ISO11801 PL Class Ⅰ (+ALL)', label: 'ISO11801 PL Class Ⅰ (+ALL)' },
|
||||
// { value: 'ISO11801 PL Class Ⅰ (+PoE)', label: 'ISO11801 PL Class Ⅰ (+PoE)' },
|
||||
// { value: 'ISO11801 Channel Class Ⅰ', label: 'ISO11801 Channel Class Ⅰ' },
|
||||
// { value: 'ISO11801 Channel Class Ⅰ (+ALL)', label: 'ISO11801 Channel Class Ⅰ (+ALL)' },
|
||||
// { value: 'ISO11801 Channel Class Ⅰ (+PoE)', label: 'ISO11801 Channel Class Ⅰ (+PoE)' }
|
||||
// ],
|
||||
// disabled: true
|
||||
// },
|
||||
// 'Class Fa': {
|
||||
// label: 'Class Fa',
|
||||
// children: [
|
||||
// { value: 'ISO11801 PL2 Class Fa', label: 'ISO11801 PL2 Class Fa' },
|
||||
// { value: 'ISO11801 PL2 Class Fa (+ALL)', label: 'ISO11801 PL2 Class Fa (+ALL)' },
|
||||
// { value: 'ISO11801 PL2 Class Fa (+PoE)', label: 'ISO11801 PL2 Class Fa (+PoE)' },
|
||||
// { value: 'ISO11801 PL3 Class Fa', label: 'ISO11801 PL3 Class Fa' },
|
||||
// { value: 'ISO11801 PL3 Class Fa (+ALL)', label: 'ISO11801 PL3 Class Fa (+ALL)' },
|
||||
// { value: 'ISO11801 PL3 Class Fa (+PoE)', label: 'ISO11801 PL3 Class Fa (+PoE)' },
|
||||
// { value: 'ISO11801 Channel Class Fa', label: 'ISO11801 Channel Class Fa' },
|
||||
// { value: 'ISO11801 Channel Class Fa (+ALL)', label: 'ISO11801 Channel Class Fa (+ALL)' },
|
||||
// { value: 'ISO11801 Channel Class Fa (+PoE)', label: 'ISO11801 Channel Class Fa (+PoE)' }
|
||||
// ],
|
||||
// disabled: true
|
||||
// },
|
||||
// 'Class F': {
|
||||
// label: 'Class F',
|
||||
// children: [
|
||||
// { value: 'ISO11801 PL Class F', label: 'ISO11801 PL Class F' },
|
||||
// { value: 'ISO11801 PL Class F (+ALL)', label: 'ISO11801 PL Class F (+ALL)' },
|
||||
// { value: 'ISO11801 PL Class F (+PoE)', label: 'ISO11801 PL Class F (+PoE)' },
|
||||
// { value: 'ISO11801 Channel Class F', label: 'ISO11801 Channel Class F' },
|
||||
// { value: 'ISO11801 Channel Class F (+ALL)', label: 'ISO11801 Channel Class F (+ALL)' },
|
||||
// { value: 'ISO11801 Channel Class F (+PoE)', label: 'ISO11801 Channel Class F (+PoE)' }
|
||||
// ],
|
||||
// disabled: true
|
||||
// },
|
||||
'Class Ea': {
|
||||
label: 'Class Ea',
|
||||
children: [
|
||||
{ value: 'ISO11801 PL2 Class Ea', label: 'ISO11801 PL2 Class Ea' },
|
||||
{ value: 'ISO11801 PL2 Class Ea (+ALL)', label: 'ISO11801 PL2 Class Ea (+ALL)' },
|
||||
{ value: 'ISO11801 PL2 Class Ea (+PoE)', label: 'ISO11801 PL2 Class Ea (+PoE)' },
|
||||
{ value: 'ISO11801 PL3 Class Ea', label: 'ISO11801 PL3 Class Ea' },
|
||||
{ value: 'ISO11801 PL3 Class Ea (+ALL)', label: 'ISO11801 PL3 Class Ea (+ALL)' },
|
||||
{ value: 'ISO11801 PL3 Class Ea (+PoE)', label: 'ISO11801 PL3 Class Ea (+PoE)' },
|
||||
{ value: 'ISO11801 Channel Class Ea', label: 'ISO11801 Channel Class Ea' },
|
||||
{ value: 'ISO11801 Channel Class Ea (+ALL)', label: 'ISO11801 Channel Class Ea (+ALL)' },
|
||||
{ value: 'ISO11801 Channel Class Ea (+PoE)', label: 'ISO11801 Channel Class Ea (+PoE)' },
|
||||
{ value: 'ISO MPTL Class Ea', label: 'ISO MPTL Class Ea' },
|
||||
{ value: 'ISO MPTL Class Ea (+PoE)', label: 'ISO MPTL Class Ea (+PoE)' }
|
||||
]
|
||||
},
|
||||
'Class E': {
|
||||
label: 'Class E',
|
||||
children: [
|
||||
{ value: 'ISO11801 PL Class E', label: 'ISO11801 PL Class E' },
|
||||
{ value: 'ISO11801 PL Class E (+ALL)', label: 'ISO11801 PL Class E (+ALL)' },
|
||||
{ value: 'ISO11801 PL Class E (+PoE)', label: 'ISO11801 PL Class E (+PoE)' },
|
||||
{ value: 'ISO11801 Channel Class E', label: 'ISO11801 Channel Class E' },
|
||||
{ value: 'ISO11801 Channel Class E (+ALL)', label: 'ISO11801 Channel Class E (+ALL)' },
|
||||
{ value: 'ISO11801 Channel Class E (+PoE)', label: 'ISO11801 Channel Class E (+PoE)' },
|
||||
{ value: 'ISO MPTL Class E', label: 'ISO MPTL Class E' },
|
||||
{ value: 'ISO MPTL Class E (+PoE)', label: 'ISO MPTL Class E (+PoE)' }
|
||||
]
|
||||
},
|
||||
'Class D': {
|
||||
label: 'Class D',
|
||||
children: [
|
||||
{ value: 'ISO11801 PL Class D', label: 'ISO11801 PL Class D' },
|
||||
{ value: 'ISO11801 PL Class D (+ALL)', label: 'ISO11801 PL Class D (+ALL)' },
|
||||
{ value: 'ISO11801 PL Class D (+PoE)', label: 'ISO11801 PL Class D (+PoE)' },
|
||||
{ value: 'ISO11801 Channel Class D', label: 'ISO11801 Channel Class D' },
|
||||
{ value: 'ISO11801 Channel Class D (+ALL)', label: 'ISO11801 Channel Class D (+ALL)' },
|
||||
{ value: 'ISO11801 Channel Class D (+PoE)', label: 'ISO11801 Channel Class D (+PoE)' },
|
||||
{ value: 'ISO MPTL Class D', label: 'ISO MPTL Class D' },
|
||||
{ value: 'ISO MPTL Class D (+PoE)', label: 'ISO MPTL Class D (+PoE)' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
value: '区域',
|
||||
label: '区域',
|
||||
children: {
|
||||
'中国': {
|
||||
|
||||
value: '中国',
|
||||
label: '中国',
|
||||
children: [
|
||||
// { value: 'GBT 50312-2016 Cat 7A PL no CP', label: 'GB/T 50312-2016 Cat 7A PL no CP' },
|
||||
@@ -273,36 +255,35 @@ const menuData = {
|
||||
{ value: 'GBT 50312-2016 Cat 5e Ch (+ALL)', label: 'GB/T 50312-2016 Cat 5e Ch (+ALL)' },
|
||||
{ value: 'GBT 50312-2016 Cat 5e Ch (+PoE)', label: 'GB/T 50312-2016 Cat 5e Ch (+PoE)' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
value: '跳线',
|
||||
label: '跳线',
|
||||
disabled: true,
|
||||
children: {
|
||||
'Cat6A Patch Cords': {
|
||||
label: 'Cat6A Patch Cords',
|
||||
disabled: true,
|
||||
children: []
|
||||
},
|
||||
'Cat6 Patch Cords': {
|
||||
label: 'Cat6 Patch Cords',
|
||||
disabled: true,
|
||||
children: []
|
||||
},
|
||||
'Cat5e Patch Cords': {
|
||||
label: 'Cat5e Patch Cords',
|
||||
disabled: true,
|
||||
children: []
|
||||
},
|
||||
'M12 Patch Cords': {
|
||||
label: 'M12 Patch Cords',
|
||||
disabled: true,
|
||||
children: []
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
// {
|
||||
// value: '跳线',
|
||||
// label: '跳线',
|
||||
// disabled: true,
|
||||
// children: {
|
||||
// 'Cat6A Patch Cords': {
|
||||
// label: 'Cat6A Patch Cords',
|
||||
// disabled: true,
|
||||
// children: []
|
||||
// },
|
||||
// 'Cat6 Patch Cords': {
|
||||
// label: 'Cat6 Patch Cords',
|
||||
// disabled: true,
|
||||
// children: []
|
||||
// },
|
||||
// 'Cat5e Patch Cords': {
|
||||
// label: 'Cat5e Patch Cords',
|
||||
// disabled: true,
|
||||
// children: []
|
||||
// },
|
||||
// 'M12 Patch Cords': {
|
||||
// label: 'M12 Patch Cords',
|
||||
// disabled: true,
|
||||
// children: []
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
{
|
||||
value: '应用',
|
||||
label: '应用',
|
||||
@@ -310,7 +291,18 @@ const menuData = {
|
||||
children: [
|
||||
{ value: 'Profinet', label: 'Profinet' },
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
value: '模块化插头',
|
||||
label: '模块化插头',
|
||||
disabled: false,
|
||||
children: [
|
||||
{ value: 'ISO MPTL Class Ea', label: 'ISO MPTL Class Ea' },
|
||||
{ value: 'ISO MPTL Class Ea (+PoE)', label: 'ISO MPTL Class Ea (+PoE)' },
|
||||
{ value: 'ISO MPTL Class E', label: 'ISO MPTL Class E' },
|
||||
{ value: 'ISO MPTL Class E (+PoE)', label: 'ISO MPTL Class E (+PoE)' }
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
WIRE_ORDER: {
|
||||
@@ -326,16 +318,7 @@ const menuData = {
|
||||
title: '光纤类型',
|
||||
subTitle: '电缆组',
|
||||
items: [
|
||||
{
|
||||
value: '定制',
|
||||
label: '定制',
|
||||
disabled: true,
|
||||
children: {}
|
||||
},
|
||||
{
|
||||
value: 'general',
|
||||
label: '通用',
|
||||
children: [
|
||||
|
||||
{ value: 'OM1 Mulitmode 62.5', label: 'OM1 Mulitmode 62.5' },
|
||||
{ value: 'OM2 Mulitmode 50', label: 'OM2 Mulitmode 50' },
|
||||
{ value: 'OM3 Mulitmode 50', label: 'OM3 Mulitmode 50' },
|
||||
@@ -343,32 +326,26 @@ const menuData = {
|
||||
{ value: 'OM5 Mulitmode 50', label: 'OM5 Mulitmode 50' },
|
||||
{ value: 'OS1 Singlemode', label: 'OS1 Singlemode' },
|
||||
{ value: 'OS2 Singlemode', label: 'OS2 Singlemode' }
|
||||
]
|
||||
},
|
||||
{
|
||||
value: '制造商',
|
||||
label: '制造商',
|
||||
disabled: true,
|
||||
children: {}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
CFP_LIMIT: {
|
||||
title: '测试极限值',
|
||||
subTitle: '极限值组',
|
||||
items: [
|
||||
{
|
||||
value: 'TIA',
|
||||
label: 'TIA',
|
||||
children: [
|
||||
{ value: 'TIA-568.3-E Multimode (STD)', label: 'TIA-568.3-E Multimode (STD)' },
|
||||
{ value: 'TIA-568.3-E Multimode (REF)', label: 'TIA-568.3-E Multimode (REF)' },
|
||||
{ value: 'TIA-568.3-E Singlemode ISP (STD)', label: 'TIA-568.3-E Singlemode ISP (STD)' },
|
||||
{ value: 'TIA-568.3-E Singlemode OSP (STD)', label: 'TIA-568.3-E Singlemode OSP (STD)' },
|
||||
{ value: 'TIA-568.3-E Singlemode ISP (REF)', label: 'TIA-568.3-E Singlemode ISP (REF)' },
|
||||
{ value: 'TIA-568.3-E Singlemode OSP (REF)', label: 'TIA-568.3-E Singlemode OSP (REF)' }
|
||||
]
|
||||
},
|
||||
// {
|
||||
// value: 'TIA',
|
||||
// label: 'TIA',
|
||||
// children: [
|
||||
// { value: 'TIA-568.3-E Multimode (STD)', label: 'TIA-568.3-E Multimode (STD)' },
|
||||
// { value: 'TIA-568.3-E Multimode (REF)', label: 'TIA-568.3-E Multimode (REF)' },
|
||||
// { value: 'TIA-568.3-E Singlemode ISP (STD)', label: 'TIA-568.3-E Singlemode ISP (STD)' },
|
||||
// { value: 'TIA-568.3-E Singlemode OSP (STD)', label: 'TIA-568.3-E Singlemode OSP (STD)' },
|
||||
// { value: 'TIA-568.3-E Singlemode ISP (REF)', label: 'TIA-568.3-E Singlemode ISP (REF)' },
|
||||
// { value: 'TIA-568.3-E Singlemode OSP (REF)', label: 'TIA-568.3-E Singlemode OSP (REF)' }
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
value: 'China',
|
||||
label: '中国',
|
||||
@@ -379,34 +356,34 @@ const menuData = {
|
||||
{ value: 'GB/T 50312-2016 OF-2000 Ch', label: 'GB/T 50312-2016 OF-2000 Ch' }
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 'ISO',
|
||||
label: 'ISO',
|
||||
children: [
|
||||
{ value: 'ISO/IEC 11801-2002 Fibre Link', label: 'ISO/IEC 11801-2002 Fibre Link' },
|
||||
{ value: 'ISO/IEC 11801-2002 OF-300 CH', label: 'ISO/IEC 11801-2002 OF-300 CH' },
|
||||
{ value: 'ISO/IEC 11801-2002 OF-500 CH', label: 'ISO/IEC 11801-2002 OF-500 CH' },
|
||||
{ value: 'ISO/IEC 11801-2002 OF-2000 CH', label: 'ISO/IEC 11801-2002 OF-2000 CH' },
|
||||
{ value: 'ISO/IEC 14763-3:2024 (Draft)', label: 'ISO/IEC 14763-3:2024 (Draft)' },
|
||||
{ value: 'ISO/IEC 14763-3:2014', label: 'ISO/IEC 14763-3:2014' },
|
||||
{ value: 'ISO/IEC 14763-3', label: 'ISO/IEC 14763-3' }
|
||||
]
|
||||
}
|
||||
// {
|
||||
// value: 'ISO',
|
||||
// label: 'ISO',
|
||||
// children: [
|
||||
// { value: 'ISO/IEC 11801-2002 Fibre Link', label: 'ISO/IEC 11801-2002 Fibre Link' },
|
||||
// { value: 'ISO/IEC 11801-2002 OF-300 CH', label: 'ISO/IEC 11801-2002 OF-300 CH' },
|
||||
// { value: 'ISO/IEC 11801-2002 OF-500 CH', label: 'ISO/IEC 11801-2002 OF-500 CH' },
|
||||
// { value: 'ISO/IEC 11801-2002 OF-2000 CH', label: 'ISO/IEC 11801-2002 OF-2000 CH' },
|
||||
// { value: 'ISO/IEC 14763-3:2024 (Draft)', label: 'ISO/IEC 14763-3:2024 (Draft)' },
|
||||
// { value: 'ISO/IEC 14763-3:2014', label: 'ISO/IEC 14763-3:2014' },
|
||||
// { value: 'ISO/IEC 14763-3', label: 'ISO/IEC 14763-3' }
|
||||
// ]
|
||||
// }
|
||||
]
|
||||
},
|
||||
OFP_LIMIT: {
|
||||
title: 'OFP极限值',
|
||||
items: [
|
||||
{
|
||||
value: 'TIA',
|
||||
label: 'TIA',
|
||||
children: [
|
||||
{ value: 'ANSI/TIA-568.3-E', label: 'ANSI/TIA-568.3-E' },
|
||||
{ value: 'ANSI/TIA-568.3-E RL = 20 dB', label: 'ANSI/TIA-568.3-E RL = 20 dB' },
|
||||
{ value: 'ANSI/TIA-568.3-E RL = 35 dB', label: 'ANSI/TIA-568.3-E RL = 35 dB' },
|
||||
{ value: 'ANSI/TIA-568.3-E RL = 55 dB', label: 'ANSI/TIA-568.3-E RL = 55 dB' }
|
||||
]
|
||||
},
|
||||
// {
|
||||
// value: 'TIA',
|
||||
// label: 'TIA',
|
||||
// children: [
|
||||
// { value: 'ANSI/TIA-568.3-E', label: 'ANSI/TIA-568.3-E' },
|
||||
// { value: 'ANSI/TIA-568.3-E RL = 20 dB', label: 'ANSI/TIA-568.3-E RL = 20 dB' },
|
||||
// { value: 'ANSI/TIA-568.3-E RL = 35 dB', label: 'ANSI/TIA-568.3-E RL = 35 dB' },
|
||||
// { value: 'ANSI/TIA-568.3-E RL = 55 dB', label: 'ANSI/TIA-568.3-E RL = 55 dB' }
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
value: 'China',
|
||||
label: '中国',
|
||||
@@ -417,22 +394,22 @@ const menuData = {
|
||||
{ value: 'GB/T 50312-2016 OF-2000 Ch', label: 'GB/T 50312-2016 OF-2000 Ch' }
|
||||
]
|
||||
},
|
||||
{
|
||||
value: 'ISO',
|
||||
label: 'ISO',
|
||||
children: [
|
||||
{ value: 'ISO/IEC 11801-2002 Fibre Link', label: 'ISO/IEC 11801-2002 Fibre Link' },
|
||||
{ value: 'ISO/IEC 11801-2002 OF-300 CH', label: 'ISO/IEC 11801-2002 OF-300 CH' },
|
||||
{ value: 'ISO/IEC 11801-2002 OF-500 CH', label: 'ISO/IEC 11801-2002 OF-500 CH' },
|
||||
{ value: 'ISO/IEC 11801-2002 OF-2000 CH', label: 'ISO/IEC 11801-2002 OF-2000 CH' },
|
||||
{ value: 'ISO/IEC 14763-3:2024 (Draft)', label: 'ISO/IEC 14763-3:2024 (Draft)' },
|
||||
{ value: 'ISO/IEC 14763-3:2024 RL = 20 (Draft)', label: 'ISO/IEC 14763-3:2024 RL = 20 (Draft)' },
|
||||
{ value: 'ISO/IEC 14763-3:2024 RL = 35 (Draft)', label: 'ISO/IEC 14763-3:2024 RL = 35 (Draft)' },
|
||||
{ value: 'ISO/IEC 14763-3:2024 RL = 60 (Draft)', label: 'ISO/IEC 14763-3:2024 RL = 60 (Draft)' },
|
||||
{ value: 'ISO/IEC 14763-3:2014', label: 'ISO/IEC 14763-3:2014' },
|
||||
{ value: 'ISO/IEC 14763-3', label: 'ISO/IEC 14763-3' }
|
||||
]
|
||||
}
|
||||
// {
|
||||
// value: 'ISO',
|
||||
// label: 'ISO',
|
||||
// children: [
|
||||
// { value: 'ISO/IEC 11801-2002 Fibre Link', label: 'ISO/IEC 11801-2002 Fibre Link' },
|
||||
// { value: 'ISO/IEC 11801-2002 OF-300 CH', label: 'ISO/IEC 11801-2002 OF-300 CH' },
|
||||
// { value: 'ISO/IEC 11801-2002 OF-500 CH', label: 'ISO/IEC 11801-2002 OF-500 CH' },
|
||||
// { value: 'ISO/IEC 11801-2002 OF-2000 CH', label: 'ISO/IEC 11801-2002 OF-2000 CH' },
|
||||
// { value: 'ISO/IEC 14763-3:2024 (Draft)', label: 'ISO/IEC 14763-3:2024 (Draft)' },
|
||||
// { value: 'ISO/IEC 14763-3:2024 RL = 20 (Draft)', label: 'ISO/IEC 14763-3:2024 RL = 20 (Draft)' },
|
||||
// { value: 'ISO/IEC 14763-3:2024 RL = 35 (Draft)', label: 'ISO/IEC 14763-3:2024 RL = 35 (Draft)' },
|
||||
// { value: 'ISO/IEC 14763-3:2024 RL = 60 (Draft)', label: 'ISO/IEC 14763-3:2024 RL = 60 (Draft)' },
|
||||
// { value: 'ISO/IEC 14763-3:2014', label: 'ISO/IEC 14763-3:2014' },
|
||||
// { value: 'ISO/IEC 14763-3', label: 'ISO/IEC 14763-3' }
|
||||
// ]
|
||||
// }
|
||||
]
|
||||
}
|
||||
};
|
||||
@@ -490,9 +467,9 @@ export default function MenuList() {
|
||||
updatedConfig.params.cableType = item.value;
|
||||
if (updatedConfig.moduleType === 'cfp') {
|
||||
if (item.value.includes('OM')) {
|
||||
updatedConfig.params.limitValue = 'TIA-568.3-E Multimode (STD)';
|
||||
updatedConfig.params.limitValue = 'GB/T 50312-2016 Fiber Link';
|
||||
} else {
|
||||
updatedConfig.params.limitValue = 'TIA-568.3-E Singlemode ISP (STD)';
|
||||
updatedConfig.params.limitValue = 'GB/T 50312-2016 Fiber Link';
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -512,7 +489,7 @@ export default function MenuList() {
|
||||
moduleType: '8000',
|
||||
modulelable: '铜缆测试仪',
|
||||
params: {
|
||||
limitValue: 'TIA Cat 6 Channel',
|
||||
limitValue: 'GBT 50312-2016 Cat 6 Ch',
|
||||
cableType: 'Cat6 U/UTP',
|
||||
wireOrder: 'T568B'
|
||||
}
|
||||
@@ -524,7 +501,7 @@ export default function MenuList() {
|
||||
moduleType: 'cfp',
|
||||
modulelable: '光损耗测试仪',
|
||||
params: {
|
||||
limitValue: 'TIA-568.3-E Multimode (STD)',
|
||||
limitValue: 'GB/T 50312-2016 Fiber Link',
|
||||
cableType: 'OM3 Multimode 50',
|
||||
refJumper: '1',
|
||||
spliceCount: '0',
|
||||
@@ -538,7 +515,7 @@ export default function MenuList() {
|
||||
moduleType: 'ofp',
|
||||
modulelable: 'OTDR测试仪',
|
||||
params: {
|
||||
limitValue: 'General Fiber RL = 35 dB',
|
||||
limitValue: 'GB/T 50312-2016 Fiber Link',
|
||||
cableType: 'OM3 Multimode 50'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ import SubTitleBar from '@/components/lib//SubTitleBar';
|
||||
import Keyboard from '@/components/lib//Keyboard';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
import { UserIcon, TagIcon, ChartBarIcon, SwatchIcon } from '@heroicons/react/24/solid';
|
||||
|
||||
export default function Project() {
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
@@ -238,7 +239,7 @@ export default function Project() {
|
||||
moduleType: '8000',
|
||||
modulelable: '铜缆测试仪',
|
||||
params: {
|
||||
limitValue: 'TIA Cat 6 Channel',
|
||||
limitValue: 'GBT 50312-2016 Cat 6 Ch',
|
||||
cableType: 'Cat6 U/UTP',
|
||||
wireOrder: 'T568B'
|
||||
}
|
||||
@@ -284,224 +285,211 @@ export default function Project() {
|
||||
case 'main':
|
||||
default:
|
||||
return (
|
||||
<div className="flex-1 bg-[#D5DFEB] p-4 space-y-4">
|
||||
{/* 操作员信息 */}
|
||||
<div className="flex-1 bg-[#D5DFEB] p-4 flex gap-4 overflow-hidden">
|
||||
{/* 左侧区域:操作员、结果命名、结果统计 */}
|
||||
<div className="w-1/3 flex flex-col gap-2 overflow-y-auto">
|
||||
{/* 操作员信息 */}
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-black flex items-center gap-1"><UserIcon className="w-4 h-4 text-black" /> 操作人员</span>
|
||||
</div>
|
||||
<div
|
||||
className="h-[70px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('operators', 'main')}
|
||||
>
|
||||
<div className="text-black text-sm"> {currentProject?.operators[useDisplayStore.getState().selectedIndexes.operatorIndex]?.name}</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* 结果命名 */}
|
||||
<div className="space-y-1">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-black flex items-center gap-1"><TagIcon className="w-4 h-4 text-black" /> 下一条记录</span>
|
||||
</div>
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('operators', 'main')}
|
||||
className="h-[70px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('cableId', 'main')}
|
||||
>
|
||||
<div className="text-black text-sm">操作员: {currentProject?.operators[useDisplayStore.getState().selectedIndexes.operatorIndex]?.name}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/arrow.png')}
|
||||
alt="箭头"
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 结果统计 */}
|
||||
<div className="space-y-1">
|
||||
<div className="text-sm text-gray-400">
|
||||
结果 {currentProject?.testResults[0]?.date} - {currentProject?.testResults[currentProject.testResults.length - 1]?.date}
|
||||
</div>
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('result', 'main')}
|
||||
>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-green-500">{passCount|| 0}</span>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/pass.png')}
|
||||
alt="通过"
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-red-500">{failCount|| 0}</span>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/fail.png')}
|
||||
alt="失败"
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-black text-sm">
|
||||
{currentProject?.cableIds?.[0]?.name || '001'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/arrow.png')}
|
||||
alt="箭头"
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 测试设置 */}
|
||||
<div className="space-y-1 flex-1 overflow-hidden">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-gray-400">测试设置</span>
|
||||
<button
|
||||
className="bg-[#404040] text-white px-3 py-1 rounded-sm text-sm"
|
||||
onClick={() => {
|
||||
// 生成唯一ID
|
||||
const generateId = () => Math.random().toString(36).substr(2, 9);
|
||||
|
||||
// 创建新的测试配置
|
||||
const newConfig = {
|
||||
id: generateId(),
|
||||
name: '新测试配置',
|
||||
moduleType: '8000',
|
||||
modulelable: '铜缆测试仪',
|
||||
params: {
|
||||
limitValue: 'TIA Cat 6 Channel',
|
||||
cableType: 'Cat6 U/UTP',
|
||||
wireOrder: 'T568B',
|
||||
refJumper: '1',
|
||||
spliceCount: '0',
|
||||
connectorCount: '2'
|
||||
}
|
||||
};
|
||||
|
||||
// 更新项目,添加新的测试配置
|
||||
const currentProjectIndex = useDisplayStore.getState().selectedIndexes.projectIndex;
|
||||
const updatedProject = {
|
||||
...currentProject,
|
||||
testConfigs: [...currentProject.testConfigs, newConfig]
|
||||
};
|
||||
updateProject(currentProjectIndex, updatedProject);
|
||||
|
||||
// 设置新配置为选中状态
|
||||
const newConfigIndex = updatedProject.testConfigs.length - 1;
|
||||
setSelectedIndexes({ testConfigIndex: newConfigIndex });
|
||||
|
||||
// 跳转到测试配置页面并进入编辑视图
|
||||
navigateTo('testConfig', 'setup');
|
||||
}}
|
||||
>
|
||||
新测试
|
||||
</button>
|
||||
</div>
|
||||
<div className="h-[100px] overflow-y-auto space-y-2 pr-2">
|
||||
{currentProject?.testConfigs.map((config, index) => (
|
||||
<div
|
||||
key={config.id}
|
||||
className="h-[100px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg cursor-pointer"
|
||||
onClick={() => navigateTo('testConfig', 'main')}
|
||||
>
|
||||
<div className="flex justify-between">
|
||||
<div className="space-y-0.2">
|
||||
{config.moduleType === '8000' && (
|
||||
<>
|
||||
<div className="text-black text-sm">{config.params.limitValue}</div>
|
||||
<div className="text-black text-sm">{config.params.cableType}</div>
|
||||
<div className="text-black text-sm">{config.params.wireOrder}</div>
|
||||
</>
|
||||
)}
|
||||
{config.moduleType === 'cfp' && (
|
||||
<>
|
||||
<div className="text-black text-sm">智能远端</div>
|
||||
<div className="text-black text-sm">{config.params.limitValue}</div>
|
||||
<div className="text-black text-sm">{config.params.cableType}</div>
|
||||
<div className="text-black text-sm">{config.params.refJumper} 跳线参照</div>
|
||||
</>
|
||||
)}
|
||||
{config.moduleType === 'ofp' && (
|
||||
<>
|
||||
<div className="text-black text-sm">自动OTDR</div>
|
||||
<div className="text-black text-sm">{config.params.limitValue}</div>
|
||||
<div className="text-black text-sm">{config.params.cableType}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col items-end justify-between">
|
||||
<span className="text-gray-500 text-sm">{config.modulelable}</span>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
className="w-6 h-6 bg-[#404040] rounded-sm flex items-center justify-center"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation(); // 阻止事件冒泡
|
||||
const currentProjectIndex = useDisplayStore.getState().selectedIndexes.projectIndex;
|
||||
const currentTestConfigIndex = useDisplayStore.getState().selectedIndexes.testConfigIndex;
|
||||
const selectedConfigId = currentProject.testConfigs[currentTestConfigIndex]?.id;
|
||||
|
||||
// 禁止删除最后一项配置
|
||||
if (currentProject.testConfigs.length <= 1) {
|
||||
setToastMessage('不能删除最后一项配置');
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新项目,删除选中的测试配置
|
||||
const updatedProject = {
|
||||
...currentProject,
|
||||
testConfigs: currentProject.testConfigs.filter(
|
||||
testConfig => testConfig.id !== config.id
|
||||
)
|
||||
};
|
||||
updateProject(currentProjectIndex, updatedProject);
|
||||
|
||||
// 更新选中索引
|
||||
const newIndex = updatedProject.testConfigs.findIndex(
|
||||
testConfig => testConfig.id === selectedConfigId
|
||||
);
|
||||
|
||||
// 如果删除的是当前选中的配置,或者找不到选中的配置ID,则设置索引为0
|
||||
setSelectedIndexes({
|
||||
testConfigIndex: newIndex === -1 ? 0 : newIndex
|
||||
});
|
||||
}}
|
||||
>
|
||||
<div className="w-4 h-4 relative">
|
||||
{/* 结果统计 */}
|
||||
<div className="space-y-1">
|
||||
<div className="text-sm text-black flex items-center gap-1 ">
|
||||
<ChartBarIcon className="w-4 h-4 text-black" /> 结果统计 {currentProject?.testResults[0]?.date} - {currentProject?.testResults[currentProject.testResults.length - 1]?.date}
|
||||
</div>
|
||||
<div
|
||||
className="h-[70px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('result', 'main')}
|
||||
>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-green-500">{passCount|| 0}</span>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/delete.png')}
|
||||
alt="删除"
|
||||
src={getAssetUrl('/pass.png')}
|
||||
alt="通过"
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-red-500">{failCount|| 0}</span>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/fail.png')}
|
||||
alt="失败"
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 电缆ID集 */}
|
||||
<div className="space-y-1">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-sm text-gray-400">电缆ID集</span>
|
||||
</div>
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('cableId', 'main')}
|
||||
{/* 右侧区域:测试设置 */}
|
||||
<div className="w-2/3 flex flex-col h-full overflow-hidden">
|
||||
<div className="space-y-1 flex-1 flex flex-col overflow-hidden">
|
||||
<div className="flex justify-between items-center shrink-0">
|
||||
<span className="text-sm text-black flex items-center gap-1"><SwatchIcon className="w-4 h-4 text-black" /> 测试设置</span>
|
||||
</div>
|
||||
<div className="flex-1 overflow-y-auto space-y-2 pr-2 mt-1">
|
||||
{currentProject?.testConfigs.map((config, index) => (
|
||||
<div
|
||||
key={config.id}
|
||||
className="h-[90px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg cursor-pointer"
|
||||
onClick={() => navigateTo('testConfig', 'main')}
|
||||
>
|
||||
<div className="flex justify-between">
|
||||
<div className="space-y-0.2">
|
||||
{config.moduleType === '8000' && (
|
||||
<>
|
||||
<div className="text-black text-xs">{config.params.limitValue}</div>
|
||||
<div className="text-black text-xs">{config.params.cableType}</div>
|
||||
<div className="text-black text-xs">{config.params.wireOrder}</div>
|
||||
</>
|
||||
)}
|
||||
{config.moduleType === 'cfp' && (
|
||||
<>
|
||||
<div className="text-black text-xs">光纤损耗测试</div>
|
||||
<div className="text-black text-xs">{config.params.limitValue}</div>
|
||||
<div className="text-black text-xs">{config.params.cableType}</div>
|
||||
<div className="text-black text-xs">{config.params.refJumper} 跳线参照</div>
|
||||
</>
|
||||
)}
|
||||
{config.moduleType === 'ofp' && (
|
||||
<>
|
||||
<div className="text-black text-xs">自动OTDR</div>
|
||||
<div className="text-black text-xs">{config.params.limitValue}</div>
|
||||
<div className="text-black text-xs">{config.params.cableType}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col items-end justify-between">
|
||||
<span className="text-gray-500 text-[0.65rem]">{config.modulelable}</span>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
className="w-6 h-6 bg-[#404040] rounded-sm flex items-center justify-center"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation(); // 阻止事件冒泡
|
||||
const currentProjectIndex = useDisplayStore.getState().selectedIndexes.projectIndex;
|
||||
const currentTestConfigIndex = useDisplayStore.getState().selectedIndexes.testConfigIndex;
|
||||
const selectedConfigId = currentProject.testConfigs[currentTestConfigIndex]?.id;
|
||||
|
||||
// 禁止删除最后一项配置
|
||||
if (currentProject.testConfigs.length <= 1) {
|
||||
setToastMessage('不能删除最后一项配置');
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新项目,删除选中的测试配置
|
||||
const updatedProject = {
|
||||
...currentProject,
|
||||
testConfigs: currentProject.testConfigs.filter(
|
||||
testConfig => testConfig.id !== config.id
|
||||
)
|
||||
};
|
||||
updateProject(currentProjectIndex, updatedProject);
|
||||
|
||||
// 更新选中索引
|
||||
const newIndex = updatedProject.testConfigs.findIndex(
|
||||
testConfig => testConfig.id === selectedConfigId
|
||||
);
|
||||
|
||||
// 如果删除的是当前选中的配置,或者找不到选中的配置ID,则设置索引为0
|
||||
setSelectedIndexes({
|
||||
testConfigIndex: newIndex === -1 ? 0 : newIndex
|
||||
});
|
||||
}}
|
||||
>
|
||||
<div className="w-4 h-4 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/delete.png')}
|
||||
alt="删除"
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<button
|
||||
className="bg-[#404040] text-white px-3 py-1 rounded-sm text-sm "
|
||||
onClick={() => {
|
||||
// 生成唯一ID
|
||||
const generateId = () => Math.random().toString(36).substr(2, 9);
|
||||
|
||||
// 创建新的测试配置
|
||||
const newConfig = {
|
||||
id: generateId(),
|
||||
name: '新测试配置',
|
||||
moduleType: '8000',
|
||||
modulelable: '铜缆测试仪',
|
||||
params: {
|
||||
limitValue: 'GBT 50312-2016 Cat 6 Ch',
|
||||
cableType: 'Cat6 U/UTP',
|
||||
wireOrder: 'T568B',
|
||||
refJumper: '1',
|
||||
spliceCount: '0',
|
||||
connectorCount: '2'
|
||||
}
|
||||
};
|
||||
|
||||
// 更新项目,添加新的测试配置
|
||||
const currentProjectIndex = useDisplayStore.getState().selectedIndexes.projectIndex;
|
||||
const updatedProject = {
|
||||
...currentProject,
|
||||
testConfigs: [...currentProject.testConfigs, newConfig]
|
||||
};
|
||||
updateProject(currentProjectIndex, updatedProject);
|
||||
|
||||
// 设置新配置为选中状态
|
||||
const newConfigIndex = updatedProject.testConfigs.length - 1;
|
||||
setSelectedIndexes({ testConfigIndex: newConfigIndex });
|
||||
|
||||
// 跳转到测试配置页面并进入编辑视图
|
||||
navigateTo('testConfig', 'setup');
|
||||
}}
|
||||
>
|
||||
<div className="text-black text-sm">
|
||||
下一个ID: {currentProject?.cableIds?.[0]?.name || '001'}
|
||||
</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl('/arrow.png')}
|
||||
alt="箭头"
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
新测试
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -7,6 +7,7 @@ import useDisplayStore from '@/store/displayStore';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import MenuList from './MenuList.js';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
import { TagIcon, SwatchIcon, Bars3Icon, SignalIcon } from '@heroicons/react/24/solid';
|
||||
|
||||
|
||||
|
||||
@@ -90,7 +91,7 @@ export default function TestConfig() {
|
||||
)}
|
||||
{config.moduleType === 'cfp' && (
|
||||
<>
|
||||
<div className="text-black text-sm">智能远端</div>
|
||||
<div className="text-black text-sm">光纤损耗测试</div>
|
||||
<div className="text-black text-sm">{config.params.limitValue}</div>
|
||||
<div className="text-black text-sm">{config.params.cableType}</div>
|
||||
<div className="text-black text-sm">{config.params.refJumper} 跳线参照</div>
|
||||
@@ -136,29 +137,35 @@ export default function TestConfig() {
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-0">
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'CABLE_TYPE',
|
||||
selectedConfigId: selectedConfigId,
|
||||
backTo: 'testconfig',
|
||||
backView: 'setup'
|
||||
})}
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center"
|
||||
|
||||
>
|
||||
<div className="text-black text-l font-bold">电缆类型:{currentConfig.params.cableType}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><TagIcon className="w-4 h-4 text-black" /> 电缆类型</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l">NVP:根据电缆类型生成</div>
|
||||
<div
|
||||
className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'CABLE_TYPE',
|
||||
selectedConfigId: selectedConfigId,
|
||||
backTo: 'testconfig',
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
|
||||
<div className="text-black text-l">{currentConfig.params.cableType}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-0">
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center"
|
||||
>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><SwatchIcon className="w-4 h-4 text-black" /> 测试极限值</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'LIMIT_VALUE',
|
||||
selectedConfigId: selectedConfigId,
|
||||
@@ -166,74 +173,72 @@ export default function TestConfig() {
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
<div className="text-black text-l font-bold">测试极限值:{currentConfig.params.limitValue}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l">存储测试数据:开</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l">TDR/TDX:仅失败</div>
|
||||
<div className="text-black text-l">{currentConfig.params.limitValue}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'WIRE_ORDER',
|
||||
selectedConfigId: selectedConfigId,
|
||||
backTo: 'testconfig',
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
<div className="text-black text-l font-bold">插座配置:{currentConfig.params.wireOrder}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
|
||||
<div className="space-y-0">
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center"
|
||||
>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><Bars3Icon className="w-4 h-4 text-black" /> 线缆线序</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'WIRE_ORDER',
|
||||
selectedConfigId: selectedConfigId,
|
||||
backTo: 'testconfig',
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
<div className="text-black text-l">{currentConfig.params.wireOrder}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
case 'cfp':
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
|
||||
<div className="space-y-0">
|
||||
<div className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l font-bold">测试类型:智能远端</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center"
|
||||
>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><TagIcon className="w-4 h-4 text-black" /> 光纤类型</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l">双向:关</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'FIBER_TYPE',
|
||||
selectedConfigId: selectedConfigId,
|
||||
backTo: 'testconfig',
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
<div className="text-black text-l font-bold">光纤类型:{currentConfig.params.cableType}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
>
|
||||
<div className="text-black text-l">{currentConfig.params.cableType}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div className="space-y-0">
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center "
|
||||
>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><SwatchIcon className="w-4 h-4 text黑色" /> 测试极限值</div>
|
||||
</div>
|
||||
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] p-4 shadow-lg flex justify-between items-center cursor-pointer "
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'CFP_LIMIT',
|
||||
selectedConfigId: selectedConfigId,
|
||||
@@ -241,29 +246,31 @@ export default function TestConfig() {
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
<div className="text-black text-l font-bold">测试极限值:{currentConfig.params.limitValue}</div>
|
||||
<div className="text-black text-l" >{currentConfig.params.limitValue}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] p-4 shadow-lg flex justify-between items-center cursor-pointer " onClick={() => updateCurrentView('cfp-conunt')}>
|
||||
<div className="text-black text-l ">参照方法:{currentConfig.params.refJumper} 跳线</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l">连接器类型:LC</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] p-4 shadow-lg flex justify-between items-center cursor-pointer " onClick={() => updateCurrentView('cfp-conunt')}>
|
||||
<div className="text-black text-l ">连接器的数量:{currentConfig.params.connectorCount}个</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center cursor-pointer " onClick={() => updateCurrentView('cfp-conunt')}>
|
||||
<div className="text-black text-l" >接线/接头的数量:{currentConfig.params.connectorCount}/{currentConfig.params.spliceCount}</div>
|
||||
<div className="text-black text-l" >熔接点的数量:{currentConfig.params.spliceCount}个</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -272,26 +279,23 @@ export default function TestConfig() {
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-0">
|
||||
<div className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l font-bold">测试类型:自动OTDR</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l ">前导补偿:开</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
{/* <Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" /> */}
|
||||
</div>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><SignalIcon className="w-4 h-4 text-black" />测试波长</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center">
|
||||
<div className="text-black text-l ">波长:{currentConfig.params.cableType.includes('OM') ? '850 nm、1310nm' : '1310nm、1550nm'}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
{/* <Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" /> */}
|
||||
<div className="text-black text-l ">{currentConfig.params.cableType.includes('OM') ? '850 nm、1310nm' : '1310nm、1550nm'}</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-0">
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center"
|
||||
>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><TagIcon className="w-4 h-4 text黑色" /> 光纤类型</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'FIBER_TYPE',
|
||||
selectedConfigId: selectedConfigId,
|
||||
@@ -299,13 +303,21 @@ export default function TestConfig() {
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
<div className="text-black text-l font-bold">光纤类型:{currentConfig.params.cableType}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
<div className="text-black text-l">{currentConfig.params.cableType}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
|
||||
|
||||
<div className="space-y-0">
|
||||
<div
|
||||
className="h-[50px] bg-[#F8F6F7] rounded-t-sm p-4 shadow-lg flex justify-between items-center"
|
||||
>
|
||||
<div className="text-black text-l font-bold flex items-center gap-1"><SwatchIcon className="w-4 h-4 text黑色" /> 测试极限值</div>
|
||||
</div>
|
||||
<div className="h-[50px] bg-gradient-to-b from-[#ffffff] to-[#ffffff] rounded-b-sm p-4 shadow-lg flex justify-between items-center cursor-pointer"
|
||||
onClick={() => navigateTo('menulist', 'setup', {
|
||||
menuType: 'OFP_LIMIT',
|
||||
selectedConfigId: selectedConfigId,
|
||||
@@ -313,11 +325,14 @@ export default function TestConfig() {
|
||||
backView: 'setup'
|
||||
})}
|
||||
>
|
||||
<div className="text-black text-l font-bold">测试极限值:{currentConfig.params.limitValue}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
<div className="text-black text-l">{currentConfig.params.limitValue}</div>
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image src={getAssetUrl('/arrow.png')} alt="箭头" fill className="object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
default:
|
||||
@@ -410,7 +425,7 @@ export default function TestConfig() {
|
||||
moduleType: '8000',
|
||||
modulelable: '铜缆测试仪',
|
||||
params: {
|
||||
limitValue: 'TIA Cat 6 Channel',
|
||||
limitValue: 'GBT 50312-2016 Cat 6 Ch',
|
||||
cableType: 'Cat6 U/UTP',
|
||||
wireOrder: 'T568B',
|
||||
refJumper: '1',
|
||||
|
||||
@@ -4,6 +4,7 @@ import TitleBar from '@/components/lib//TitleBar';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
|
||||
// 计算电阻余量的函数
|
||||
function calculateResistanceMargin(data, limitdata, limitValue) {
|
||||
@@ -722,7 +723,7 @@ export default function Testing() {
|
||||
{/* 背景图片 */}
|
||||
<div
|
||||
className="absolute inset-0 bg-cover bg-center bg-no-repeat"
|
||||
style={{ backgroundImage: 'url(/testing.gif)' }}
|
||||
style={{ backgroundImage: `url(${getAssetUrl('/testing.gif')})` }}
|
||||
/>
|
||||
|
||||
{/* 测试配置limit值 */}
|
||||
|
||||
@@ -663,9 +663,9 @@ export default function Tools() {
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex items-end justify-end px-20">
|
||||
<div className="relative flex flex-col items-start space-y-20">
|
||||
<div className="relative flex flex-col items-start space-y-20 pt-10">
|
||||
<div className="flex flex-col space-y-4 mb-4">
|
||||
<label className="text-white text-xl flex items-center">
|
||||
<label className="text-black text-xl flex items-center">
|
||||
<input
|
||||
type="radio"
|
||||
name="compensation"
|
||||
@@ -677,7 +677,7 @@ export default function Tools() {
|
||||
仅前导
|
||||
</label>
|
||||
{faultScenario !== 'DataCenter' && (
|
||||
<label className="text-white text-xl flex items-center">
|
||||
<label className="text-black text-xl flex items-center">
|
||||
<input
|
||||
type="radio"
|
||||
name="compensation"
|
||||
@@ -689,7 +689,7 @@ export default function Tools() {
|
||||
</label>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-white text-m mb-4">
|
||||
<div className="text-black text-m mb-4">
|
||||
光纤类型:{currentConfig?.params?.cableType}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -150,7 +150,17 @@ export default function CopperResultMain({ testResult: initialTestResult }) {
|
||||
useEffect(() => {
|
||||
navigateTo(navigation.current.name, navigation.current.view, { ...navigation.current.params, activeTab });
|
||||
}, [activeTab]);
|
||||
const tabs = testResult?.CopperWiremapResultStatus === 'pass' ? (testResult?.resultdata?.result === 'pass' ? ['布线图', '性能'] : ['布线图', '性能', '诊断']) : ['布线图'];
|
||||
const tabs = (() => {
|
||||
if (estmodel === 'general') {
|
||||
if (testResult?.CopperWiremapResultStatus === 'pass') {
|
||||
return testResult?.resultdata?.result === 'pass' ? ['布线图', '性能'] : ['布线图', '性能'];
|
||||
}
|
||||
return ['布线图'];
|
||||
}
|
||||
return testResult?.CopperWiremapResultStatus === 'pass'
|
||||
? (testResult?.resultdata?.result === 'pass' ? ['布线图', '性能'] : ['布线图', '性能', '诊断'])
|
||||
: ['布线图'];
|
||||
})();
|
||||
|
||||
//console.log(testResult);
|
||||
const renderContent = () => {
|
||||
|
||||
@@ -11,16 +11,28 @@ export default function DiagnosticView({ testResult }) {
|
||||
navigateTo('copperperformance', 'HDTD', { testResult, curtitle });
|
||||
};
|
||||
|
||||
const renderRow = (title) => (
|
||||
<div
|
||||
className="w-full flex items-center justify-between p-3 mb-2 rounded-md bg-[#F8F6F7] shadow-md cursor-pointer"
|
||||
onClick={() => handleRowClick(title)}
|
||||
>
|
||||
<span className="text-lg font-medium text-black">
|
||||
{title === 'HDTDR' ? '回波损耗分析' : title === 'HDTDX' ? '串扰分析' : title}
|
||||
</span>
|
||||
const renderRow = (title) => (
|
||||
estmodel === 'general' ? (
|
||||
<div
|
||||
className="w-full flex items-center justify-between p-3 mb-2 rounded-md bg-[#F8F6F7] shadow-md cursor-pointer"
|
||||
onClick={() => handleRowClick(title)}
|
||||
>
|
||||
<span className="text-lg font-medium text-black">
|
||||
{title === 'HDTDR' ? '时域反射分析' : title === 'HDTDX' ? '串扰分析' : title}
|
||||
</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className="w-full flex items-center justify-between p-3 mb-2 rounded-md bg-gradient-to-b from-[#dedede] via-[#b5b5b5] to-[#8b898b] shadow-md cursor-pointer"
|
||||
onClick={() => handleRowClick(title)}
|
||||
>
|
||||
<span className="text-lg font-medium text-black">
|
||||
{title}
|
||||
</span>
|
||||
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import React, { useState, useEffect, useMemo, useCallback } from 'react';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
import Image from 'next/image';
|
||||
import { useRef } from 'react';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
import EventTable from './EventTable';
|
||||
|
||||
export default function EventMapView({ testResult }) {
|
||||
|
||||
const { estmodel } = useDeviceStore();
|
||||
const connectionStatus = testResult.ofpConnectionStatus;
|
||||
const { view } = useDisplayStore.getState().navigation.current;
|
||||
const currentCableId = useDisplayStore.getState().getCurrentCableId();
|
||||
@@ -12,7 +16,7 @@ export default function EventMapView({ testResult }) {
|
||||
const [eventData, setEventData] = useState({});
|
||||
const eventRefs = useRef({});
|
||||
const isMultiMode = testResult?.testconfig?.params?.cableType.includes('OM');
|
||||
|
||||
const tempTestResult = testResult;
|
||||
// 加载事件数据
|
||||
useEffect(() => {
|
||||
const loadTraceData = async () => {
|
||||
@@ -454,7 +458,7 @@ const renderEventComponent = useCallback((event, status) => {
|
||||
</div>
|
||||
|
||||
);
|
||||
};
|
||||
};
|
||||
//末导样式
|
||||
const EndRef = () => {
|
||||
return (
|
||||
@@ -477,8 +481,8 @@ const renderEventComponent = useCallback((event, status) => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
// 无光纤
|
||||
const EndNoFiber = () => {
|
||||
// 无光纤
|
||||
const EndNoFiber = () => {
|
||||
return (
|
||||
// <div className=" w-full h-[3px] bg-[#cc0000] top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-[1.5px] -rotate-45" />
|
||||
|
||||
@@ -490,9 +494,9 @@ const renderEventComponent = useCallback((event, status) => {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
};
|
||||
// 熔接点样式
|
||||
const SplicePoint = ({ status = 'normal' }) => {
|
||||
const SplicePoint = ({ status = 'normal' }) => {
|
||||
return (
|
||||
<div className={`w-4 h-4 rounded-full relative
|
||||
${status === 'fail' ? 'bg-gradient-to-r from-[#8b0000] to-[#cc0000]' :
|
||||
@@ -506,7 +510,7 @@ const renderEventComponent = useCallback((event, status) => {
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
};
|
||||
// 弯曲事件样式
|
||||
const BendEvent = () => {
|
||||
return (
|
||||
@@ -514,7 +518,7 @@ const renderEventComponent = useCallback((event, status) => {
|
||||
-mr-0.5 flex-shrink-0"
|
||||
style={{ clipPath: 'inset(0 50% 0 0)' }} />
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full h-full flex flex-row bg-[#f0f0f0]"> {/* Changed to flex-row and added background */}
|
||||
@@ -522,49 +526,218 @@ const renderEventComponent = useCallback((event, status) => {
|
||||
<div className="w-1/3 h-full flex flex-col">
|
||||
<div className="w-full h-[100%] bg-white p-2 flex items-end justify-center"> {/* 改为items-end使内容底部对齐 */}
|
||||
<div className="w-full h-[90%] bg-white p-2 flex flex-col items-center justify-end relative">
|
||||
{processedEvents.map(([key, event], index, array) => {
|
||||
const nextEvent = array[index + 1]?.[1];
|
||||
const prevEvent = array[index - 1]?.[1];
|
||||
const distance = nextEvent ?
|
||||
(event.distance - nextEvent.distance).toFixed(1) :
|
||||
(eventData.summary.totalDistance - event.distance).toFixed(1);
|
||||
const status = getEventStatus(event, nextEvent, prevEvent);
|
||||
{processedEvents.map(([key, event], index, array) => {
|
||||
const nextEvent = array[index + 1]?.[1];
|
||||
const prevEvent = array[index - 1]?.[1];
|
||||
const distance = nextEvent ?
|
||||
(event.distance - nextEvent.distance).toFixed(1) :
|
||||
(eventData.summary.totalDistance - event.distance).toFixed(1);
|
||||
const status = getEventStatus(event, nextEvent, prevEvent);
|
||||
|
||||
return (
|
||||
<div key={key} className="flex flex-col items-center">
|
||||
<div
|
||||
ref={el => eventRefs.current[key] = el}
|
||||
onClick={() => setSelectedEvent(event)}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
{renderEventComponent(event, status)}
|
||||
</div>
|
||||
return (
|
||||
<div key={key} className="flex flex-col items-center">
|
||||
<div
|
||||
ref={el => eventRefs.current[key] = el}
|
||||
onClick={() => setSelectedEvent(event)}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
{renderEventComponent(event, status)}
|
||||
</div>
|
||||
|
||||
{index < array.length - 1 && (
|
||||
<div className="flex items-center relative">
|
||||
<div className="absolute left-[-65px] text-sm text-black whitespace-nowrap">
|
||||
{distance} m
|
||||
</div>
|
||||
<div
|
||||
className={`w-[2px] ${nextEvent?.type === 'StartRef' || event.type === 'EndRef' ? 'bg-gray-400' : 'bg-black'}`}
|
||||
style={{ height: getConnectionLineHeight(array.length) }}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
<Image
|
||||
src={getAssetUrl('/otdr-start.png')}
|
||||
alt="OTDR Start"
|
||||
width={40}
|
||||
height={40}
|
||||
/>
|
||||
</div>
|
||||
{index < array.length - 1 && (
|
||||
<div className="flex items-center relative">
|
||||
<div className="absolute left-[-65px] text-sm text-black whitespace-nowrap">
|
||||
{distance} m
|
||||
</div>
|
||||
<div
|
||||
className={`w-[2px] ${nextEvent?.type === 'StartRef' || event.type === 'EndRef' ? 'bg-gray-400' : 'bg-black'}`}
|
||||
style={{ height: getConnectionLineHeight(array.length) }}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
<Image
|
||||
src={getAssetUrl('/otdr-start.png')}
|
||||
alt="OTDR Start"
|
||||
width={40}
|
||||
height={40}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right Area (2/3 width) */}
|
||||
{estmodel === 'general' ? (
|
||||
|
||||
<div className="w-2/3 h-full flex flex-col bg-[#F8F6F7]"> {/* Added right column */}
|
||||
<div className="h-[20%] bg-white p-3 flex flex-col">
|
||||
<div className="flex justify-between items-start">
|
||||
<div>
|
||||
<div className="flex items-center">
|
||||
<span className="text-black font-bold text-sm">光纤长度:</span>
|
||||
<span className="text-black ml-1 text-sm">{eventData?.summary?.totalDistance || '0'} m</span>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<span className="text-black font-bold text-sm">总体损耗:</span>
|
||||
<span className="text-black ml-1 text-sm">{eventData?.summary?.totalLoss || 'N/A'} dB</span>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<span className="text-black font-bold text-sm">光纤类型:</span>
|
||||
<span className="text-black ml-1 text-sm">{testResult?.testconfig?.params?.cableType || null}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className="flex flex-col items-start">
|
||||
|
||||
|
||||
|
||||
{view === 'nosave' && (
|
||||
<div className="flex items-center">
|
||||
<span className="text-black font-bold text-sm">下一个ID:</span>
|
||||
<span className="text-black ml-1 text-sm">{currentCableId?.name || 'OTDR-02'}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<span className="text-black font-bold text-sm">测试极限值: </span>
|
||||
<span className="text-black ml-1 text-sm">{testResult?.testconfig?.params?.limitValue || null}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right Middle (60%) */}
|
||||
<div className="h-[45%] bg-white p-2 relative"> {/* Adjusted padding */}
|
||||
{/* 事件简要框 */}
|
||||
{selectedEvent && (
|
||||
<div className="absolute p-4 rounded-lg shadow-lg bg-gradient-to-b from-gray-200 to-gray-300 border-2"
|
||||
style={{
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
width: '80%',
|
||||
maxWidth: '350px',
|
||||
zIndex: 10,
|
||||
borderColor: selectedEvent.type === 'StartRef' || selectedEvent.type === 'Start' ? '#1a9850' :
|
||||
selectedEvent.type === 'EndRef' || selectedEvent.type === 'End' ? '#1a365d' :
|
||||
selectedEvent.spliceLoss > 0.75 || selectedEvent.spliceLoss > 0.35 ? '#cc0000' : '#1a365d'
|
||||
}}
|
||||
>
|
||||
{/* 小尾巴 - 指向左侧事件 */}
|
||||
<div className="absolute w-0 h-0 border-solid"
|
||||
style={{
|
||||
left: '-20px',
|
||||
top: '50%',
|
||||
transform: 'translateY(-50%)',
|
||||
borderWidth: '10px 20px 10px 0',
|
||||
borderColor: 'transparent ' +
|
||||
(selectedEvent.type === 'StartRef' || selectedEvent.type === 'Start' ? '#1a9850' :
|
||||
selectedEvent.type === 'EndRef' || selectedEvent.type === 'End' ? '#1a365d' :
|
||||
selectedEvent.spliceLoss > 0.75 || selectedEvent.spliceLoss > 0.35 ? '#cc0000' : '#1a365d') +
|
||||
' transparent transparent'
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 标题 */}
|
||||
<div className="text-center font-bold text-xl mb-4">
|
||||
{selectedEvent.type === 'StartRef' ? 'OTDR端口' :
|
||||
selectedEvent.type === 'EndRef' ? '末尾事件' :
|
||||
selectedEvent.type === 'EndNoRef' ? '未找到末尾事件' :
|
||||
selectedEvent.type === 'Start' ? 'OTDR端口' :
|
||||
selectedEvent.type === 'End' ? '端点' :
|
||||
selectedEvent.type === 'Reflector' ? '反射器' :
|
||||
selectedEvent.type === 'Hidden' ? '隐藏事件' :
|
||||
selectedEvent.type === 'Splice' ? '熔接点' :
|
||||
selectedEvent.type === 'Bend' ? '弯曲事件' : '事件'}
|
||||
</div>
|
||||
|
||||
{/* 事件信息 */}
|
||||
<div className="mb-2">
|
||||
<div className="text-center mb-2">在{selectedEvent.distance.toFixed(2)} m</div>
|
||||
|
||||
{/* 根据事件类型显示不同信息 */}
|
||||
{(selectedEvent.type === 'Reflector' ||
|
||||
selectedEvent.type === 'Hidden' ||
|
||||
selectedEvent.type === 'EndRef') && (
|
||||
<div>
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
src={selectedEvent.spliceLoss > 0.75 ? getAssetUrl('/fail.png') : getAssetUrl('/pass.png')}
|
||||
alt="status"
|
||||
className="w-4 h-4 mr-2"
|
||||
/>
|
||||
<span className="font-bold">损耗:</span>
|
||||
</div>
|
||||
<span>{selectedEvent.spliceLoss ? selectedEvent.spliceLoss.toFixed(2) : '0'} dB</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<div className="flex items-center">
|
||||
<div className="w-4 h-4 mr-2"></div>
|
||||
<span className="font-bold">反射率:</span>
|
||||
</div>
|
||||
<span>{selectedEvent.reflLoss ? selectedEvent.reflLoss.toFixed(2) : '0'} dB</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{(selectedEvent.type === 'Splice' || selectedEvent.type === 'Bend') && (
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
src={selectedEvent.type === 'Splice' ?
|
||||
(selectedEvent.spliceLoss > 0.35 ? getAssetUrl('/fail.png') : getAssetUrl('/pass.png')) :
|
||||
(selectedEvent.spliceLoss > 0.75 ? getAssetUrl('/fail.png') : getAssetUrl('/pass.png'))}
|
||||
alt="status"
|
||||
className="w-4 h-4 mr-2"
|
||||
/>
|
||||
<span className="font-bold">损耗:</span>
|
||||
</div>
|
||||
<span>{selectedEvent.spliceLoss ? selectedEvent.spliceLoss.toFixed(2) : '0'} dB</span>
|
||||
</div>
|
||||
)}
|
||||
{(selectedEvent.type === 'StartRef' ||
|
||||
selectedEvent.type === 'Start' ||
|
||||
selectedEvent.type === 'End') && (
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<div className="flex items-center">
|
||||
<div className="w-4 h-4 mr-2"></div>
|
||||
<span className="font-bold">反射率:</span>
|
||||
</div>
|
||||
<span>{selectedEvent.reflLoss ? selectedEvent.reflLoss.toFixed(2) : '0'} dB</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 连接质量指示器 - 仅对某些事件类型显示 */}
|
||||
{(selectedEvent.type === 'Start' || selectedEvent.type === 'StartRef') && (
|
||||
<div className="mt-4">
|
||||
<div className="text-center mb-2">端口连接质量</div>
|
||||
<div className="relative h-4 bg-gray-200 rounded-full overflow-hidden">
|
||||
<div className="absolute top-0 left-0 h-full w-full flex">
|
||||
<div className="h-full bg-red-600" style={{width: '33%'}}></div>
|
||||
<div className="h-full bg-yellow-400" style={{width: '33%'}}></div>
|
||||
<div className="h-full bg-green-500" style={{width: '34%'}}></div>
|
||||
</div>
|
||||
<div className="absolute top-0 right-4 h-full flex items-center">
|
||||
<div className="w-3 h-3 bg-black transform rotate-45"></div>
|
||||
</div>
|
||||
<div className="absolute bottom-[-20px] right-4 text-xs">良好</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Right Bottom (20%) */}
|
||||
<div className="h-[35%] bg-white p-2 flex flex-col items-start justify-center"> {/* Adjusted padding and alignment */}
|
||||
<EventTable testResult={tempTestResult} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
):(
|
||||
<div className="w-2/3 h-full flex flex-col"> {/* Added right column */}
|
||||
{/* Right Top (20%) */}
|
||||
<div className="h-[20%] bg-white p-3 flex justify-between items-start ">
|
||||
@@ -714,6 +887,9 @@ const renderEventComponent = useCallback((event, status) => {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ export default function EventTable({ testResult }) {
|
||||
const [eventData, setEventData] = useState(null);
|
||||
const [currentWavelength, setCurrentWavelength] = useState(null);
|
||||
const [wavelengthData, setWavelengthData] = useState({});
|
||||
const { estmodel } = useDeviceStore();
|
||||
|
||||
// 判断是否为多模光纤
|
||||
const isMultiMode = testResult?.testconfig?.params?.cableType.includes('OM');
|
||||
@@ -374,76 +375,151 @@ export default function EventTable({ testResult }) {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full h-full flex flex-col bg-white p-4">
|
||||
{/* 表头 */}
|
||||
<div className="flex border-b border-gray-300 py-2 font-bold text-black">
|
||||
<div className="w-24 text-center">(m)</div>
|
||||
<div className="w-24 text-center">损耗</div>
|
||||
<div className="w-24 text-center">反射</div>
|
||||
<div className="flex-1 text-center">类型</div>
|
||||
<div className="w-16 text-center"></div>
|
||||
</div>
|
||||
estmodel === 'general' ? (
|
||||
<div className="w-full h-full flex flex-col bg-white">
|
||||
{/* 表头 */}
|
||||
<div className="flex border-b border-gray-300 font-bold text-black">
|
||||
<div className="w-[20%] text-center text-sm">(m)</div>
|
||||
<div className="w-[20%] text-center text-sm">损耗</div>
|
||||
<div className="w-[20%] text-center text-sm">反射</div>
|
||||
<div className="w-[30%] text-center text-sm">类型</div>
|
||||
<div className="w-[10%] text-center text-sm"></div>
|
||||
</div>
|
||||
|
||||
{/* 表格内容 */}
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
{eventData && Object.entries(eventData.events)
|
||||
.sort((a, b) => b[1].distance - a[1].distance)
|
||||
.map(([key, event]) => (
|
||||
<div key={key} className="flex items-center border-b border-gray-200 py-2">
|
||||
<div className="w-24 text-center text-black">
|
||||
{event.distance.toFixed(2)}
|
||||
</div>
|
||||
<div className="w-24 text-center text-black">
|
||||
{event.spliceLoss ? event.spliceLoss.toFixed(2) : 'N/A'}
|
||||
</div>
|
||||
<div className="w-24 text-center text-black">
|
||||
{event.reflLoss ? event.reflLoss.toFixed(2) : 'N/A'}
|
||||
</div>
|
||||
<div className="flex-1 text-center text-black">
|
||||
{getEventTypeName(event.type)}
|
||||
</div>
|
||||
<div className="w-16 flex justify-center">
|
||||
<div className="w-5 h-5 relative">
|
||||
<Image
|
||||
src={getAssetUrl(getEventStatusIcon(event))}
|
||||
alt="status"
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
{/* 表格内容 */}
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
{eventData && Object.entries(eventData.events)
|
||||
.sort((a, b) => b[1].distance - a[1].distance)
|
||||
.map(([key, event]) => (
|
||||
<div key={key} className="flex items-center border-b border-gray-200 ">
|
||||
<div className="w-[20%] text-center text-black text-sm">
|
||||
{event.distance.toFixed(2)}
|
||||
</div>
|
||||
<div className="w-[20%] text-center text-black text-sm">
|
||||
{event.spliceLoss ? event.spliceLoss.toFixed(2) : 'N/A'}
|
||||
</div>
|
||||
<div className="w-[20%] text-center text-black text-sm">
|
||||
{event.reflLoss ? event.reflLoss.toFixed(2) : 'N/A'}
|
||||
</div>
|
||||
<div className="w-[30%] text-center text-black text-sm">
|
||||
{getEventTypeName(event.type)}
|
||||
</div>
|
||||
<div className="w-[10%] flex justify-center text-sm">
|
||||
<div className="w-3 h-3 relative">
|
||||
<Image
|
||||
src={getAssetUrl(getEventStatusIcon(event))}
|
||||
alt="status"
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 底部控制区 */}
|
||||
<div className="h-[10%] flex items-center justify-center space-x-4">
|
||||
<button
|
||||
onClick={() => {
|
||||
const wavelengths = Object.keys(wavelengthData);
|
||||
const currentIndex = wavelengths.indexOf(currentWavelength);
|
||||
const prevWavelength = wavelengths[(currentIndex - 1 + wavelengths.length) % wavelengths.length];
|
||||
setCurrentWavelength(prevWavelength);
|
||||
setEventData(wavelengthData[prevWavelength]);
|
||||
}}
|
||||
className="p-2 rounded-full bg-gray-300 hover:bg-gray-400"
|
||||
>
|
||||
◀
|
||||
</button>
|
||||
<span className="text-lg font-semibold">{currentWavelength}nm</span>
|
||||
<button
|
||||
onClick={() => {
|
||||
const wavelengths = Object.keys(wavelengthData);
|
||||
const currentIndex = wavelengths.indexOf(currentWavelength);
|
||||
const nextWavelength = wavelengths[(currentIndex + 1) % wavelengths.length];
|
||||
setCurrentWavelength(nextWavelength);
|
||||
setEventData(wavelengthData[nextWavelength]);
|
||||
}}
|
||||
className="p-2 rounded-full bg-gray-300 hover:bg-gray-400"
|
||||
>
|
||||
▶
|
||||
</button>
|
||||
{/* 底部控制区 */}
|
||||
<div className="h-[10%] flex items-center justify-center space-x-4">
|
||||
<button
|
||||
onClick={() => {
|
||||
const wavelengths = Object.keys(wavelengthData);
|
||||
const currentIndex = wavelengths.indexOf(currentWavelength);
|
||||
const prevWavelength = wavelengths[(currentIndex - 1 + wavelengths.length) % wavelengths.length];
|
||||
setCurrentWavelength(prevWavelength);
|
||||
setEventData(wavelengthData[prevWavelength]);
|
||||
}}
|
||||
className="w-6 h-6 rounded-full bg-gray-300 hover:bg-gray-400 flex items-center justify-center text-xs"
|
||||
>
|
||||
◀
|
||||
</button>
|
||||
<span className="text-sm font-semibold">{currentWavelength}nm</span>
|
||||
<button
|
||||
onClick={() => {
|
||||
const wavelengths = Object.keys(wavelengthData);
|
||||
const currentIndex = wavelengths.indexOf(currentWavelength);
|
||||
const nextWavelength = wavelengths[(currentIndex + 1) % wavelengths.length];
|
||||
setCurrentWavelength(nextWavelength);
|
||||
setEventData(wavelengthData[nextWavelength]);
|
||||
}}
|
||||
className="w-6 h-6 rounded-full bg-gray-300 hover:bg-gray-400 flex items-center justify-center text-xs"
|
||||
>
|
||||
▶
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
):(
|
||||
<div className="w-full h-full flex flex-col bg-white p-4">
|
||||
{/* 表头 */}
|
||||
<div className="flex border-b border-gray-300 py-2 font-bold text-black">
|
||||
<div className="w-[20%] text-center">(m)</div>
|
||||
<div className="w-[20%] text-center">损耗</div>
|
||||
<div className="w-[20%] text-center">反射</div>
|
||||
<div className="w-[20%] text-center">类型</div>
|
||||
<div className="w-[20%] text-center"></div>
|
||||
</div>
|
||||
|
||||
{/* 表格内容 */}
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
{eventData && Object.entries(eventData.events)
|
||||
.sort((a, b) => b[1].distance - a[1].distance)
|
||||
.map(([key, event]) => (
|
||||
<div key={key} className="flex items-center border-b border-gray-200 py-2">
|
||||
<div className="w-[20%] text-center text-black">
|
||||
{event.distance.toFixed(2)}
|
||||
</div>
|
||||
<div className="w-[20%] text-center text-black">
|
||||
{event.spliceLoss ? event.spliceLoss.toFixed(2) : 'N/A'}
|
||||
</div>
|
||||
<div className="w-[20%] text-center text-black">
|
||||
{event.reflLoss ? event.reflLoss.toFixed(2) : 'N/A'}
|
||||
</div>
|
||||
<div className="w-[20%] text-center text-black">
|
||||
{getEventTypeName(event.type)}
|
||||
</div>
|
||||
<div className="w-[20%] flex justify-center">
|
||||
<div className="w-5 h-5 relative">
|
||||
<Image
|
||||
src={getAssetUrl(getEventStatusIcon(event))}
|
||||
alt="status"
|
||||
fill
|
||||
className="object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 底部控制区 */}
|
||||
<div className="h-[10%] flex items-center justify-center space-x-4">
|
||||
<button
|
||||
onClick={() => {
|
||||
const wavelengths = Object.keys(wavelengthData);
|
||||
const currentIndex = wavelengths.indexOf(currentWavelength);
|
||||
const prevWavelength = wavelengths[(currentIndex - 1 + wavelengths.length) % wavelengths.length];
|
||||
setCurrentWavelength(prevWavelength);
|
||||
setEventData(wavelengthData[prevWavelength]);
|
||||
}}
|
||||
className="p-2 rounded-full bg-gray-300 hover:bg-gray-400"
|
||||
>
|
||||
◀
|
||||
</button>
|
||||
<span className="text-lg font-semibold">{currentWavelength}nm</span>
|
||||
<button
|
||||
onClick={() => {
|
||||
const wavelengths = Object.keys(wavelengthData);
|
||||
const currentIndex = wavelengths.indexOf(currentWavelength);
|
||||
const nextWavelength = wavelengths[(currentIndex + 1) % wavelengths.length];
|
||||
setCurrentWavelength(nextWavelength);
|
||||
setEventData(wavelengthData[nextWavelength]);
|
||||
}}
|
||||
className="p-2 rounded-full bg-gray-300 hover:bg-gray-400"
|
||||
>
|
||||
▶
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
);
|
||||
}
|
||||
@@ -31,7 +31,9 @@ const FrequencyChart = ({
|
||||
limitdata,
|
||||
limitValue,
|
||||
HDTD,
|
||||
CopperResultStatus,
|
||||
curtitle,
|
||||
displayTitle,
|
||||
wireOrder // 添加 wireOrder 参数
|
||||
}) => {
|
||||
const chartRef = useRef(null);
|
||||
@@ -407,7 +409,7 @@ const FrequencyChart = ({
|
||||
return (
|
||||
<div className="flex justify-between p-2 w-full">
|
||||
<div className="space-y-2">
|
||||
<div className="font-bold">{curtitle} : {mouseInfo.values.worstValue} dB </div>
|
||||
<div className="font-bold">{displayTitle || curtitle} : {mouseInfo.values.worstValue} dB </div>
|
||||
<div className="font-bold">余量 : {mouseInfo.values.margin} dB</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -415,7 +417,7 @@ const FrequencyChart = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full flex flex-col"> {/* 移除h-full */}
|
||||
<div className="w-full flex flex-col">
|
||||
{renderChart()}
|
||||
{renderParameters()}
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import React from 'react';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
|
||||
|
||||
export default function OLTSResultMain({ testResult }) {
|
||||
const { estmodel } = useDeviceStore();
|
||||
const { getCurrentTestConfig } = useDisplayStore.getState();
|
||||
const { view } = useDisplayStore.getState().navigation.current;
|
||||
const currentConfig = getCurrentTestConfig();
|
||||
@@ -44,79 +47,173 @@ export default function OLTSResultMain({ testResult }) {
|
||||
};
|
||||
|
||||
return (
|
||||
estmodel === 'general' ? (
|
||||
<div className="w-full h-[490px] flex flex-col overflow-hidden">
|
||||
{/* 背景图片层 */}
|
||||
|
||||
<div className="w-full h-full relative">
|
||||
{/* 背景图片层 */}
|
||||
<div
|
||||
className="absolute inset-0 bg-cover bg-center bg-no-repeat"
|
||||
style={{ backgroundImage: `url(${getAssetUrl(getBackgroundImage())})` }}
|
||||
/>
|
||||
{/* 测试结果显示 */}
|
||||
<div className="absolute inset-0 flex items-center justify-center pb-24">
|
||||
<div className="flex flex-row gap-30 ">
|
||||
<div className={`w-40 bg-[#F8F6F7] p-2 rounded-lg border-2 ${testResult.isLossValidOut ? 'border-[#00A65A]' : 'border-[#ce1d31]'}`}>
|
||||
<div className="flex flex-col gap-0">
|
||||
{/* 损耗显示 */}
|
||||
{view !== 'nosave' ? (
|
||||
<div className="text-black pb-3 font-bold whitespace-nowrap overflow-hidden text-ellipsis">{testResult.inputname}</div>
|
||||
) : (
|
||||
<div className="text-black pb-3 font-bold">未保存的结果</div>
|
||||
)}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidOut ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">{`λ${isMultiMode ? '850' : '1310'}`}:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainOut.wavelength1.loss}dB</div>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidOut ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">{`λ${isMultiMode ? '1300' : '1550'}`}:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainOut.wavelength2.loss}dB</div>
|
||||
</div>
|
||||
|
||||
{/* 数据显示层 */}
|
||||
<div className="absolute inset-0 flex items-center justify-center pl-66 pb-24">
|
||||
<div className="flex flex-col gap-6 ">
|
||||
{/* 上方数据显示框 */}
|
||||
<div className="bg-gradient-to-b w-48 from-[#e6e3e6] to-[#7b797b] p-2 rounded-lg">
|
||||
<div className="flex flex-col gap-0">
|
||||
{/* 损耗显示 */}
|
||||
{view !== 'nosave' ? (
|
||||
<div className="text-black pb-3 font-bold whitespace-nowrap overflow-hidden text-ellipsis">{testResult.inputname}</div>
|
||||
) : (
|
||||
<div className="text-black pb-3 font-bold">未保存的结果</div>
|
||||
)}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidOut ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">损耗:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainOut.wavelength1.loss}dB</div>
|
||||
{/* 长度显示 */}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLengthValidOut ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">长度:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainOut.wavelength1.distance}m</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 长度显示 */}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLengthValidOut ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">长度:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainOut.wavelength1.distance}m</div>
|
||||
<div className={`w-40 bg-[#F8F6F7] p-2 rounded-lg border-2 ${testResult.isLossValidIn ? 'border-[#00A65A]' : 'border-[#ce1d31]'}`}>
|
||||
<div className="flex flex-col gap-0">
|
||||
{/* 损耗显示 */}
|
||||
{view !== 'nosave' ? (
|
||||
<div className="text-black pb-3 font-bold whitespace-nowrap overflow-hidden text-ellipsis">{testResult.outname}</div>
|
||||
) : (
|
||||
<div className="text-black pb-3 font-bold">未保存的结果</div>
|
||||
)}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidIn ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">{`λ${isMultiMode ? '850' : '1310'}`}:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainIn.wavelength1.loss}dB</div>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidIn ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">{`λ${isMultiMode ? '1300' : '1550'}`}:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainIn.wavelength2.loss}dB</div>
|
||||
</div>
|
||||
|
||||
{/* 长度显示 */}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLengthValidIn ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">长度:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainIn.wavelength1.distance}m</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 下方数据显示框 */}
|
||||
<div className="bg-gradient-to-b w-48 from-[#e6e3e6] to-[#7b797b] p-2 rounded-lg">
|
||||
<div className="flex flex-col gap-0">
|
||||
{/* 损耗显示 */}
|
||||
{view !== 'nosave' ? (
|
||||
<div className="text-black pb-3 font-bold whitespace-nowrap overflow-hidden text-ellipsis">{testResult.outname}</div>
|
||||
) : (
|
||||
<div className="text-black pb-3 font-bold">未保存的结果</div>
|
||||
)}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidIn ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">损耗:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainIn.wavelength1.loss}dB</div>
|
||||
</div>
|
||||
|
||||
{/* 长度显示 */}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLengthValidIn ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">长度:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainIn.wavelength1.distance}m</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
):(
|
||||
<div className="w-full h-[490px] flex flex-col overflow-hidden">
|
||||
|
||||
<div className="w-full h-full relative">
|
||||
{/* 背景图片层 */}
|
||||
<div
|
||||
className="absolute inset-0 bg-cover bg-center bg-no-repeat"
|
||||
style={{ backgroundImage: `url(${getAssetUrl(getBackgroundImage())})` }}
|
||||
/>
|
||||
{/* 测试结果显示 */}
|
||||
<div className="absolute inset-0 flex items-center justify-center pl-66 pb-24">
|
||||
<div className="flex flex-col gap-6 ">
|
||||
{/* 上方数据显示框 */}
|
||||
<div className="bg-gradient-to-b w-48 from-[#e6e3e6] to-[#7b797b] p-2 rounded-lg">
|
||||
<div className="flex flex-col gap-0">
|
||||
{/* 损耗显示 */}
|
||||
{view !== 'nosave' ? (
|
||||
<div className="text-black pb-3 font-bold whitespace-nowrap overflow-hidden text-ellipsis">{testResult.inputname}</div>
|
||||
) : (
|
||||
<div className="text-black pb-3 font-bold">未保存的结果</div>
|
||||
)}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidOut ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">损耗:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainOut.wavelength1.loss}dB</div>
|
||||
</div>
|
||||
|
||||
{/* 长度显示 */}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLengthValidOut ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">长度:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainOut.wavelength1.distance}m</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 下方数据显示框 */}
|
||||
<div className="bg-gradient-to-b w-48 from-[#e6e3e6] to-[#7b797b] p-2 rounded-lg">
|
||||
<div className="flex flex-col gap-0">
|
||||
{/* 损耗显示 */}
|
||||
{view !== 'nosave' ? (
|
||||
<div className="text-black pb-3 font-bold whitespace-nowrap overflow-hidden text-ellipsis">{testResult.outname}</div>
|
||||
) : (
|
||||
<div className="text-black pb-3 font-bold">未保存的结果</div>
|
||||
)}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLossValidIn ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">损耗:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainIn.wavelength1.loss}dB</div>
|
||||
</div>
|
||||
|
||||
{/* 长度显示 */}
|
||||
<div className="flex items-center">
|
||||
{testResult.isLengthValidIn ? (<img src={getAssetUrl('/pass.png')} alt="Pass" className="w-6 h-6" />
|
||||
) : (
|
||||
<img src={getAssetUrl('/fail.png')} alt="Fail" className="w-6 h-6" />
|
||||
)}
|
||||
<div className="text-black font-bold ml-2">长度:</div>
|
||||
<div className="text-black ml-auto">{testResult.CFPMainIn.wavelength1.distance}m</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
);
|
||||
}
|
||||
@@ -4,11 +4,14 @@ import EventTable from './EventTable';
|
||||
import CurveChart from './CurveChart';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
|
||||
|
||||
export default function OTDRResultMain({ testResult }) {
|
||||
const [activeTab, setActiveTab] = useState('EventMap');
|
||||
const tabs = ['EventMap', '表', '曲线'];
|
||||
const tempTestResult = testResult;
|
||||
|
||||
const { estmodel } = useDeviceStore();
|
||||
const [activeTab, setActiveTab] = useState('EventMap');
|
||||
|
||||
const tabs = estmodel === 'general' ? ['EventMap', '曲线'] : ['EventMap', '表', '曲线'];
|
||||
const tempTestResult = testResult;
|
||||
|
||||
const renderContent = () => {
|
||||
switch (activeTab) {
|
||||
@@ -48,7 +51,7 @@ export default function OTDRResultMain({ testResult }) {
|
||||
? 'bg-gradient-to-b from-[#d5dfeb] via-[#f8f6f7] to-[#d5dfeb] text-black'
|
||||
: 'bg-[#132843] text-[#fffe92]'}`}
|
||||
>
|
||||
{tab}
|
||||
{estmodel === 'general' && tab === 'EventMap' ? '链路图' : tab}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -49,6 +49,8 @@ export default function PerformanceView({ testResult }) {
|
||||
}
|
||||
|
||||
let minMargin = Infinity;
|
||||
let worstIndex = null;
|
||||
const frequencies = testResult?.resultdata?.performance?.data?.frequencies || [];
|
||||
const data = testResult.resultdata.performance.data[dataGroup];
|
||||
const limitValues = limitdata[dataGroup]?.['PAIRLimit (dB)'] || [];
|
||||
|
||||
@@ -72,12 +74,21 @@ export default function PerformanceView({ testResult }) {
|
||||
const margin = paramTitle === '插入损耗' ?
|
||||
Math.abs(limitValue) - Math.abs(actualValue) : // 插入损耗:极限值 - 参数值
|
||||
Math.abs(actualValue) - limitValue; // 其他参数:参数值 - 极限值
|
||||
minMargin = Math.min(minMargin, margin);
|
||||
if (margin < minMargin) {
|
||||
minMargin = margin;
|
||||
worstIndex = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return minMargin !== Infinity ? minMargin.toFixed(1) : null;
|
||||
if (minMargin === Infinity) return null;
|
||||
const freqVal = Number(frequencies?.[worstIndex]);
|
||||
return {
|
||||
value: minMargin.toFixed(1),
|
||||
index: worstIndex,
|
||||
freq: Number.isFinite(freqVal) ? Math.round(freqVal) : undefined
|
||||
};
|
||||
};
|
||||
|
||||
// 计算长度余量和状态
|
||||
@@ -234,8 +245,8 @@ export default function PerformanceView({ testResult }) {
|
||||
const lengthStatus = calculateLengthStatus();
|
||||
isPass = lengthStatus.isPass;
|
||||
} else {
|
||||
// 其他参数保持原有逻辑
|
||||
isPass = parseFloat(value) >= 0;
|
||||
const numeric = typeof value === 'object' && value !== null ? parseFloat(value.value) : parseFloat(value);
|
||||
isPass = numeric >= 0;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -273,27 +284,96 @@ export default function PerformanceView({ testResult }) {
|
||||
}
|
||||
};
|
||||
|
||||
const renderRow = (title, value, unit = '') => (
|
||||
const getDisplayTitle = (key) => {
|
||||
const map = {
|
||||
'长度': '长度',
|
||||
'电阻': '电阻',
|
||||
'插入损耗': '插入损耗',
|
||||
'回波损耗': '回波损耗',
|
||||
'NEXT': '近端串音',
|
||||
'PS NEXT': '近端串音功率和',
|
||||
'ACR-N': '衰减近端串音比',
|
||||
'PS ACR-N': '衰减近端串音比功率和',
|
||||
'ACR-F': '衰减远端串音比',
|
||||
'PS ACR-F': '衰减远端串音比功率和',
|
||||
'CDNEXT': '共模转差模近端串音',
|
||||
'CMRL': '共模回波损耗',
|
||||
'TCL': '横向转换损耗',
|
||||
'ELTCTL': '两端等效横向转换损耗'
|
||||
};
|
||||
return map[key] || key;
|
||||
};
|
||||
|
||||
const renderRow = (key, value, unit = '') => (
|
||||
estmodel === 'general' ? (
|
||||
<div
|
||||
className="w-full flex items-center justify-between p-3 mb-2 rounded-md bg-[#F8F6F7] shadow-md cursor-pointer"
|
||||
onClick={() => handleRowClick(title)}
|
||||
onClick={() => handleRowClick(key)}
|
||||
>
|
||||
<span className="text-lg font-medium text-black">{title}</span>
|
||||
<div className="flex items-center">
|
||||
<span className="text-lg text-black">{title === '电阻' ? '' : (value ? `(${value}${unit})` : '')}</span>
|
||||
{getStatusIcon(value, title)}
|
||||
<span className="text-lg font-medium text-black min-w-[220px]">{getDisplayTitle(key)}</span>
|
||||
<div className="grid grid-cols-3 gap-3 items-center ">
|
||||
|
||||
<span className="text-lg text-black text-right">
|
||||
|
||||
{(() => {
|
||||
if (key === '长度') {
|
||||
// 长度显示原始value
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
return `${value.value}${unit}`; // 若长度返回对象,取value字段
|
||||
}
|
||||
return `${value}${unit}`;
|
||||
}
|
||||
if (key === '电阻' || key === '长度') return '';
|
||||
if (!value) return '';
|
||||
const unitText = (unit || '').trim();
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
return `${value.value}${unitText}`;
|
||||
}
|
||||
return `${value}${unitText}`;
|
||||
})()}
|
||||
</span>
|
||||
<span className="text-lg text-black text-right">
|
||||
{(() => {
|
||||
if (key === '电阻' || key === '长度') return '';
|
||||
if (!value) return '';
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
const freq = value.freq !== undefined ? value.freq : (Number.isFinite(value.index) ? value.index : undefined);
|
||||
return freq !== undefined ? `@${freq}MHz` : '';
|
||||
}
|
||||
return '';
|
||||
})()}
|
||||
</span>
|
||||
<div className="flex justify-end">
|
||||
{getStatusIcon(value, key)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
):(
|
||||
<div
|
||||
className="w-full flex items-center justify-between p-3 mb-2 rounded-md bg-gradient-to-b from-[#dedede] via-[#b5b5b5] to-[#8b898b] shadow-md cursor-pointer"
|
||||
onClick={() => handleRowClick(title)}
|
||||
onClick={() => handleRowClick(key)}
|
||||
>
|
||||
<span className="text-lg font-medium text-black">{title}</span>
|
||||
<span className="text-lg font-medium text-black">{key}</span>
|
||||
<div className="flex items-center">
|
||||
<span className="text-lg text-black">{title === '电阻' ? '' : (value ? `(${value}${unit})` : '')}</span>
|
||||
{getStatusIcon(value, title)}
|
||||
<span className="text-lg text-black">
|
||||
{(() => { if (key === '电阻') return '';
|
||||
if (!value) return '';
|
||||
if (key === '长度') {
|
||||
// 长度显示原始value
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
return `(${value.value}${unit})`; // 若长度返回对象,取value字段
|
||||
}
|
||||
return `(${value}${unit})`;
|
||||
}
|
||||
// 其他参数显示对象的value
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
return `(${value.value}${unit})`;
|
||||
}
|
||||
return `(${value}${unit})`;
|
||||
})()}
|
||||
|
||||
</span>
|
||||
{getStatusIcon(value, key)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -2,27 +2,42 @@ import React from 'react';
|
||||
import Image from 'next/image';
|
||||
import useDisplayStore from '@/store/displayStore';
|
||||
import { getAssetUrl } from '@/utils/asset';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
|
||||
export default function ResultTitleBar({ title, backTo, view, onBack, testResult, result }) {
|
||||
const { navigateTo, goBack, updateCurrentView, navigation } = useDisplayStore();
|
||||
|
||||
const { estmodel } = useDeviceStore();
|
||||
|
||||
// 根据结果获取背景颜色
|
||||
const getBgColor = () => {
|
||||
// 如果存在CopperWiremapResultStatus,使用铜缆测试逻辑
|
||||
if (estmodel === 'general') {
|
||||
if (testResult?.CopperResultStatus) {
|
||||
return testResult.CopperResultStatus === 'pass'
|
||||
? 'bg-gradient-to-r from-[#003366] to-[#00A65A]'
|
||||
: 'bg-gradient-to-r from-[#003366] to-[#ce1d31]';
|
||||
}
|
||||
if (testResult?.CFPResultStatus) {
|
||||
return testResult.CFPResultStatus === 'pass'
|
||||
? 'bg-gradient-to-r from-[#003366] to-[#00A65A]'
|
||||
: 'bg-gradient-to-r from-[#003366] to-[#ce1d31]';
|
||||
}
|
||||
if (testResult?.ofpResultStatus) {
|
||||
return testResult.ofpResultStatus === 'pass'
|
||||
? 'bg-gradient-to-r from-[#003366] to-[#00A65A]'
|
||||
: 'bg-gradient-to-r from-[#003366] to-[#ce1d31]';
|
||||
}
|
||||
return 'bg-[#003366]';
|
||||
}
|
||||
if (testResult?.CopperResultStatus) {
|
||||
if (testResult.CopperResultStatus !== 'pass') return 'bg-[#ce1d31]';
|
||||
return testResult.CopperResultStatus === 'pass' ? 'bg-[#00A65A]' : 'bg-[#ce1d31]';
|
||||
}
|
||||
// 如果存在OFPStatus,使用光纤测试逻辑
|
||||
if (testResult?.CFPResultStatus) {
|
||||
return testResult.CFPResultStatus === 'pass' ? 'bg-[#00A65A]' : 'bg-[#ce1d31]';
|
||||
}
|
||||
// 如果存在OFPStatus,使用光纤测试逻辑
|
||||
if (testResult?.ofpResultStatus) {
|
||||
return testResult.ofpResultStatus === 'pass' ? 'bg-[#00A65A]' : 'bg-[#ce1d31]';
|
||||
}
|
||||
// 默认蓝色
|
||||
return 'bg-[#003366]';
|
||||
};
|
||||
|
||||
|
||||
@@ -409,7 +409,7 @@ const CopperAnalyzer = () => {
|
||||
className="w-full p-2 border rounded text-xs bg-[#1E293B] text-[#0ff] border-[#0ff]/30 focus:border-[#0ff] focus:outline-none"
|
||||
>
|
||||
{/* <option value="coaxial">同轴线</option> */}
|
||||
<option value="twisted_single">双绞线(单对)</option>
|
||||
{/* <option value="twisted_single">双绞线(单对)</option> */}
|
||||
<option value="twisted_dual">双绞线(两对)</option>
|
||||
{/* <option value="fiber">光纤</option> */}
|
||||
</select>
|
||||
@@ -511,7 +511,7 @@ const CopperAnalyzer = () => {
|
||||
{params.cableType === 'twisted_dual' && (
|
||||
<div>
|
||||
<label className="block text-xs font-semibold text-[#0ff] mb-1">
|
||||
节距比例:
|
||||
线对节距:
|
||||
<span className="block text-[#0ff] font-bold">{params.pair2TwistRatio.toFixed(2)}×</span>
|
||||
</label>
|
||||
<input
|
||||
|
||||
@@ -15,6 +15,7 @@ export default function AdminPage() {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
const [currentScene, setCurrentScene] = useState('WorldSkill');
|
||||
const [availableScenes, setAvailableScenes] = useState(['Office', 'Industry', 'WorldSkill']);
|
||||
const [showModal, setShowModal] = useState(false);
|
||||
const [showhistoryModal, setShowhistoryModal] = useState(false);
|
||||
const [uuid, setUuid] = useState(null);
|
||||
@@ -22,6 +23,24 @@ export default function AdminPage() {
|
||||
const [confirmDialogMessage, setConfirmDialogMessage] = useState('');
|
||||
const [confirmDialogCallback, setConfirmDialogCallback] = useState(null);
|
||||
|
||||
// 场景标签映射
|
||||
const sceneLabels = { Office: '办公场景', Industry: '工业场景', WorldSkill: '竞赛模式' };
|
||||
const buildScenesFromModel = (model) => {
|
||||
if (!model) return ['Office', 'Industry', 'WorldSkill'];
|
||||
const m = model.match(/EST-(\d+)([A-Za-z]*)/i);
|
||||
const num = m?.[1] || '';
|
||||
const letter = (m?.[2] || '').toUpperCase();
|
||||
const scenes = [];
|
||||
if (num === '05') {
|
||||
scenes.push('Office');
|
||||
} else if (num === '10' || num === '100') {
|
||||
scenes.push('Office', 'Industry');
|
||||
}
|
||||
if (letter.includes('C')) {
|
||||
scenes.push('WorldSkill');
|
||||
}
|
||||
return [...new Set(scenes.length ? scenes : ['Office'])];
|
||||
};
|
||||
// 检查比赛状态
|
||||
const checkCompetitionStatus = async () => {
|
||||
try {
|
||||
@@ -45,6 +64,7 @@ export default function AdminPage() {
|
||||
const currentUrl = window.location.href;
|
||||
const urlParams = new URLSearchParams(currentUrl.split('?')[1] || '');
|
||||
const token = urlParams.get('token');
|
||||
const model = urlParams.get('model');
|
||||
if (!token) {
|
||||
router.push('/');
|
||||
return;
|
||||
@@ -57,6 +77,9 @@ export default function AdminPage() {
|
||||
const data = await response.json();
|
||||
if (data.isAdmin) {
|
||||
setIsAdmin(true);
|
||||
const scenes = buildScenesFromModel(model);
|
||||
setAvailableScenes(scenes);
|
||||
setCurrentScene((prev) => (scenes.includes(prev) ? prev : scenes[0]));
|
||||
// 通过鉴权后再触发后续初始化逻辑
|
||||
checkCompetitionStatus();
|
||||
fetchConnectionMap();
|
||||
@@ -70,7 +93,7 @@ export default function AdminPage() {
|
||||
}
|
||||
};
|
||||
verifyAdmin();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
|
||||
}, []);
|
||||
|
||||
// 从API获取连接配置
|
||||
@@ -407,9 +430,9 @@ export default function AdminPage() {
|
||||
onChange={(e) => setCurrentScene(e.target.value)}
|
||||
className="px-4 py-2 bg-[#1F2937] text-[#0ff] rounded-lg border border-[#0ff]/20"
|
||||
>
|
||||
<option value="Office">办公场景</option>
|
||||
<option value="Industry">工业场景</option>
|
||||
<option value="WorldSkill">竞赛模式</option>
|
||||
{availableScenes.map((s) => (
|
||||
<option key={s} value={s}>{sceneLabels[s]}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -429,9 +429,10 @@ function classNames(...classes) {
|
||||
play('uninstall');
|
||||
};
|
||||
|
||||
// 检查是否安装了OTDR模块(用于控制远端区域的显示)
|
||||
// 检查是否安装了特殊模块(用于控制远端区域的显示)
|
||||
const hasOtdrModule = mainUnitModules.some(m => m.id === 'ofp');
|
||||
const hasWiFiModule = installedDevices.main && installedDevices.main.id === 'wifi';
|
||||
const hasBenchmarkModule = useDeviceStore.getState().hasBenchmarkModule;
|
||||
//鼠标元素穿透检测显示到鼠标元素穿透检测显示到StatusToast
|
||||
const [portTooltip, setPortTooltip] = useState('');
|
||||
|
||||
@@ -511,14 +512,16 @@ function classNames(...classes) {
|
||||
<>
|
||||
|
||||
{/* 开发环境切换型号按钮 */}
|
||||
{/* <div className="fixed bottom-4 right-4 z-50">
|
||||
<button
|
||||
onClick={() => updateEstmodel(estmodel === 'fluke' ? 'general' : 'fluke')}
|
||||
className="px-3 py-2 text-sm rounded bg-blue-600 text-white hover:bg-blue-700"
|
||||
>
|
||||
切换型号:{estmodel}
|
||||
</button>
|
||||
</div> */}
|
||||
|
||||
{/* <div className="fixed bottom-4 right-4 z-50">
|
||||
<button
|
||||
onClick={() => updateEstmodel(estmodel === 'fluke' ? 'general' : 'fluke')}
|
||||
className="px-3 py-2 text-sm rounded bg-blue-600 text-white hover:bg-blue-700"
|
||||
>
|
||||
切换型号:{estmodel}
|
||||
</button>
|
||||
</div> */}
|
||||
|
||||
|
||||
<style>{scrollbarStyles}</style>
|
||||
{/* 比赛ID */}
|
||||
@@ -1185,6 +1188,25 @@ function classNames(...classes) {
|
||||
|
||||
{/* 主机和远端区域 */}
|
||||
<div className="h-[45%] flex-1 flex gap-4">
|
||||
{hasBenchmarkModule ? (
|
||||
<div
|
||||
className="w-full bg-[#0F172A] shadow-lg p-4 border border-[#0ff]/20 rounded-lg flex flex-col items-center justify-center relative"
|
||||
onContextMenu={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleContextMenu(e, 'benchmark');
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src={getAssetUrl('/benchmark-copperanalyer.png')}
|
||||
alt="基准参考"
|
||||
sizes={"auto"}
|
||||
fill
|
||||
className="object-contain p-10"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{/* 主机区域 */}
|
||||
<div className="w-[calc(50%-0.5rem)] bg-[#0F172A] shadow-lg p-4 border border-[#0ff]/20 rounded-lg">
|
||||
<div
|
||||
@@ -1420,6 +1442,8 @@ function classNames(...classes) {
|
||||
) : (
|
||||
<div className="w-[calc(50%-0.5rem)]"></div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1560,6 +1584,20 @@ function classNames(...classes) {
|
||||
y={contextMenu.y}
|
||||
onClose={() => setContextMenu(null)}
|
||||
items={[
|
||||
...(contextMenu.target === 'benchmark' ? [
|
||||
{
|
||||
label: '卸载传输线基准模块',
|
||||
onClick: () => {
|
||||
if (mainUnitModules.some(m => m.id === 'benchmark-copper')) {
|
||||
handleUninstall('benchmark-copper', 'main');
|
||||
}
|
||||
if (remoteUnitModules.some(m => m.id === 'benchmark-copper')) {
|
||||
handleUninstall('benchmark-copper', 'remote');
|
||||
}
|
||||
setContextMenu(null);
|
||||
}
|
||||
}
|
||||
] : []),
|
||||
...(contextMenu.target === 'connection' && contextMenu.item ? [
|
||||
{
|
||||
label: '移除物品',
|
||||
|
||||
@@ -241,18 +241,17 @@ devtools(
|
||||
portType: 'copper',
|
||||
image: '/CAL-4P.png',
|
||||
description: '插座测试夹具4芯'
|
||||
}
|
||||
],
|
||||
'基准': [
|
||||
},
|
||||
{
|
||||
id: 'pachcode-copper',
|
||||
id: 'benchmark-copper',
|
||||
name: '基准连接器',
|
||||
type: 'cable',
|
||||
type: 'module',
|
||||
portType: 'cal-copper-out',
|
||||
image: '/benchmark.png',
|
||||
description: '基准连接'
|
||||
},
|
||||
],
|
||||
|
||||
},
|
||||
|
||||
|
||||
@@ -295,6 +294,8 @@ devtools(
|
||||
// 连接状态分析结果
|
||||
connectionStatus: [],
|
||||
|
||||
// 传输线基准状态
|
||||
hasBenchmarkModule: false,
|
||||
// 线缆参数
|
||||
cableParams: {
|
||||
conductorMaterial: 'copper',
|
||||
@@ -346,10 +347,12 @@ devtools(
|
||||
updates.mainUnitAdapter = null;
|
||||
updates.mainUnitFixture = null;
|
||||
updates.mainUnitPorts = [];
|
||||
updates.hasBenchmarkModule = false;
|
||||
} else {
|
||||
updates.remoteUnitModules = [];
|
||||
updates.remoteUnitAdapter = null;
|
||||
updates.remoteUnitPorts = [];
|
||||
updates.hasBenchmarkModule = false;
|
||||
}
|
||||
|
||||
return updates;
|
||||
@@ -388,9 +391,12 @@ devtools(
|
||||
];
|
||||
}
|
||||
|
||||
const newMainModules = [...state.mainUnitModules, module];
|
||||
const newRemoteModules = state.remoteUnitModules;
|
||||
return {
|
||||
mainUnitModules: [...state.mainUnitModules, module],
|
||||
mainUnitPorts: ports
|
||||
mainUnitModules: newMainModules,
|
||||
mainUnitPorts: ports,
|
||||
hasBenchmarkModule: newMainModules.some(m => m.id === 'benchmark-copper') && newRemoteModules.some(m => m.id === 'benchmark-copper')
|
||||
};
|
||||
} else {
|
||||
let ports = [];
|
||||
@@ -415,9 +421,12 @@ devtools(
|
||||
];
|
||||
}
|
||||
|
||||
const newRemoteModules = [...state.remoteUnitModules, module];
|
||||
const newMainModules = state.mainUnitModules;
|
||||
return {
|
||||
remoteUnitModules: [...state.remoteUnitModules, module],
|
||||
remoteUnitPorts: ports
|
||||
remoteUnitModules: newRemoteModules,
|
||||
remoteUnitPorts: ports,
|
||||
hasBenchmarkModule: newMainModules.some(m => m.id === 'benchmark-copper') && newRemoteModules.some(m => m.id === 'benchmark-copper')
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -427,16 +436,22 @@ devtools(
|
||||
uninstallModule: (moduleId, target) => {
|
||||
set((state) => {
|
||||
if (target === 'main') {
|
||||
const newMainModules = state.mainUnitModules.filter(m => m.id !== moduleId);
|
||||
const newRemoteModules = state.remoteUnitModules;
|
||||
return {
|
||||
mainUnitModules: state.mainUnitModules.filter(m => m.id !== moduleId),
|
||||
mainUnitModules: newMainModules,
|
||||
mainUnitPorts: [],
|
||||
mainUnitAdapter: null
|
||||
mainUnitAdapter: null,
|
||||
hasBenchmarkModule: newMainModules.some(m => m.id === 'benchmark-copper') && newRemoteModules.some(m => m.id === 'benchmark-copper')
|
||||
};
|
||||
} else {
|
||||
const newRemoteModules = state.remoteUnitModules.filter(m => m.id !== moduleId);
|
||||
const newMainModules = state.mainUnitModules;
|
||||
return {
|
||||
remoteUnitModules: state.remoteUnitModules.filter(m => m.id !== moduleId),
|
||||
remoteUnitModules: newRemoteModules,
|
||||
remoteUnitPorts: [],
|
||||
remoteUnitAdapter: null
|
||||
remoteUnitAdapter: null,
|
||||
hasBenchmarkModule: newMainModules.some(m => m.id === 'benchmark-copper') && newRemoteModules.some(m => m.id === 'benchmark-copper')
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -564,6 +579,11 @@ devtools(
|
||||
setTotalToastMessage: (message) => set({ totalToastMessage: message }),
|
||||
|
||||
// ---***线缆参数管理***---
|
||||
// 更新传输线基准状态
|
||||
updateHasBenchmarkModule: (status) =>
|
||||
set(() => ({
|
||||
hasBenchmarkModule: status
|
||||
})),
|
||||
|
||||
// 更新线缆参数
|
||||
updateCableParams: (params) =>
|
||||
@@ -630,6 +650,8 @@ devtools(
|
||||
connectionStatus: [],
|
||||
// 报告数据
|
||||
reports: [],
|
||||
// 传输线基准状态
|
||||
hasBenchmarkModule: false,
|
||||
// 线缆参数
|
||||
cableParams: {
|
||||
conductorMaterial: 'copper',
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { create } from 'zustand';
|
||||
import { devtools } from 'zustand/middleware';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import useDeviceStore from '@/store/deviceStore';
|
||||
|
||||
|
||||
// 默认项目配置
|
||||
const defaultProject = {
|
||||
// 默认项目配置(根据设备模型动态设置)
|
||||
const createDefaultProject = (estmodel) => ({
|
||||
id: 'default',
|
||||
name: 'DEFAULT',
|
||||
testResults: [],
|
||||
@@ -15,7 +16,7 @@ const defaultProject = {
|
||||
moduleType: '8000',
|
||||
modulelable: '铜缆测试仪',
|
||||
params: {
|
||||
limitValue: 'TIA Cat 6 Channel',
|
||||
limitValue: estmodel === 'general' ? 'GBT 50312-2016 Cat 6 Ch' : 'TIA Cat 6 Channel',
|
||||
cableType: 'Cat6 U/UTP',
|
||||
wireOrder: 'T568B'
|
||||
}
|
||||
@@ -25,7 +26,7 @@ const defaultProject = {
|
||||
moduleType: 'cfp',
|
||||
modulelable: '光损耗测试仪',
|
||||
params: {
|
||||
limitValue: 'TIA-568.3-E Multimode (STD)',
|
||||
limitValue: estmodel === 'general' ? 'GB/T 50312-2016 Fiber Link' : 'TIA-568.3-E Multimode (STD)',
|
||||
cableType: 'OM3 Multimode 50',
|
||||
refJumper: '1',
|
||||
spliceCount: '0',
|
||||
@@ -37,7 +38,7 @@ const defaultProject = {
|
||||
moduleType: 'ofp',
|
||||
modulelable: 'OTDR测试仪',
|
||||
params: {
|
||||
limitValue: 'General Fiber RL = 35 dB',
|
||||
limitValue: estmodel === 'general' ? 'GB/T 50312-2016 Fiber Link' : 'General Fiber RL = 35 dB',
|
||||
cableType: 'OM3 Multimode 50'
|
||||
}
|
||||
}
|
||||
@@ -55,7 +56,9 @@ const defaultProject = {
|
||||
operators: [
|
||||
{ id: uuidv4(), name: 'Bob' }
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
const defaultProject = createDefaultProject(useDeviceStore.getState().estmodel);
|
||||
|
||||
// 默认状态
|
||||
const defaultState = {
|
||||
@@ -302,7 +305,7 @@ const useDisplayStore = create(devtools((set, get) => ({
|
||||
resetToDefaultState: () => {
|
||||
set(() => ({
|
||||
...defaultState,
|
||||
projects: [defaultProject]
|
||||
projects: [createDefaultProject(useDeviceStore.getState().estmodel)]
|
||||
}));
|
||||
},
|
||||
|
||||
@@ -324,4 +327,46 @@ const useDisplayStore = create(devtools((set, get) => ({
|
||||
|
||||
})));
|
||||
|
||||
useDeviceStore.subscribe(
|
||||
(state) => state.estmodel,
|
||||
(estmodel) => {
|
||||
const ds = useDisplayStore.getState();
|
||||
const idx = ds.selectedIndexes.projectIndex;
|
||||
const proj = ds.projects[idx];
|
||||
if (!proj) return;
|
||||
const testConfigs = proj.testConfigs.map((tc) => {
|
||||
if (tc.moduleType === '8000') {
|
||||
return {
|
||||
...tc,
|
||||
params: {
|
||||
...tc.params,
|
||||
limitValue: estmodel === 'general' ? 'GBT 50312-2016 Cat 6 Ch' : 'TIA Cat 6 Channel'
|
||||
}
|
||||
};
|
||||
}
|
||||
if (tc.moduleType === 'cfp') {
|
||||
return {
|
||||
...tc,
|
||||
params: {
|
||||
...tc.params,
|
||||
limitValue: estmodel === 'general' ? 'GB/T 50312-2016 Fiber Link' : 'TIA-568.3-E Multimode (STD)'
|
||||
}
|
||||
};
|
||||
}
|
||||
if (tc.moduleType === 'ofp') {
|
||||
return {
|
||||
...tc,
|
||||
params: {
|
||||
...tc.params,
|
||||
limitValue: estmodel === 'general' ? 'GB/T 50312-2016 Fiber Link' : 'General Fiber RL = 35 dB'
|
||||
}
|
||||
};
|
||||
}
|
||||
return tc;
|
||||
});
|
||||
const projects = ds.projects.map((p, i) => (i === idx ? { ...p, testConfigs } : p));
|
||||
useDisplayStore.setState({ projects });
|
||||
}
|
||||
);
|
||||
|
||||
export default useDisplayStore;
|
||||