litian
2025-03-18 4a8d8a5f49321d9597251e7ba69bf39f78baa51b
tijiao
4个文件已删除
9个文件已修改
12个文件已添加
1 文件已重命名
2625 ■■■■ 已修改文件
package-lock.json 444 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/App.vue 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/icon/fullScreen.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/icon/halfScreen.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/middleGround/tool.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/toolClass.js 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/TreeMenu.vue 268 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/header.vue 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/pageLayout.vue 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/plugin/axios/index.ts 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.ts 144 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/styles/global.less 134 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/index.vue 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/simulation/Config.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/simulation/Result.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/simulation/Test.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/simulation/autonomousFunction/index.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/simulation/index.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/simulation/realTimeSimulation/index.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/simulation/testSimulation/detail.vue 508 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/simulation/testSimulation/index.vue 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/simulation/testSimulation/testReport.vue 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/User.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/index.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/roleManage.vue 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/userManage.vue 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json
@@ -1,15 +1,18 @@
{
  "name": "my-vue-app",
  "name": "model",
  "version": "0.0.0",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
    "": {
      "name": "my-vue-app",
      "name": "model",
      "version": "0.0.0",
      "license": "MIT",
      "dependencies": {
        "@element-plus/icons-vue": "^2.3.1",
        "axios": "^1.6.2",
        "element-plus": "^2.5.6",
        "spark-md5": "^3.0.2",
        "vue": "^3.4.21",
        "vue-router": "^4.3.0"
      },
@@ -951,6 +954,44 @@
      "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz",
      "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
    },
    "node_modules/asynckit": {
      "version": "0.4.0",
      "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
    },
    "node_modules/axios": {
      "version": "1.8.1",
      "resolved": "https://registry.npmmirror.com/axios/-/axios-1.8.1.tgz",
      "integrity": "sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==",
      "dependencies": {
        "follow-redirects": "^1.15.6",
        "form-data": "^4.0.0",
        "proxy-from-env": "^1.1.0"
      }
    },
    "node_modules/call-bind-apply-helpers": {
      "version": "1.0.2",
      "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
      "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
      "dependencies": {
        "es-errors": "^1.3.0",
        "function-bind": "^1.1.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/combined-stream": {
      "version": "1.0.8",
      "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
      "dependencies": {
        "delayed-stream": "~1.0.0"
      },
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/copy-anything": {
      "version": "2.0.6",
      "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-2.0.6.tgz",
@@ -972,6 +1013,27 @@
      "version": "1.11.13",
      "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
      "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
    },
    "node_modules/delayed-stream": {
      "version": "1.0.0",
      "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
      "engines": {
        "node": ">=0.4.0"
      }
    },
    "node_modules/dunder-proto": {
      "version": "1.0.1",
      "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
      "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
      "dependencies": {
        "call-bind-apply-helpers": "^1.0.1",
        "es-errors": "^1.3.0",
        "gopd": "^1.2.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/element-plus": {
      "version": "2.9.5",
@@ -1022,6 +1084,47 @@
        "errno": "cli.js"
      }
    },
    "node_modules/es-define-property": {
      "version": "1.0.1",
      "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
      "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-errors": {
      "version": "1.3.0",
      "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-object-atoms": {
      "version": "1.1.1",
      "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
      "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
      "dependencies": {
        "es-errors": "^1.3.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-set-tostringtag": {
      "version": "2.1.0",
      "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
      "dependencies": {
        "es-errors": "^1.3.0",
        "get-intrinsic": "^1.2.6",
        "has-tostringtag": "^1.0.2",
        "hasown": "^2.0.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/esbuild": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz",
@@ -1070,6 +1173,39 @@
      "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
    },
    "node_modules/follow-redirects": {
      "version": "1.15.9",
      "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz",
      "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
      "funding": [
        {
          "type": "individual",
          "url": "https://github.com/sponsors/RubenVerborgh"
        }
      ],
      "engines": {
        "node": ">=4.0"
      },
      "peerDependenciesMeta": {
        "debug": {
          "optional": true
        }
      }
    },
    "node_modules/form-data": {
      "version": "4.0.2",
      "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.2.tgz",
      "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
      "dependencies": {
        "asynckit": "^0.4.0",
        "combined-stream": "^1.0.8",
        "es-set-tostringtag": "^2.1.0",
        "mime-types": "^2.1.12"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/fsevents": {
      "version": "2.3.3",
      "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
@@ -1084,12 +1220,102 @@
        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
      }
    },
    "node_modules/function-bind": {
      "version": "1.1.2",
      "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/get-intrinsic": {
      "version": "1.3.0",
      "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
      "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
      "dependencies": {
        "call-bind-apply-helpers": "^1.0.2",
        "es-define-property": "^1.0.1",
        "es-errors": "^1.3.0",
        "es-object-atoms": "^1.1.1",
        "function-bind": "^1.1.2",
        "get-proto": "^1.0.1",
        "gopd": "^1.2.0",
        "has-symbols": "^1.1.0",
        "hasown": "^2.0.2",
        "math-intrinsics": "^1.1.0"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/get-proto": {
      "version": "1.0.1",
      "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
      "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
      "dependencies": {
        "dunder-proto": "^1.0.1",
        "es-object-atoms": "^1.0.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/gopd": {
      "version": "1.2.0",
      "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
      "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/graceful-fs": {
      "version": "4.2.11",
      "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz",
      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
      "dev": true,
      "optional": true
    },
    "node_modules/has-symbols": {
      "version": "1.1.0",
      "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
      "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/has-tostringtag": {
      "version": "1.0.2",
      "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
      "dependencies": {
        "has-symbols": "^1.0.3"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/hasown": {
      "version": "2.0.2",
      "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
      "dependencies": {
        "function-bind": "^1.1.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/iconv-lite": {
      "version": "0.6.3",
@@ -1217,6 +1443,14 @@
        "node": ">=6"
      }
    },
    "node_modules/math-intrinsics": {
      "version": "1.1.0",
      "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/memoize-one": {
      "version": "6.0.0",
      "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz",
@@ -1233,6 +1467,25 @@
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/mime-db": {
      "version": "1.52.0",
      "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/mime-types": {
      "version": "2.1.35",
      "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
      "dependencies": {
        "mime-db": "1.52.0"
      },
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/nanoid": {
@@ -1325,6 +1578,11 @@
        "node": "^10 || ^12 || >=14"
      }
    },
    "node_modules/proxy-from-env": {
      "version": "1.1.0",
      "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
    },
    "node_modules/prr": {
      "version": "1.0.1",
      "resolved": "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz",
@@ -1411,6 +1669,11 @@
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/spark-md5": {
      "version": "3.0.2",
      "resolved": "https://registry.npmmirror.com/spark-md5/-/spark-md5-3.0.2.tgz",
      "integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw=="
    },
    "node_modules/tslib": {
      "version": "2.8.1",
@@ -2046,6 +2309,38 @@
      "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz",
      "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
    },
    "asynckit": {
      "version": "0.4.0",
      "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
    },
    "axios": {
      "version": "1.8.1",
      "resolved": "https://registry.npmmirror.com/axios/-/axios-1.8.1.tgz",
      "integrity": "sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==",
      "requires": {
        "follow-redirects": "^1.15.6",
        "form-data": "^4.0.0",
        "proxy-from-env": "^1.1.0"
      }
    },
    "call-bind-apply-helpers": {
      "version": "1.0.2",
      "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
      "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
      "requires": {
        "es-errors": "^1.3.0",
        "function-bind": "^1.1.2"
      }
    },
    "combined-stream": {
      "version": "1.0.8",
      "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
      "requires": {
        "delayed-stream": "~1.0.0"
      }
    },
    "copy-anything": {
      "version": "2.0.6",
      "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-2.0.6.tgz",
@@ -2064,6 +2359,21 @@
      "version": "1.11.13",
      "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
      "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
    },
    "delayed-stream": {
      "version": "1.0.0",
      "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
    },
    "dunder-proto": {
      "version": "1.0.1",
      "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
      "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
      "requires": {
        "call-bind-apply-helpers": "^1.0.1",
        "es-errors": "^1.3.0",
        "gopd": "^1.2.0"
      }
    },
    "element-plus": {
      "version": "2.9.5",
@@ -2100,6 +2410,35 @@
      "optional": true,
      "requires": {
        "prr": "~1.0.1"
      }
    },
    "es-define-property": {
      "version": "1.0.1",
      "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
      "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="
    },
    "es-errors": {
      "version": "1.3.0",
      "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="
    },
    "es-object-atoms": {
      "version": "1.1.1",
      "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
      "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
      "requires": {
        "es-errors": "^1.3.0"
      }
    },
    "es-set-tostringtag": {
      "version": "2.1.0",
      "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
      "requires": {
        "es-errors": "^1.3.0",
        "get-intrinsic": "^1.2.6",
        "has-tostringtag": "^1.0.2",
        "hasown": "^2.0.2"
      }
    },
    "esbuild": {
@@ -2143,6 +2482,22 @@
      "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
    },
    "follow-redirects": {
      "version": "1.15.9",
      "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz",
      "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ=="
    },
    "form-data": {
      "version": "4.0.2",
      "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.2.tgz",
      "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
      "requires": {
        "asynckit": "^0.4.0",
        "combined-stream": "^1.0.8",
        "es-set-tostringtag": "^2.1.0",
        "mime-types": "^2.1.12"
      }
    },
    "fsevents": {
      "version": "2.3.3",
      "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
@@ -2150,12 +2505,69 @@
      "dev": true,
      "optional": true
    },
    "function-bind": {
      "version": "1.1.2",
      "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
    },
    "get-intrinsic": {
      "version": "1.3.0",
      "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
      "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
      "requires": {
        "call-bind-apply-helpers": "^1.0.2",
        "es-define-property": "^1.0.1",
        "es-errors": "^1.3.0",
        "es-object-atoms": "^1.1.1",
        "function-bind": "^1.1.2",
        "get-proto": "^1.0.1",
        "gopd": "^1.2.0",
        "has-symbols": "^1.1.0",
        "hasown": "^2.0.2",
        "math-intrinsics": "^1.1.0"
      }
    },
    "get-proto": {
      "version": "1.0.1",
      "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
      "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
      "requires": {
        "dunder-proto": "^1.0.1",
        "es-object-atoms": "^1.0.0"
      }
    },
    "gopd": {
      "version": "1.2.0",
      "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
      "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="
    },
    "graceful-fs": {
      "version": "4.2.11",
      "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz",
      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
      "dev": true,
      "optional": true
    },
    "has-symbols": {
      "version": "1.1.0",
      "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
      "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="
    },
    "has-tostringtag": {
      "version": "1.0.2",
      "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
      "requires": {
        "has-symbols": "^1.0.3"
      }
    },
    "hasown": {
      "version": "2.0.2",
      "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
      "requires": {
        "function-bind": "^1.1.2"
      }
    },
    "iconv-lite": {
      "version": "0.6.3",
@@ -2240,6 +2652,11 @@
        "semver": "^5.6.0"
      }
    },
    "math-intrinsics": {
      "version": "1.1.0",
      "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="
    },
    "memoize-one": {
      "version": "6.0.0",
      "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz",
@@ -2251,6 +2668,19 @@
      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
      "dev": true,
      "optional": true
    },
    "mime-db": {
      "version": "1.52.0",
      "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
    },
    "mime-types": {
      "version": "2.1.35",
      "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
      "requires": {
        "mime-db": "1.52.0"
      }
    },
    "nanoid": {
      "version": "3.3.8",
@@ -2300,6 +2730,11 @@
        "picocolors": "^1.1.1",
        "source-map-js": "^1.2.1"
      }
    },
    "proxy-from-env": {
      "version": "1.1.0",
      "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
    },
    "prr": {
      "version": "1.0.1",
@@ -2370,6 +2805,11 @@
      "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="
    },
    "spark-md5": {
      "version": "3.0.2",
      "resolved": "https://registry.npmmirror.com/spark-md5/-/spark-md5-3.0.2.tgz",
      "integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw=="
    },
    "tslib": {
      "version": "2.8.1",
      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz",
src/App.vue
@@ -1,31 +1,8 @@
<script setup lang="ts">
import { ref } from "vue";
import Header from "./layout/Header.vue";
import TreeMenu from "./components/TreeMenu.vue";
import { ElConfigProvider } from "element-plus";
import zhCn from "element-plus/es/locale/lang/zh-cn";
const menuItem = ref("/");
const handMenu = (key: string) => {
  menuItem.value = key;
};
</script>
<template>
  <el-config-provider :locale="zhCn">
    <el-container class="common-layout">
      <el-header height="60px">
        <Header @selectMenu="handMenu" />
      </el-header>
      <el-container>
        <el-aside width="240px">
          <TreeMenu :menuItem="menuItem" />
        </el-aside>
        <el-main>
          <RouterView />
        </el-main>
      </el-container>
    </el-container>
  </el-config-provider>
</template>
<script setup lang="ts">
</script>
<style></style>
src/assets/images/icon/fullScreen.png
src/assets/images/icon/halfScreen.png
src/assets/js/middleGround/tool.js
@@ -1,9 +1,5 @@
import { requestCtx, appId } from "@/assets/js/config.js";
import defaultImg from "@/assets/images/default-book-img.png";
import defaultBookFair from "@/assets/images/default-bookFair.png"
import bookCover from "@/assets/images/book-cover.png";
import courseIcon from "@/assets/images/courseIcon.png";
import textBookIcon from "@/assets/images/textBookIcon.png";
import moment from "moment";
// 处理列表查询结果
export function handleQueryResourceListData({
@@ -428,15 +424,8 @@
  if (md5) {
    src = requestCtx + `/file/GetPreViewImage?md5=${md5}`;
  } else {
    if(storeInfo == 'jsek_bookFair') {
      // return defaultBookFair;
      return
    }else if(storeInfo == `defaultGoodsStore${appId}`){
    if(storeInfo == `defaultGoodsStore${appId}`){
      return bookCover;
    }else if(storeInfo == 'jsek_digitalCourses'){
      return courseIcon;
    }else if(storeInfo == 'jsek_digitalTextbooks'){
      return textBookIcon;
    }else{
      return ""
    }
src/assets/js/toolClass.js
@@ -1,6 +1,5 @@
import SparkMD5 from 'spark-md5'
import { getPublicImage } from '@/assets/js/middleGround/tool.js'
// import moment from "moment";
var tool = {
  secondToTime(second) {
@@ -71,70 +70,6 @@
  }
}
// 处理订单记录
// export function setOrderList(res) {
//   // 获取当前年份的开始时间
//   let currentTimestamp = moment().startOf("year");
//   let arr = [];
//   for (let i = 0; i < res.length; i++) {
//     const item = res[i];
//     // 发票状态为审核中或者审核失败,将item选中状态设置选中。
//     // UI控制禁用(显示的效果为 选中并且禁用)
//     if (item.invoiceInfo) {
//       item.checked = true;
//     } else {
//       item.checked = false;
//     }
//     // 判断是否超出申请发票的日期
//     item.exceedingTheSpecifiedTime = moment(item.createDate).isBefore(
//       currentTimestamp
//     );
//     if (item.saleMethodLinks.length > 0) {
//       let itemName = null;
//       let itemIcon = null;
//       let cmsItemList = null;
//       try {
//         cmsItemList = item.saleMethodLinks[0].orderSaleMethod.cmsItemList[0];
//       } catch (error) {
//         cmsItemList = null;
//       }
//       if (cmsItemList && cmsItemList.icon) {
//         itemName = cmsItemList.name;
//         itemIcon = cmsItemList.icon;
//       } else {
//         itemName = item.saleMethodLinks[0].orderSaleMethod.product.name;
//         itemIcon = item.saleMethodLinks[0].orderSaleMethod.product.icon;
//       }
//       item.saleMethodLinks[0].title = itemName;
//       item.saleMethodLinks[0].icon = getPublicImage(itemIcon);
//     } else {
//       const itemIcon = require("@/assets/images/bookCity/place_img.png");
//       const saleMethodLink = [];
//       const obj = {
//         icon: itemIcon,
//         orderSaleMethod: {
//           price: item.payPrice,
//         },
//       };
//       saleMethodLink.push(obj);
//       item.saleMethodLinks = saleMethodLink;
//     }
//     if (item.state == "Success") {
//       item.CustomState = "支付成功";
//     }
//     if (item.state == "Cancel") {
//       item.CustomState = "取消支付";
//     }
//     if (item.state == "WaitPay") {
//       item.CustomState = "等待支付";
//     }
//     if (item.state == "WaitDeliver") {
//       item.CustomState = "正在支付";
//     }
//     arr.push(item);
//   }
//   return arr;
// }
//处理表单提交数据
export function worksData(res) {
@@ -354,106 +289,7 @@
  })
}
// 处理时间,用于显示音视频当前时间
// export function realFormatSecond(time) {
//   let duration = parseInt(time);
//   let minute = parseInt(duration / 60);
//   let sec = (duration % 60) + "";
//   let isM0 = ":";
//   if (minute == 0) {
//     minute = "00";
//   } else if (minute < 10) {
//     minute = "0" + minute;
//   }
//   if (sec.length == 1) {
//     sec = "0" + sec;
//   }
//   return minute + isM0 + sec;
// }
// export function parseHtml(content) {
//   const tagReg =
//     /<\/?div[^>]*>|<\/?span[^>]*>|<\/?table[^>]*>|<\/?th[^>]*>|<\/?thead>|<\/?tbody>|<\/?tr>|<\/?td[^>]*>|<br[^>]*>|<\/?p[^>]*>|<\/?sub>|<\/?sup>|<\/?font[^>]*>|<img[^>]*>|<\/?a[^>]*>|\n|\\n/gi;
//   const escapeReg =
//     /&(lt|gt|le|ge|nbsp|amp|quot|times|Alpha|Beta|Gamma|Delta|Epsilon|Zeta|Eta|Theta|Iota|Kappa|Lambda|MU|NU|Xi|Omicron|Pi|Rho|Sigma|Tau|Upsilon|Phi|Chi|Psi|Omega|alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigmaf|sigma|tau|upsilon|phi|chi|psi|omega|thetasym|upsih|piv|circ|tilde|ndash|permil|lsquo|rsquo|ldquo|rdquo|prime);/gi;
//   const escapeElements = {
//     lt: "<",
//     gt: ">",
//     le: "≤",
//     ge: "≥",
//     nbsp: " ",
//     amp: "&",
//     quot: '""',
//     times: "×",
//     Alpha: "Α",
//     Beta: "Β",
//     Gamma: "Γ",
//     Delta: "Δ",
//     Epsilon: "Ε",
//     Zeta: "Ζ",
//     Eta: "Η",
//     Theta: "Θ",
//     Iota: "Ι",
//     Kappa: "Κ",
//     Lambda: "Λ",
//     Mu: "Μ",
//     Nu: "Ν",
//     Xi: "Ξ",
//     Omicron: "Ο",
//     Pi: "Π",
//     Rho: "Ρ",
//     Sigma: "Σ",
//     Tau: "Τ",
//     Upsilon: "Υ",
//     Phi: "Φ",
//     Chi: "Χ",
//     Psi: "Ψ",
//     Omega: "Ω",
//     alpha: "α",
//     beta: "β",
//     gamma: "γ",
//     delta: "δ",
//     epsilon: "ε",
//     zeta: "ζ",
//     eta: "η",
//     theta: "θ",
//     iota: "ι",
//     kappa: "κ",
//     lambda: "λ",
//     mu: "μ",
//     nu: "ν",
//     xi: "ξ",
//     omicron: "ο",
//     pi: "π",
//     rho: "ρ",
//     sigmaf: "ς",
//     sigma: "σ",
//     tau: "τ",
//     upsilon: "υ",
//     phi: "φ",
//     chi: "χ",
//     psi: "ψ",
//     omega: "ω",
//     thetasym: "ϑ",
//     upsih: "ϒ",
//     piv: "ϖ",
//     circ: "ˆ",
//     tilde: "˜",
//     ndash: "–",
//     permil: "‰",
//     lsquo: "‘",
//     rsquo: "’",
//     ldquo: "“",
//     rdquo: "”",
//     prime: "′",
//   };
//   const contentWithoutTag = content.replace(tagReg, "");
//   const contentWithOnlyOneSpace = contentWithoutTag.replace(/ {2,}/g, " ");
//   return contentWithOnlyOneSpace.replace(
//     escapeReg,
//     (all, t) => escapeElements[t]
//   );
// }
export default {
  ...tool,
@@ -463,5 +299,4 @@
  UpdateworksDataBytool,
  getPublicImage,
  worksData
  // parseHtml,
}
src/components/TreeMenu.vue
@@ -1,11 +1,13 @@
<template>
  <div class="tree-menu-box">
    <div class="flex">
  <div class="tree-menu">
    <div class="topMenu">
      <span class="topMenu-title">模型库</span>
      <div class="btnGroup">
        <el-icon class="icon1"><FolderAdd /></el-icon>
        <el-icon class="icon2"><Edit /></el-icon>
        <el-icon class="icon3"><Delete /></el-icon>
          <span class="topMenu-title">{{ menuName }}</span>
          <div class="btnGroup" v-if="props.menuItem == 'model'">
            <el-icon class="icon1" @click="addBtn"><FolderAdd /></el-icon>
            <el-icon class="icon2" @click="editBtn"><Edit /></el-icon>
            <el-icon class="icon3" @click="delBtn"><Delete /></el-icon>
      </div>
    </div>
    <el-tree
@@ -24,11 +26,67 @@
      </template>
    </el-tree>
  </div>
      <div class="tree-menu" v-if="props.menuItem == 'systemManage'">
        <div class="topMenu">
          <span class="topMenu-title">{{ systemMenuName }}</span>
          <div class="btnGroup">
            <el-icon class="icon1" @click="addBtn"><FolderAdd /></el-icon>
            <el-icon class="icon2" @click="editBtn"><Edit /></el-icon>
            <el-icon class="icon3" @click="delBtn"><Delete /></el-icon>
          </div>
        </div>
        <el-tree
          ref="treeRef"
          :data="systemData"
          :props="defaultProps"
          :filter-node-method="filterNode1"
          default-expand-all
          @node-click="systemClick"
        >
          <template #default="{ node, data }">
            <span class="custom-tree-node">
              <el-icon v-if="data.icon"><component :is="data.icon" /></el-icon>
              <span>{{ node.label }}</span>
            </span>
          </template>
        </el-tree>
      </div>
    </div>
  </div>
  <el-dialog
    v-model="dialogFormVisible"
    :title="dialogTitle"
    width="500"
    @close="closeDialog(formRef)"
  >
    <el-form :model="form" ref="formRef" :rules="formRules" label-width="140px">
      <el-form-item label="名称" prop="name">
        <el-input v-model="form.name" autocomplete="off" placeholder="请输入" style="width: 240px"/>
      </el-form-item>
      <el-form-item label="描述">
        <el-input
          v-model="form.description"
          style="width: 240px"
          :rows="2"
          type="textarea"
          placeholder="请输入"
        />
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="closeDialog(formRef)">取消</el-button>
        <el-button type="primary" @click="submitBtn(formRef)"> 确定 </el-button>
      </div>
    </template>
  </el-dialog>
</template>
<script setup lang="ts">
import { ref, watch, defineProps } from "vue";
import { ref, reactive, defineProps, onMounted } from "vue";
import { useRouter } from "vue-router";
import type { FormInstance, FormRules} from "element-plus";
import { ElMessage, ElMessageBox } from 'element-plus'
import { Document, FolderOpened } from "@element-plus/icons-vue";
const router = useRouter();
@@ -36,13 +94,21 @@
const props = defineProps<{
  menuItem: string;
}>();
const menuName = ref("模型库");
const filteredData = ref();
const systemMenuName = ref("");
const systemData = ref();
const selectData = ref()
interface TreeNode {
  label: string;
  path?: string;
  icon?: string;
  children?: TreeNode[];
}
const defaultProps = {
  children: "children",
  label: "label",
};
const modelTreeData = ref<TreeNode[]>([
  {
@@ -68,41 +134,199 @@
  },
]);
const defaultProps = {
  children: "children",
  label: "label",
};
const visualSimulationTreeData = ref<TreeNode[]>([
  {
    label: "测试仿真",
    path: "/testSimulation",
    icon: "Document",
  },
  {
    label: "实时仿真",
    path: "realTimeSimulation",
    icon: "Document",
  },
  {
    label: "自主功能",
    path: "/autonomousFunction",
    icon: "Document",
  },
]);
const filteredData = ref(modelTreeData.value);
const systemManageTreeData = ref<TreeNode[]>([
  {
    label: "机构用户",
    path: "/userManage",
    icon: "Document",
  },
  {
    label: "角色权限管理",
    path: "/roleManage",
    icon: "Document",
  },
]);
const systemTreeData = ref<TreeNode[]>([
  {
    label: "501",
    path: "",
    icon: "Document",
    children: [
      {
        label: "一室",
        path: "",
        icon: "",
      },
      {
        label: "二室",
        path: "",
        icon: "",
      },
      {
        label: "三室",
        path: "",
        icon: "",
      },
    ],
  },
]);
const systemTreeData1 = ref<TreeNode[]>([
  {
    label: "系统管理员",
    path: "",
    icon: "",
  },
  {
    label: "模型管理员",
    path: "",
    icon: "",
  },
  {
    label: "测试人员",
    path: "",
    icon: "",
  },
  {
    label: "报告查看人员",
    path: "",
    icon: "",
  },
]);
const dialogFormVisible = ref(false);
const dialogTitle = ref()
const formRef = ref<FormInstance>();
const form = reactive({
  name: "",
  description: "",
});
interface formInfo {
  name: string;
}
const formRules = reactive<FormRules<formInfo>>({
  name: [{ required: true, message: "名称不能为空", trigger: "blur" }],
});
onMounted(() => {
  console.log(props.menuItem, "123");
  if (props.menuItem == "model") {
    filteredData.value = modelTreeData.value;
    menuName.value = "模型库";
  } else if (props.menuItem == "simulation") {
    menuName.value = "可视化仿真";
    filteredData.value = visualSimulationTreeData.value;
  } else if (props.menuItem == "systemManage") {
    menuName.value = "系统管理";
    filteredData.value = systemManageTreeData.value;
  } else {
    filteredData.value = [];
  }
  systemMenuName.value = systemManageTreeData.value[0].label;
});
const filterNode = (value: string, data: TreeNode) => {
  if (!value) return true;
  return data.label.toLowerCase().includes(value.toLowerCase());
};
const filterNode1 = (value: string, data: TreeNode) => {
  if (!value) return true;
  return data.label.toLowerCase().includes(value.toLowerCase());
};
const handleNodeClick = (data: TreeNode) => {
  console.log(data, 12);
  selectData.value = data
  if (data.path) {
    systemMenuName.value = data.label;
    if (data.path == "/userManage") {
      systemData.value = systemTreeData.value;
    } else if (data.path == "/roleManage") {
      systemData.value = systemTreeData1.value;
    }
    router.push(data.path);
  }
};
watch(
  () => props.menuItem,
  (value) => {
    if (value == "/" || value == "/model") {
      filteredData.value = modelTreeData.value;
    } else {
      filteredData.value = []
//添加目录
const addBtn = () => {
  dialogTitle.value = '添加'
  dialogFormVisible.value = true;
};
const submitBtn = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate((valid, fields) => {
    if (valid) {
    }
  });
};
const closeDialog = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.resetFields();
  dialogFormVisible.value = false;
};
const editBtn =() =>{
  dialogTitle.value = '编辑'
  form.name = selectData.value.label
  dialogFormVisible.value = true;
  }
);
const delBtn =()=>{
  ElMessageBox.confirm(
    '确定要删除选中的数据?',
    'Warning',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )
    .then(() => {
      console.log()
    })
    .catch(() => {
    })
}
const systemClick = (data: TreeNode) => {};
</script>
<style lang="less" scoped>
.tree-menu {
.tree-menu-box {
  height: 100%;
  background-color: #fff;
  .flex {
    height: 100%;
  }
}
.tree-menu {
  width: 260px;
  height: 100%;
  border-right: 1px solid #e9eef3;
  :deep(.el-tree) {
    padding: 10px;
  }
src/layout/components/header.vue
File was renamed from src/layout/Header.vue
@@ -8,25 +8,47 @@
      mode="horizontal"
      :default-active="activeIndex"
      class="header-menu"
      @select="handleSelect"
      router
    >
      <el-menu-item index="/">模型管理</el-menu-item>
      <el-menu-item index="/simulation-config">可视化仿真</el-menu-item>
      <el-menu-item index="/system/user">系统管理</el-menu-item>
      <!-- <el-menu-item index="/">模型管理</el-menu-item>
      <el-menu-item index="/simulation">可视化仿真</el-menu-item>
      <el-menu-item index="/systemManage">系统管理</el-menu-item> -->
      <el-menu-item
        v-for="(item,index) in navList"
        :key="item.path"
        :index="item.path"
        @click="handleSelect(item.path, index)"
        >{{ item.name }}</el-menu-item
      >
    </el-menu>
  </div>
</template>
<script setup lang="ts">
import { ref, defineEmits } from "vue";
import { useRoute, useRouter } from "vue-router";
const router = useRouter();
const route = useRoute();
const activeIndex = ref("/");
const emit = defineEmits(["selectMenu"]);
const navList = ref([
  {
    name: "模型管理",
    path: "/model",
  },
  {
    name: "可视化仿真",
    path: "/simulation",
  },
  {
    name: "系统管理",
    path: "/systemManage",
  },
]);
const handleSelect = (key: string) => {
  activeIndex.value = key;
  emit("selectMenu", key);
const handleSelect = (path: string) => {
  activeIndex.value = path;
  router.push(path);
};
</script>
src/layout/pageLayout.vue
New file
@@ -0,0 +1,22 @@
<template>
  <div class="common-layout">
    <el-config-provider :locale="zhCn">
      <el-container>
        <el-header>
            <Header class="header"></Header>
        </el-header>
        <el-main>
          <RouterView />
        </el-main>
      </el-container>
    </el-config-provider>
  </div>
</template>
<script setup lang="ts">
import { ref, watch, provide, onMounted } from "vue";
import { RouterView, useRouter } from "vue-router";
import zhCn from "element-plus/es/locale/lang/zh-cn";
import Header from "./components/header.vue";
const router = useRouter();
</script>
<style lang="less" scoped></style>
src/plugin/axios/index.ts
@@ -1,6 +1,5 @@
import axios from 'axios'
import myConfig from '@/assets/js/config.js'
import toolClass from '@/assets/js/toolClass.js'
import router from '@/router'
// 创建 axios 实例
const service = axios.create({
@@ -59,18 +58,7 @@
      //   }
      // })
      const url = window.location.hash.slice(1)
      console.log(url, 'url')
      if (url.includes('showLogin=1')) {
        router.push(url)
      } else {
        // router.push(url)
        if (url.includes('?')) {
          console.log(url.includes('?'))
          router.push(url)
        } else {
          router.push(url + '?showLogin=1')
        }
      }
    } else {
      if (error.response && error.response.data && error.response.data.error) {
        console.error(error.response.data.error.msg)
src/router/index.ts
@@ -1,58 +1,118 @@
import { createRouter, createWebHistory } from 'vue-router'
import { createRouter, createWebHistory } from "vue-router";
import PageLayout from '../layout/pageLayout.vue'
const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/',
      redirect: '/model'
    },
    {
      path: '/model',
      name: 'model',
      redirect: '/model/landerModel',
      component: () => import('../views/model/index.vue'),
      path: "/",
      component: PageLayout,
      redirect: "/model",
      children: [
        {
          path: '/model/landerModel',
          name: 'landerModel',
          component: () => import('../views/model/children/landerModel.vue')
          path: "/model",
          name: "model",
          redirect: "/model/landerModel",
          component: () => import("../views/model/index.vue"),
          children: [
            {
              path: "/model/landerModel",
              name: "landerModel",
              component: () => import("../views/model/children/landerModel.vue"),
        },
        {
          path: '/model/roverModel',
          name: 'roverModel',
          component: () => import('../views/model/children/roverModel.vue')
              path: "/model/roverModel",
              name: "roverModel",
              component: () => import("../views/model/children/roverModel.vue"),
        },
        {
          path: '/model/leapMachineModel',
          name: 'leapMachineModel',
          component: () => import('../views/model/children/leapMachineModel.vue')
              path: "/model/leapMachineModel",
              name: "leapMachineModel",
              component: () =>
                import("../views/model/children/leapMachineModel.vue"),
            },
          ],
        },
        {
          path: "/simulation",
          name: "simulation",
          component: () => import("../views/simulation/index.vue"),
          redirect: "/testSimulation",
          meta: {
            name: '测试仿真'
          },
          children: [
            {
              path: "/testSimulation",
              name: "testSimulation",
              component: () =>
                import("../views/simulation/testSimulation/index.vue"),
            },
            {
              path: "/testSimulation/detail",
              name: "testSimulation-detail",
              component: () =>
                import("../views/simulation/testSimulation/detail.vue"),
            },
            {
              path: "/testSimulation/testReport",
              name: "testReport",
              component: () =>
                import("../views/simulation/testSimulation/testReport.vue"),
            },
            {
              path: "/realTimeSimulation",
              name: "realTimeSimulation",
              meta: {
                name: '实时仿真'
              },
              component: () =>
                import("../views/simulation/realTimeSimulation/index.vue"),
            },
            {
              path: "/autonomousFunction",
              name: "autonomousFunction",
              meta: {
                name: '自主功能'
              },
              component: () =>
                import("../views/simulation/autonomousFunction/index.vue"),
            },
          ],
        },
        {
          path: "/systemManage",
          name: "systemManage",
          meta: {
            name: '系统管理'
          },
          component: () => import("../views/system/index.vue"),
          redirect: "/userManage",
          children: [
            {
              path: "/userManage",
              name: "userManage",
              meta: {
                name: '用户管理'
              },
              component: () =>
                import("../views/system/userManage.vue"),
            },
            {
              path: "/roleManage",
              name: "roleManage",
              meta: {
                name: '角色管理'
              },
              component: () =>
                import("../views/system/roleManage.vue"),
        },
      ]
    },
    {
      path: '/simulation-config',
      name: 'simulationConfig',
      component: () => import('../views/simulation/Config.vue')
    },
    {
      path: '/simulation-result',
      name: 'simulationResult',
      component: () => import('../views/simulation/Result.vue')
    },
    {
      path: '/simulation-test',
      name: 'simulationTest',
      component: () => import('../views/simulation/test.vue')
    },
    {
      path: '/system/user',
      name: 'systemUser',
      component: () => import('../views/system/User.vue')
    },
      ],
    }
  ]
})
});
export default router
export default router;
src/styles/global.less
@@ -11,6 +11,44 @@
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
}
div,
span,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
a,
img,
strong,
sub,
sup,
ol,
ul,
li,
form,
label,
table,
tbody,
tfoot,
thead,
tr,
th,
td,
canvas,
audio,
video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  /* vertical-align: baseline; */
}
// 混入
@@ -48,18 +86,10 @@
  color: #535bf2;
}
html,
body {
  margin: 0;
  display: flex;
  place-items: center;
  width: 100%;
  height: 100%;
}
h1 {
  font-size: 3.2em;
  line-height: 1.1;
  margin:0;
}
button {
@@ -91,12 +121,11 @@
  width: 100%;
  height: 100%;
  margin: 0 auto;
  text-align: center;
  // text-align: center;
}
/* 引入 Element Plus 的基础样式 */
.common-layout {
  width: 100%;
@@ -104,7 +133,7 @@
}
.common-layout .el-container {
  height: calc(100% - 60px);
  height: 100%;
}
.el-header {
@@ -113,17 +142,40 @@
  line-height: 60px;
}
.el-aside {
  background-color: #D3DCE6;
  color: #333;
}
.el-main {
  background-color: #E9EEF3;
  color: #333;
  padding: 10px !important;
  padding: 0 !important;
  box-sizing: border-box;
  flex: auto;
}
.pageContainer{
  display: flex;
  width: 100%;
  height: 100%;
  // background-color: #fff;
  padding-top: 10px;
  box-sizing: border-box;
}
.menuBox{
  box-sizing: border-box;
}
.contentBox{
  flex:1 1;
  box-sizing: border-box;
  overflow: hidden;
  padding:10px;
  background-color: #fff;
}
.el-table__header{
  thead .el-table__cell{
    background:#f1f1f1;
  }
}
.mb-4 {
  margin-bottom: 16px;
@@ -148,3 +200,49 @@
    background-color: #f9f9f9;
  }
}
//自定义
ul {
  list-style: none;
  margin:0
}
.flex{
  display: flex;
}
/* 垂直居中 */
.ai-c {
  align-items: center;
}
/* 两边对齐 */
.jc-sb {
  justify-content: space-between;
}
.hover{
  cursor: pointer;
}
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-track-piece {
  background-color: rgba(0, 0, 0, 0.2);
  -webkit-border-radius: 6px;
}
::-webkit-scrollbar-thumb:vertical {
  height: 5px;
  background-color: rgba(125, 125, 125, 0.7);
  -webkit-border-radius: 6px;
}
::-webkit-scrollbar-thumb:horizontal {
  width: 5px;
  background-color: rgba(125, 125, 125, 0.7);
  -webkit-border-radius: 6px;
}
src/views/model/index.vue
@@ -1,16 +1,16 @@
<template>
  <div class="modelContainer">
    <RouterView />
  <div class="pageContainer">
    <div class="menuBox">
      <treeMenu :menuItem="menuItem"/>
    </div>
    <div class="contentBox"><RouterView /></div>
  </div>
</template>
<script setup lang="ts">
import { ref} from "vue";
import treeMenu from "@/components/treeMenu.vue";
const menuItem = ref('model')
</script>
<style lang="less" scoped>
.modelContainer {
  width: 100%;
  height: 100%;
  background-color: #fff;
}
</style>
<style lang="less" scoped></style>
src/views/simulation/Config.vue
File was deleted
src/views/simulation/Result.vue
File was deleted
src/views/simulation/Test.vue
File was deleted
src/views/simulation/autonomousFunction/index.vue
New file
@@ -0,0 +1,14 @@
<template>
    <div class="simulation-config">
      <h2>自主管理</h2>
    </div>
  </template>
  <script setup lang="ts">
  </script>
  <style lang="less" scoped>
  .simulation-config {
    padding: 20px;
  }
  </style>
src/views/simulation/index.vue
New file
@@ -0,0 +1,16 @@
<template>
  <div class="pageContainer">
    <div class="menuBox">
      <treeMenu :menuItem="menuItem"/>
    </div>
    <div class="contentBox"><RouterView /></div>
  </div>
</template>
<script setup lang="ts">
import { ref} from "vue";
import treeMenu from "@/components/treeMenu.vue";
const menuItem = ref('simulation')
</script>
<style lang="less" scoped></style>
src/views/simulation/realTimeSimulation/index.vue
New file
@@ -0,0 +1,14 @@
<template>
    <div class="simulation-config">
      <h2>实时仿真</h2>
    </div>
</template>
  <script setup lang="ts">
  </script>
  <style lang="less" scoped>
  .simulation-config {
    padding: 20px;
  }
  </style>
src/views/simulation/testSimulation/detail.vue
New file
@@ -0,0 +1,508 @@
<template>
  <div class="simulation-result">
    <div style="width: 100%; height: 100%; background: #fff" id="myDiv">
      <div class="titleBox">
        <div class="name">
          <span>{{ name }}仿真</span>
          <img
            src="@/assets/images/icon/fullScreen.png"
            @click="enlargeDiv('true')"
            v-if="enlarge"
          />
          <img
            src="@/assets/images/icon/halfScreen.png"
            @click="enlargeDiv('false')"
            v-else
          />
        </div>
        <div class="back hover" @click="goBack">
          <el-icon ><ArrowLeftBold /></el-icon>返回
        </div>
      </div>
      <div class="flex bodyBox">
        <div class="modelBox"></div>
        <div class="shadowBox">
          <div id="shadowX">
            <div class="title">
              <span>X轴投影</span>
              <img
                src="@/assets/images/icon/fullScreen.png"
                @click="enlargeXDiv('true')"
                v-if="enlargeX"
              />
              <img
                src="@/assets/images/icon/halfScreen.png"
                @click="enlargeXDiv('false')"
                v-else
              />
            </div>
            <div class="shadowX-body"></div>
          </div>
          <div id="shadowY">
            <div class="title">
              <span>Y轴投影</span>
              <img
                src="@/assets/images/icon/fullScreen.png"
                @click="enlargeYDiv('true')"
                v-if="enlargeY"
              />
              <img
                src="@/assets/images/icon/halfScreen.png"
                @click="enlargeYDiv('false')"
                v-else
              />
            </div>
            <div class="shadowY-body"></div>
          </div>
          <div id="shadowZ">
            <div class="title">
              <span>Z轴投影</span>
              <img
                src="@/assets/images/icon/fullScreen.png"
                @click="enlargeZDiv('true')"
                v-if="enlargeZ"
              />
              <img
                src="@/assets/images/icon/halfScreen.png"
                @click="enlargeZDiv('false')"
                v-else
              />
            </div>
            <div class="shadowZ-body"></div>
          </div>
        </div>
      </div>
      <div class="flex operateBox" id="operateBox">
        <div id="instruct">
          <div class="title jc-sb">
            <div class="title">
              <span>指令</span>
              <img
                src="@/assets/images/icon/fullScreen.png"
                @click="enlargeInstructDiv('true')"
                v-if="enlargeI"
              />
              <img
                src="@/assets/images/icon/halfScreen.png"
                @click="enlargeInstructDiv('false')"
                v-else
              />
            </div>
            <div class="upBold">
              <el-icon @click="operateBoxDiv('true')" v-if="operate"
                ><ArrowUpBold
              /></el-icon>
              <el-icon @click="operateBoxDiv('false')" v-else
                ><ArrowDownBold
              /></el-icon>
            </div>
          </div>
          <div class="instruct-body">
            <div class="instruct-list">
              <div v-for="(item, index) in instructList" :key="index">
                >{{ item }}
              </div>
            </div>
            <div class="inputBox">
              <el-input
                v-model="instructContent"
                placeholder="请输入指令"
                @keyup.enter="setInstruct"
              />
            </div>
          </div>
        </div>
        <div id="resize"></div>
        <div id="log">
          <div class="title jc-sb">
            <div class="title">
              <span>日志</span>
              <img
                src="@/assets/images/icon/fullScreen.png"
                @click="enlargeLogDiv('true')"
                v-if="enlargeL"
              />
              <img
                src="@/assets/images/icon/halfScreen.png"
                @click="enlargeLogDiv('false')"
                v-else
              />
            </div>
            <div class="upBold">
              <el-icon @click="operateBoxDiv('true')" v-if="operate"
                ><ArrowUpBold
              /></el-icon>
              <el-icon @click="operateBoxDiv('false')" v-else
                ><ArrowDownBold
              /></el-icon>
            </div>
          </div>
          <div class="log-body">
            <div class="log-list">
              <div v-for="(item, index) in instructList" :key="index">
                >{{ item }}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <el-dialog v-model="reportDialogForm" title="生成测试报告" width="500">
    <el-form :model="reportInfo">
      <el-form-item label="报告名称" label-width="100px">
        <el-input v-model="reportInfo.reportName" autocomplete="off" />
      </el-form-item>
      <el-form-item label="测试时间" label-width="100px">
        <el-input v-model="reportInfo.testTime" autocomplete="off" disabled/>
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="reportDialogForm = false">否</el-button>
        <el-button type="primary" @click="reportDialogForm = false">
         是
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>
<script setup lang="ts">
import { ref, reactive,onMounted } from "vue";
const name = ref("飞跃器整模型");
const reportDialogForm = ref(false)
const reportInfo = reactive({
  reportName:'',
  testTime: '',
})
const enlarge = ref(true);
const enlargeX = ref(true);
const enlargeY = ref(true);
const enlargeZ = ref(true);
const enlargeI = ref(true);
const enlargeL = ref(true);
const instructContent = ref("");
const operate = ref(true);
const instructList = ref([]);
const logList = ref([]);
const goBack =()=>{
  var time = new Date(Date.now());
        var year = time.getFullYear();
        var month = time.getMonth()+1;
        var day = time.getDate();
        var hour = time.getHours();
        var minute = time.getMinutes();
        var second = time.getSeconds();
        reportInfo.testTime = year+'-'+(month<10?'0'+month:month)+'-'+(day<10?'0'+day:day)+' '+(hour<10?'0'+hour:hour)+':'+(minute<10?'0'+minute:minute)+':'+(second<10?'0'+second:second)
    reportDialogForm.value = true
}
const enlargeDiv = (state) => {
  let divStyle = document.getElementById("myDiv");
  if (state == "true") {
    enlarge.value = false;
    let screenWidth = window.innerWidth; // 获取屏幕宽度
    let screenHeight = window.innerHeight; // 获取屏幕高度
    divStyle.style.width = screenWidth + "px"; // 设置宽度为屏幕宽度
    divStyle.style.height = screenHeight + "px"; // 设置高度为屏幕高度
    divStyle.style.left = "0"; // 设置左边距为0,使其从屏幕左侧开始
    divStyle.style.top = "0"; // 设置顶部边距为0,使其从屏幕顶部开始
    divStyle.style.position = "fixed"; // 使用fixed定位,确保覆盖整个屏幕
  } else {
    enlarge.value = true;
    divStyle.style.width = "100%"; // 还原宽度
    divStyle.style.height = "100%"; // 还原高度
    divStyle.style.left = ""; // 清除左边距
    divStyle.style.top = ""; // 清除顶部边距
    divStyle.style.position = ""; // 清除定位属性
  }
};
const enlargeXDiv = (state) => {
  let divStyle = document.getElementById("shadowX");
  if (state == "true") {
    enlargeX.value = false;
    let screenWidth = window.innerWidth;
    let screenHeight = window.innerHeight;
    divStyle.style.width = screenWidth + "px";
    divStyle.style.height = screenHeight + "px";
    divStyle.style.left = "0";
    divStyle.style.top = "0";
    divStyle.style.position = "fixed";
  } else {
    enlargeX.value = true;
    divStyle.style.width = "100%";
    divStyle.style.height = "calc((100% - 6px) / 3)";
    divStyle.style.left = "";
    divStyle.style.top = "";
    divStyle.style.position = "";
  }
};
const enlargeYDiv = (state) => {
  let divStyle = document.getElementById("shadowY");
  if (state == "true") {
    enlargeY.value = false;
    let screenWidth = window.innerWidth;
    let screenHeight = window.innerHeight;
    divStyle.style.width = screenWidth + "px";
    divStyle.style.height = screenHeight + "px";
    divStyle.style.left = "0";
    divStyle.style.top = "0";
    divStyle.style.position = "fixed";
  } else {
    enlargeY.value = true;
    divStyle.style.width = "100%";
    divStyle.style.height = "calc((100% - 6px) / 3)";
    divStyle.style.left = "";
    divStyle.style.top = "";
    divStyle.style.position = "";
  }
};
const enlargeZDiv = (state) => {
  let divStyle = document.getElementById("shadowZ");
  if (state == "true") {
    enlargeZ.value = false;
    let screenWidth = window.innerWidth;
    let screenHeight = window.innerHeight;
    divStyle.style.width = screenWidth + "px";
    divStyle.style.height = screenHeight + "px";
    divStyle.style.left = "0";
    divStyle.style.top = "0";
    divStyle.style.position = "fixed";
  } else {
    enlargeZ.value = true;
    divStyle.style.width = "100%";
    divStyle.style.height = "calc((100% - 6px) / 3)";
    divStyle.style.left = "";
    divStyle.style.top = "";
    divStyle.style.position = "";
  }
};
const enlargeInstructDiv = (state) => {
  let divStyle = document.getElementById("instruct");
  if (state == "true") {
    enlargeI.value = false;
    let screenWidth = window.innerWidth;
    let screenHeight = window.innerHeight;
    divStyle.style.width = screenWidth + "px";
    divStyle.style.height = screenHeight + "px";
    divStyle.style.left = "0";
    divStyle.style.top = "0";
    divStyle.style.position = "fixed";
  } else {
    enlargeI.value = true;
    divStyle.style.width = "100%";
    divStyle.style.height = "100%";
    divStyle.style.left = "";
    divStyle.style.top = "";
    divStyle.style.position = "";
  }
};
const enlargeLogDiv = (state) => {
  let divStyle = document.getElementById("log");
  if (state == "true") {
    enlargeL.value = false;
    let screenWidth = window.innerWidth;
    let screenHeight = window.innerHeight;
    divStyle.style.width = screenWidth + "px";
    divStyle.style.height = screenHeight + "px";
    divStyle.style.left = "0";
    divStyle.style.top = "0";
    divStyle.style.position = "fixed";
  } else {
    enlargeL.value = true;
    divStyle.style.width = "100%";
    divStyle.style.height = "100%";
    divStyle.style.left = "";
    divStyle.style.top = "";
    divStyle.style.position = "";
  }
};
const operateBoxDiv = (state) => {
  let divStyle = document.getElementById("operateBox");
  if (state == "true") {
    operate.value = false;
    divStyle.style.width = "100%";
    divStyle.style.height = "calc(100% - 36px)";
    divStyle.style.left = "0";
    divStyle.style.top = "36px";
    divStyle.style.position = "absolute";
  } else {
    operate.value = true;
    divStyle.style.height = "calc(100% - 36px - 70%)";
    divStyle.style.left = "";
    divStyle.style.top = "";
    divStyle.style.position = "";
  }
};
const setInstruct = () => {
  console.log(instructContent.value);
  instructList.value.push(instructContent.value);
  logList.value.push(instructContent.value);
  instructContent.value = "";
};
onMounted(() => {
  handleResize();
});
//指令日志框宽度拖拽
const handleResize = () => {
  let operateDom = document.getElementById("operateBox");
  let instructDom = document.getElementById("instruct");
  let logDom = document.getElementById("log");
  let resizeDom = document.getElementById("resize");
  for (let i = 0; i < resizeDom.length; i++) {
        // 鼠标按下事件
        console.log(1)
        resizeDom[i].onmousedown = function (e) {
            //颜色改变提醒
            resizeDom[i].style.background = '#f0f2f5'
            var startX = e.clientX
            resizeDom[i].left = resizeDom[i].offsetLeft
            // 鼠标拖动事件
            document.onmousemove = function (e) {
              console.log(2)
                var endX = e.clientX
                var moveLen = resizeDom[i].left + (endX - startX) // (endx-startx)=移动的距离。resize[i].left+移动的距离=左边区域最后的宽度
                var maxT = operateDom[i].clientWidth - resizeDom[i].offsetWidth // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
                if (moveLen < 200) moveLen = 200 // 左边区域的最小宽度为32px
                if (moveLen > maxT - 200) moveLen = maxT - 200 //右边区域最小宽度为150px
                resizeDom[i].style.left = moveLen // 设置左侧区域的宽度
                for (let j = 0; j < instructDom.length; j++) {
                  instructDom[j].style.width = moveLen + 'px'
                    logDom[j].style.width = operateDom[i].clientWidth - moveLen - 10 + 'px'
                }
            }
            // 鼠标松开事件
            document.onmouseup = function (evt) {
                //颜色恢复
                resizeDom[i].style.background = '#f0f2f5'
                document.onmousemove = null
                document.onmouseup = null
                resizeDom[i].releaseCapture && resizeDom[i].releaseCapture() //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
            }
            resizeDom[i].setCapture && resizeDom[i].setCapture() //该函数在属于当前线程的指定窗口里设置鼠标捕获
            return false
        }
    }
};
</script>
<style lang="less" scoped>
.simulation-result {
  width: 100%;
  height: 100%;
  position: relative;
}
.titleBox {
  height: 36px;
  line-height: 36px;
  background: #409eff;
  position: relative;
  .name {
    display: flex;
    justify-content: center; /* 水平居中 */
    align-items: center;
    img {
      margin-left: 10px;
    }
  }
  .back {
    position: absolute;
    left: 10px;
    top: 0;
    display: flex;
    align-items: center;
    color: #ffffff;
  }
}
.title {
  background: #409eff;
  height: 36px;
  display: flex;
  align-items: center;
  padding: 0 10px;
  img {
    margin-left: 10px;
  }
}
.bodyBox {
  height: 70%;
  .modelBox {
    width: 60%;
    border: 1px solid #f1f1f1;
  }
  .shadowBox {
    width: 40%;
  }
  #shadowX,
  #shadowY,
  #shadowZ {
    background: #fff;
    height: calc((100% - 6px) / 3);
    border: 1px solid #f1f1f1;
  }
}
.operateBox {
  height: calc(100% - 36px - 70%);
  box-sizing: border-box;
  overflow: hidden;
  #instruct,
  #log {
    background: #fff;
    border: 1px solid #f1f1f1;
    width: calc((100% - 4px) / 2);
    height: 100%;
    box-sizing: border-box;
    float: left;
  }
  #resize {
    width: 3px;
    position: relative;
    cursor: col-resize;
    background-size: cover;
    background-position: center;
    &:hover {
      background: #45a3ff;
    }
  }
  .upBold {
    display: flex;
    align-items: center;
    color: #fff;
  }
  .instruct-body {
    height: calc(100% - 36px);
    position: relative;
    .instruct-list {
      height: calc(100% - 52px);
      overflow-y: auto;
      padding: 10px;
    }
    .inputBox {
      width: 100%;
      position: absolute;
      bottom: 0;
    }
  }
  .log-body {
    height: calc(100% - 36px);
    .log-list {
      height: calc(100% - 20px);
      overflow-y: auto;
      padding: 10px;
    }
  }
}
</style>
src/views/simulation/testSimulation/index.vue
New file
@@ -0,0 +1,238 @@
<template>
  <div class="simulation-index">
    <div class="flex ai-c">
      <el-select v-model="aircraftActive" placeholder="Select" style="width: 140px">
        <el-option
          v-for="item in aircraftList"
          :key="item.id"
          :label="item.name"
          :value="item.id"
        />
      </el-select>
      <ul class="flex tabs">
        <li
          v-for="item in modelTypeList"
          :key="item.id"
          @click="handleClick(item)"
          :class="item.id == modelTypeActive ? 'activeItem' : 'item'"
        >
          {{ item.name }}
        </li>
      </ul>
    </div>
    <div class="page-box">
      <div class="search">
        <el-input
          v-model="searchValue"
          style="width: 400px"
          placeholder="请输入搜索关键字"
        >
          <template #suffix>
            <el-icon class="el-input__icon"><search /></el-icon>
          </template>
        </el-input>
      </div>
      <div class="list">
        <div class="model-body" v-loading="listLoading">
          <el-row :gutter="20" v-if="modelDataList.length > 0">
            <el-col
              :span="6"
              v-for="(item, index) in modelDataList"
              :key="index"
            >
              <div class="model-body-box">
                <div class="model-img">
                  <img :src="item.icon" alt="" />
                </div>
                <div class="model-info">
                  <h1 class="model-title" :title="item.name">
                    {{ item.name }}
                  </h1>
                  <p class="flex jc-sb">
                    <span class="attribute hover" @click="gotoDetail(item)">属性</span>
                    <span class="report hover" @click="gotoReport(item)">测试报告</span>
                    <span class="simulation hover" @click="gotoSimulation(item)">仿真</span>
                  </p>
                </div>
              </div>
            </el-col>
          </el-row>
          <div v-if="modelDataList.length == 0">
            <el-empty :image-size="140" />
          </div>
        </div>
      </div>
    </div>
  </div>
  <el-dialog
    v-model="detailDialogVisible"
    title="属性"
    width="500"
    :before-close="handleClose"
  >
    <div>
      <div>名称:巡视器整模型</div>
      <div>尺寸:巡视器整模型</div>
    </div>
  </el-dialog>
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { useRouter, useRoute } from 'vue-router'
const router = useRouter()
const route = useRoute()
const aircraftList = ref([]);
const aircraftActive = ref('1')
const modelTypeList = ref([
  {
    name: "着陆器",
    id: "2",
  },
  {
    name: "巡视器",
    id: "3",
  },
  {
    name: "飞跃器",
    id: "4",
  },
]);
const modelTypeActive = ref("3");
const searchValue = ref();
const modelDataList = ref([]);
const listLoading = ref(false);
const detailDialogVisible = ref(false)
onMounted(() => {
  getAircraftList();
  getModelData();
});
const getAircraftList = () => {
  let list = [
    {
      name: "嫦娥七号",
      id: "1",
    },
    {
      name: "其他型号",
      id: "2",
    },
  ];
  aircraftList.value = list;
};
const handleClick = (item) => {
  modelTypeActive.value = item.id
};
const getModelData = () => {
  listLoading.value = true;
  let list = [
    {
      name: "巡视器整模型",
      icon: "",
      id: "1",
    },
    {
      name: "天线",
      icon: "",
      id: "2",
    },
    {
      name: "太阳翼",
      icon: "",
      id: "3",
    },
  ];
  modelDataList.value = list;
  listLoading.value = false;
};
//查看属性
const gotoDetail = () => {
  detailDialogVisible.value = true
};
const handleClose = () =>{
  detailDialogVisible.value = false
}
//查看测试报告
const gotoReport = (item) => {
  router.push({
    name: 'testReport',
    query: {
      id: item.id
    }
  })
};
//打开仿真
const gotoSimulation = (item) => {
  router.push({
    name: 'testSimulation-detail',
    query: {
      id: item.id
    }
  })
};
</script>
<style lang="less" scoped>
.simulation-index {
  padding: 20px;
}
.tabs{
  margin-left: 40px;
  li{
    width:60px;
    text-align: center;
    padding: 5px 0;
    margin:0 15px;
    cursor: pointer;
  }
  .activeItem{
    border-bottom:2px solid #1890ff;
  }
}
.page-box{
  margin-top: 20px;
}
.list {
  margin-top: 20px;
  .model-body-box {
    border: 1px solid #f1f1f1;
    .model-img {
      height: 240px;
      img {
        width: 100%;
        height: 100%;
        object-fit: contain;
      }
    }
    .model-info {
      height: 80px;
      padding: 20px;
      .model-title {
        font-size: 16px;
      }
      p {
        line-height: 30px;
        font-size: 16px;
      }
      .attribute {
        color: #1890ff;
      }
      .report {
        color: #1fbc1f;
      }
      .simulation {
        color: #ee1818;
      }
    }
  }
}
</style>
src/views/simulation/testSimulation/testReport.vue
New file
@@ -0,0 +1,130 @@
<template>
  <div class="permission-manage">
    <div class="titleBox">
      <div class="name">
        <span>{{ name }}测试报告</span>
      </div>
      <div class="back"><el-icon><ArrowLeftBold /></el-icon>返回</div>
    </div>
    <div class="page-box">
      <div class="search flex">
        <el-date-picker
        v-model="testTime"
        type="date"
        placeholder="选择日期"
      />
        <el-input
          v-model="searchValue"
          placeholder="请输入搜索关键字"
          class="searchInput"
        >
          <template #suffix>
            <el-icon class="el-input__icon"><search /></el-icon>
          </template>
        </el-input>
      </div>
      <div class="list">
        <div>
          <el-table :data="tableData" border :default-sort="{ prop: 'date', order: 'descending' }" style="width: 100%">
            <el-table-column prop="index" label="序号" width="60"/>
            <el-table-column prop="name" label="测试名称" />
            <el-table-column prop="model" label="测试模型" />
            <el-table-column prop="time" label="测试时间" sortable />
            <el-table-column prop="operator" label="测试人"/>
            <el-table-column label="操作">
              <template #default="scope">
                <el-button
                  size="small"
                  @click="getDetail(scope.row)"
                >
                  查看
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
const name = ref('飞跃器整模型')
const testTime = ref()
const searchValue = ref()
const tableData = ref([])
onMounted(() => {
  getReportData();
});
const getReportData =()=>{
  let list=[
    {
      index: 1,
      name:'',
      model:'',
      time:'',
      operator:'',
    },
    {
      index: 2,
      name:'',
      model:'',
      time:'',
      operator:'',
    },
    {
      index: 3,
      name:'',
      model:'',
      time:'',
      operator:'',
    },
  ]
  tableData.value = list
}
const getDetail =(row)=>{
}
</script>
<style lang="less" scoped>
.testReport {
  padding: 20px;
}
.titleBox{
  height:36px;
  line-height: 36px;
  background:#409eff;
  position: relative;
  .name{
    text-align:center;
  }
  .back{
    position:absolute;
    left:10px;
    top: 0;
    display: flex;
    align-items: center;
    color:#ffffff;
  }
}
.page-box{
  padding: 20px;
  .searchInput{
    width:220px;
    margin-left:20px;
  }
  .list{
    margin-top:20px;
  }
}
</style>
src/views/system/User.vue
File was deleted
src/views/system/index.vue
New file
@@ -0,0 +1,16 @@
<template>
  <div class="pageContainer">
    <div class="menuBox">
      <treeMenu :menuItem="menuItem"/>
    </div>
    <div class="contentBox"><RouterView /></div>
  </div>
</template>
<script setup lang="ts">
import { ref} from "vue";
import treeMenu from "@/components/treeMenu.vue";
const menuItem = ref('systemManage')
</script>
<style lang="less" scoped></style>
src/views/system/roleManage.vue
New file
@@ -0,0 +1,166 @@
<template>
  <div class="user-manage">
    <div>
      <ul class="flex tabs">
        <li
          v-for="item in tabList"
          :key="item.value"
          @click="handleClick(item)"
          :class="item.value == tabActive ? 'activeItem' : 'item'"
        >
          {{ item.lable }}
        </li>
      </ul>
    </div>
    <div class="list">
      <div>
        <el-tree
          :data="dataList"
          show-checkbox
          node-key="id"
          default-expand-all
          :props="defaultProps"
        />
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
const tabList = ref([
  {
    lable:'菜单/功能访问权限',
    value:'menu'
  },
  {
    lable:'模型访问权限',
    value:'model'
  }
])
const tabActive = ref('menu')
const dataList = ref([])
onMounted(() => {
  getData();
});
const defaultProps = {
  children: 'children',
  label: 'name',
}
const getData = () =>{
  let list = [
    {
      name:'模型管理',
      sysType:'cmsFolder',
      productLinkPath:'111',
      children:[
        {
          name:'新增型号',
          sysType:'cmsItem',
          productLinkPath:'211',
        },
        {
          name:'编辑型号',
          sysType:'cmsItem',
          productLinkPath:'212',
        },
        {
          name:'删除型号',
          sysType:'cmsItem',
          productLinkPath:'213',
        },
        {
          name:'新增模型',
          sysType:'cmsItem',
          productLinkPath:'214',
        },{
          name:'删除模型',
          sysType:'cmsItem',
          productLinkPath:'215',
        },{
          name:'删除模型',
          sysType:'cmsItem',
          productLinkPath:'216',
        }
      ]
    },
    {
      name:'可视化仿真',
      sysType:'cmsFolder',
      productLinkPath:'112',
      children:[
        {
          name:'测试仿真',
          sysType:'cmsFolder',
          productLinkPath:'221',
          children:[
            {
              name:'检索模型',
              sysType:'cmsItem',
              productLinkPath:'231',
            },
            {
              name:'模型预览',
              sysType:'cmsItem',
              productLinkPath:'232',
            },
            {
              name:'模型属性查看',
              sysType:'cmsItem',
              productLinkPath:'233',
            },
            {
              name:'模型仿真',
              sysType:'cmsItem',
              productLinkPath:'234',
            },
            {
              name:'测试报告',
              sysType:'cmsItem',
              productLinkPath:'235',
            },
          ]
        },
        {
          name:'测试报告',
          sysType:'cmsFolder',
          productLinkPath:'221',
        },
      ]
    }
  ]
  dataList.value = list
}
const handleClick = (item) => {
  tabActive.value = item.value
};
</script>
<style lang="less" scoped>
.user-manage {
  padding: 20px;
}
.tabs{
  li{
    width:140px;
    text-align: center;
    padding: 5px 0;
    margin:0 15px;
    cursor: pointer;
  }
  .activeItem{
    border-bottom:2px solid #1890ff;
  }
}
</style>
src/views/system/userManage.vue
New file
@@ -0,0 +1,176 @@
<template>
  <div class="user-manage">
    <div class="flex jc-sb ai-c">
      <div class="addBox">
        <el-icon><Plus /></el-icon>
        <span>新建</span>
      </div>
      <div class="search">
        <el-input
          v-model="searchValue"
          style="width: 400px"
          placeholder="请输入搜索关键字"
        >
          <template #suffix>
            <el-icon class="el-input__icon"><search /></el-icon>
          </template>
        </el-input>
      </div>
    </div>
    <div class="list">
      <el-table
        :data="tableData"
        row-key="id"
        border
        style="width: 100%"
        class="roverTable"
      >
        <el-table-column prop="index" label="序号" width="60" />
        <el-table-column prop="userName" label="用户姓名" />
        <el-table-column prop="name" label="用户名" />
        <el-table-column prop="state" label="状态" />
        <el-table-column prop="role" label="类型" />
        <el-table-column prop="creatTime" label="创建时间" />
        <el-table-column label="操作"  width="220" >
          <template #default="scope">
            <el-button size="small" @click="update(scope.row)">
              编辑
            </el-button>
            <el-button size="small" @click="goDisable(scope.row)">
              禁用
            </el-button>
            <el-button size="small" @click="goDelete(scope.row)">
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div class="rover-pagination-block">
      <el-pagination
        v-model:current-page="currentPage"
        :page-size="pageSize"
        :background="background"
        layout="total, prev, pager, next"
        :total="100"
        @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { ElMessage, ElMessageBox } from 'element-plus'
const searchValue = ref();
const tableData = ref([]);
// 分页
const currentPage = ref(4);
const pageSize = ref(100);
const background = ref(true);
onMounted(() => {
  getUserData();
});
const getUserData =() =>{
  let list=[
    {
      index: 1,
      userName:'',
      name:'',
      state:'',
      role:'',
      creatTime:'',
    },
    {
      index: 2,
      userName:'',
      name:'',
      state:'',
      role:'',
      creatTime:'',
    },
    {
      index: 3,
      userName:'',
      name:'',
      state:'',
      role:'',
      creatTime:'',
    },
  ]
  tableData.value = list
}
const handleCurrentChange = (val: number) => {
  console.log(`current page: ${val}`);
};
// 编辑
const update = (row) =>{
}
//禁用
const goDisable = (row) =>{
  ElMessageBox.confirm(
    '确定要禁用该用户?',
    'Warning',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )
    .then(() => {
      console.log(row)
    })
    .catch(() => {
    })
}
//删除
const goDelete = () =>{
  ElMessageBox.confirm(
    '确定要删除该用户?',
    'Warning',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )
    .then(() => {
      console.log(row)
    })
    .catch(() => {
    })
}
</script>
<style lang="less" scoped>
.user-manage {
  padding: 20px;
}
.addBox {
  display: flex;
  align-items: center;
  color: #409eff;
}
.list{
  margin-top:20px;
}
.rover-pagination-block {
    height: 60px;
    display: flex;
    justify-content: flex-end;
    background-color: #fff;
    padding: 0 10px;
    box-sizing: border-box;
  }
</style>