Compare commits

...

14 Commits

Author SHA1 Message Date
Dreamglade f6c4ee9011 feat: 同步 master 的 Dockerfile 和 pnpm-lock 配置 4 months ago
Dreamglade 93393410dd 小改一下 4 months ago
Dreamglade c73d294c6e 改了一下版本 4 months ago
Dreamglade 6126dc5f60 pnpm 10.14.0 4 months ago
chenjiale 7fe3d8fa38 Merge pull request 'cjl-dev' (#41) from cjl-dev into master 4 months ago
CJL6015 b12fa64f1e Update build scripts to use tsx and upgrade dependencies 4 months ago
CJL6015 961f103ede update pnpm version in lockfile and Dockerfile to 10.14.0 4 months ago
CJL6015 473ab6502d Merge branch 'master' of http://120.26.116.243:3000/root/alert-front into cjl-dev 4 months ago
chenjiale 28769d1eb1 Merge pull request '保持跟服务器pnpm版本一致' (#40) from Zyq into master 4 months ago
chenjiale b970f44375 Merge pull request 'Zyq' (#39) from Zyq into master 4 months ago
Jiale 99e38cf13d feat: 添加底层模型获取功能并更新相关逻辑 5 months ago
CJL6015 ef628de515 feat: add model editing functionality with transfer component and update pagination 5 months ago
Jiale 41c7f01c93 feat: 添加清除训练结果功能并优化模型信息更新逻辑 5 months ago
Jiale f016fd0f21 feat: 添加测试模型API并更新相关功能 5 months ago
  1. 2
      .vscode/settings.json
  2. 7
      package.json
  3. 294
      pnpm-lock.yaml
  4. 2
      scripts/Dockerfile
  5. 6
      src/api/alert/model/models.ts
  6. 120
      src/views/model/list/step/Step3.vue
  7. 529
      src/views/model/train/index.vue

2
.vscode/settings.json

@ -120,7 +120,7 @@
"source.organizeImports": "never", "source.organizeImports": "never",
"source.fixAll.stylelint": "explicit" "source.fixAll.stylelint": "explicit"
}, },
"editor.defaultFormatter": "stylelint.vscode-stylelint" "editor.defaultFormatter": "octref.vetur"
}, },
"i18n-ally.localesPaths": ["src/locales/lang"], "i18n-ally.localesPaths": ["src/locales/lang"],
"i18n-ally.keystyle": "nested", "i18n-ally.keystyle": "nested",

7
package.json

@ -25,9 +25,9 @@
"serve": "pnpm dev", "serve": "pnpm dev",
"dev": "vite", "dev": "vite",
"front": "vite --mode front", "front": "vite --mode front",
"build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 vite build && esno ./build/script/postBuild.ts", "build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 vite build && tsx ./build/script/postBuild.ts",
"build:test": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode test && esno ./build/script/postBuild.ts", "build:test": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode test && tsx ./build/script/postBuild.ts",
"build:static": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode static && esno ./build/script/postBuild.ts", "build:static": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode static && tsx ./build/script/postBuild.ts",
"build:no-cache": "pnpm store prune && pnpm build", "build:no-cache": "pnpm store prune && pnpm build",
"report": "cross-env REPORT=true pnpm build", "report": "cross-env REPORT=true pnpm build",
"type:check": "vue-tsc --noEmit --skipLibCheck", "type:check": "vue-tsc --noEmit --skipLibCheck",
@ -128,6 +128,7 @@
"stylelint-order": "^6.0.3", "stylelint-order": "^6.0.3",
"stylelint-prettier": "^4.0.2", "stylelint-prettier": "^4.0.2",
"terser": "^5.24.0", "terser": "^5.24.0",
"tsx": "^4.20.3",
"typescript": "^5.2.2", "typescript": "^5.2.2",
"unocss": "^0.57.3", "unocss": "^0.57.3",
"vite": "^4.5.0", "vite": "^4.5.0",

294
pnpm-lock.yaml

@ -78,7 +78,7 @@ importers:
specifier: ^3.2.0 specifier: ^3.2.0
version: 3.2.0(pinia@2.1.7(typescript@5.2.2)(vue@3.3.8(typescript@5.2.2))) version: 3.2.0(pinia@2.1.7(typescript@5.2.2)(vue@3.3.8(typescript@5.2.2)))
pnpm: pnpm:
specifier: ^10.12.1 specifier: ^10.7.0
version: 10.12.1 version: 10.12.1
print-js: print-js:
specifier: ^1.6.0 specifier: ^1.6.0
@ -258,6 +258,9 @@ importers:
terser: terser:
specifier: ^5.24.0 specifier: ^5.24.0
version: 5.24.0 version: 5.24.0
tsx:
specifier: ^4.20.3
version: 4.20.3
typescript: typescript:
specifier: ^5.2.2 specifier: ^5.2.2
version: 5.2.2 version: 5.2.2
@ -1026,138 +1029,294 @@ packages:
resolution: {integrity: sha512-aKUhyn1QI5Ksbqcr3fFJj16p99QdjUxXAEuFst1Z47DRyoiMwivIH9MV/ARcJOCXVjPfjITciej8ZD2O/6qUmw==} resolution: {integrity: sha512-aKUhyn1QI5Ksbqcr3fFJj16p99QdjUxXAEuFst1Z47DRyoiMwivIH9MV/ARcJOCXVjPfjITciej8ZD2O/6qUmw==}
engines: {node: '>=16'} engines: {node: '>=16'}
'@esbuild/aix-ppc64@0.25.8':
resolution: {integrity: sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
'@esbuild/android-arm64@0.18.20': '@esbuild/android-arm64@0.18.20':
resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [arm64] cpu: [arm64]
os: [android] os: [android]
'@esbuild/android-arm64@0.25.8':
resolution: {integrity: sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
'@esbuild/android-arm@0.18.20': '@esbuild/android-arm@0.18.20':
resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [arm] cpu: [arm]
os: [android] os: [android]
'@esbuild/android-arm@0.25.8':
resolution: {integrity: sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
'@esbuild/android-x64@0.18.20': '@esbuild/android-x64@0.18.20':
resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [x64] cpu: [x64]
os: [android] os: [android]
'@esbuild/android-x64@0.25.8':
resolution: {integrity: sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
'@esbuild/darwin-arm64@0.18.20': '@esbuild/darwin-arm64@0.18.20':
resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@esbuild/darwin-arm64@0.25.8':
resolution: {integrity: sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
'@esbuild/darwin-x64@0.18.20': '@esbuild/darwin-x64@0.18.20':
resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@esbuild/darwin-x64@0.25.8':
resolution: {integrity: sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
'@esbuild/freebsd-arm64@0.18.20': '@esbuild/freebsd-arm64@0.18.20':
resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [arm64] cpu: [arm64]
os: [freebsd] os: [freebsd]
'@esbuild/freebsd-arm64@0.25.8':
resolution: {integrity: sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
'@esbuild/freebsd-x64@0.18.20': '@esbuild/freebsd-x64@0.18.20':
resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [x64] cpu: [x64]
os: [freebsd] os: [freebsd]
'@esbuild/freebsd-x64@0.25.8':
resolution: {integrity: sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
'@esbuild/linux-arm64@0.18.20': '@esbuild/linux-arm64@0.18.20':
resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@esbuild/linux-arm64@0.25.8':
resolution: {integrity: sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
'@esbuild/linux-arm@0.18.20': '@esbuild/linux-arm@0.18.20':
resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
'@esbuild/linux-arm@0.25.8':
resolution: {integrity: sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
'@esbuild/linux-ia32@0.18.20': '@esbuild/linux-ia32@0.18.20':
resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [ia32] cpu: [ia32]
os: [linux] os: [linux]
'@esbuild/linux-ia32@0.25.8':
resolution: {integrity: sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
'@esbuild/linux-loong64@0.18.20': '@esbuild/linux-loong64@0.18.20':
resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [loong64] cpu: [loong64]
os: [linux] os: [linux]
'@esbuild/linux-loong64@0.25.8':
resolution: {integrity: sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
'@esbuild/linux-mips64el@0.18.20': '@esbuild/linux-mips64el@0.18.20':
resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [mips64el] cpu: [mips64el]
os: [linux] os: [linux]
'@esbuild/linux-mips64el@0.25.8':
resolution: {integrity: sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
'@esbuild/linux-ppc64@0.18.20': '@esbuild/linux-ppc64@0.18.20':
resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
'@esbuild/linux-ppc64@0.25.8':
resolution: {integrity: sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
'@esbuild/linux-riscv64@0.18.20': '@esbuild/linux-riscv64@0.18.20':
resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
'@esbuild/linux-riscv64@0.25.8':
resolution: {integrity: sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
'@esbuild/linux-s390x@0.18.20': '@esbuild/linux-s390x@0.18.20':
resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
'@esbuild/linux-s390x@0.25.8':
resolution: {integrity: sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
'@esbuild/linux-x64@0.18.20': '@esbuild/linux-x64@0.18.20':
resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@esbuild/linux-x64@0.25.8':
resolution: {integrity: sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
'@esbuild/netbsd-arm64@0.25.8':
resolution: {integrity: sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [netbsd]
'@esbuild/netbsd-x64@0.18.20': '@esbuild/netbsd-x64@0.18.20':
resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [x64] cpu: [x64]
os: [netbsd] os: [netbsd]
'@esbuild/netbsd-x64@0.25.8':
resolution: {integrity: sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
'@esbuild/openbsd-arm64@0.25.8':
resolution: {integrity: sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
'@esbuild/openbsd-x64@0.18.20': '@esbuild/openbsd-x64@0.18.20':
resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [x64] cpu: [x64]
os: [openbsd] os: [openbsd]
'@esbuild/openbsd-x64@0.25.8':
resolution: {integrity: sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
'@esbuild/openharmony-arm64@0.25.8':
resolution: {integrity: sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openharmony]
'@esbuild/sunos-x64@0.18.20': '@esbuild/sunos-x64@0.18.20':
resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [x64] cpu: [x64]
os: [sunos] os: [sunos]
'@esbuild/sunos-x64@0.25.8':
resolution: {integrity: sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
'@esbuild/win32-arm64@0.18.20': '@esbuild/win32-arm64@0.18.20':
resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@esbuild/win32-arm64@0.25.8':
resolution: {integrity: sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
'@esbuild/win32-ia32@0.18.20': '@esbuild/win32-ia32@0.18.20':
resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [ia32] cpu: [ia32]
os: [win32] os: [win32]
'@esbuild/win32-ia32@0.25.8':
resolution: {integrity: sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
'@esbuild/win32-x64@0.18.20': '@esbuild/win32-x64@0.18.20':
resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@esbuild/win32-x64@0.25.8':
resolution: {integrity: sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
'@eslint-community/eslint-utils@4.4.0': '@eslint-community/eslint-utils@4.4.0':
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@ -2716,6 +2875,11 @@ packages:
engines: {node: '>=12'} engines: {node: '>=12'}
hasBin: true hasBin: true
esbuild@0.25.8:
resolution: {integrity: sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==}
engines: {node: '>=18'}
hasBin: true
escalade@3.1.1: escalade@3.1.1:
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -3118,6 +3282,9 @@ packages:
resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
get-tsconfig@4.10.1:
resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==}
get-tsconfig@4.7.2: get-tsconfig@4.7.2:
resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==} resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==}
@ -4765,6 +4932,7 @@ packages:
source-map@0.8.0-beta.0: source-map@0.8.0-beta.0:
resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
deprecated: The work that was done in this beta branch won't be included in future versions
sourcemap-codec@1.4.8: sourcemap-codec@1.4.8:
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
@ -5078,8 +5246,8 @@ packages:
tslib@2.6.2: tslib@2.6.2:
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
tsx@4.1.1: tsx@4.20.3:
resolution: {integrity: sha512-zyPn5BFMB0TB5kMLbYPNx4x/oL/oSlaecdKCv6WeJ0TeSEfx8RTJWjuB5TZ2dSewktgfBsBO/HNA9mrMWqLXMA==} resolution: {integrity: sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==}
engines: {node: '>=18.0.0'} engines: {node: '>=18.0.0'}
hasBin: true hasBin: true
@ -6508,72 +6676,150 @@ snapshots:
esquery: 1.5.0 esquery: 1.5.0
jsdoc-type-pratt-parser: 4.0.0 jsdoc-type-pratt-parser: 4.0.0
'@esbuild/aix-ppc64@0.25.8':
optional: true
'@esbuild/android-arm64@0.18.20': '@esbuild/android-arm64@0.18.20':
optional: true optional: true
'@esbuild/android-arm64@0.25.8':
optional: true
'@esbuild/android-arm@0.18.20': '@esbuild/android-arm@0.18.20':
optional: true optional: true
'@esbuild/android-arm@0.25.8':
optional: true
'@esbuild/android-x64@0.18.20': '@esbuild/android-x64@0.18.20':
optional: true optional: true
'@esbuild/android-x64@0.25.8':
optional: true
'@esbuild/darwin-arm64@0.18.20': '@esbuild/darwin-arm64@0.18.20':
optional: true optional: true
'@esbuild/darwin-arm64@0.25.8':
optional: true
'@esbuild/darwin-x64@0.18.20': '@esbuild/darwin-x64@0.18.20':
optional: true optional: true
'@esbuild/darwin-x64@0.25.8':
optional: true
'@esbuild/freebsd-arm64@0.18.20': '@esbuild/freebsd-arm64@0.18.20':
optional: true optional: true
'@esbuild/freebsd-arm64@0.25.8':
optional: true
'@esbuild/freebsd-x64@0.18.20': '@esbuild/freebsd-x64@0.18.20':
optional: true optional: true
'@esbuild/freebsd-x64@0.25.8':
optional: true
'@esbuild/linux-arm64@0.18.20': '@esbuild/linux-arm64@0.18.20':
optional: true optional: true
'@esbuild/linux-arm64@0.25.8':
optional: true
'@esbuild/linux-arm@0.18.20': '@esbuild/linux-arm@0.18.20':
optional: true optional: true
'@esbuild/linux-arm@0.25.8':
optional: true
'@esbuild/linux-ia32@0.18.20': '@esbuild/linux-ia32@0.18.20':
optional: true optional: true
'@esbuild/linux-ia32@0.25.8':
optional: true
'@esbuild/linux-loong64@0.18.20': '@esbuild/linux-loong64@0.18.20':
optional: true optional: true
'@esbuild/linux-loong64@0.25.8':
optional: true
'@esbuild/linux-mips64el@0.18.20': '@esbuild/linux-mips64el@0.18.20':
optional: true optional: true
'@esbuild/linux-mips64el@0.25.8':
optional: true
'@esbuild/linux-ppc64@0.18.20': '@esbuild/linux-ppc64@0.18.20':
optional: true optional: true
'@esbuild/linux-ppc64@0.25.8':
optional: true
'@esbuild/linux-riscv64@0.18.20': '@esbuild/linux-riscv64@0.18.20':
optional: true optional: true
'@esbuild/linux-riscv64@0.25.8':
optional: true
'@esbuild/linux-s390x@0.18.20': '@esbuild/linux-s390x@0.18.20':
optional: true optional: true
'@esbuild/linux-s390x@0.25.8':
optional: true
'@esbuild/linux-x64@0.18.20': '@esbuild/linux-x64@0.18.20':
optional: true optional: true
'@esbuild/linux-x64@0.25.8':
optional: true
'@esbuild/netbsd-arm64@0.25.8':
optional: true
'@esbuild/netbsd-x64@0.18.20': '@esbuild/netbsd-x64@0.18.20':
optional: true optional: true
'@esbuild/netbsd-x64@0.25.8':
optional: true
'@esbuild/openbsd-arm64@0.25.8':
optional: true
'@esbuild/openbsd-x64@0.18.20': '@esbuild/openbsd-x64@0.18.20':
optional: true optional: true
'@esbuild/openbsd-x64@0.25.8':
optional: true
'@esbuild/openharmony-arm64@0.25.8':
optional: true
'@esbuild/sunos-x64@0.18.20': '@esbuild/sunos-x64@0.18.20':
optional: true optional: true
'@esbuild/sunos-x64@0.25.8':
optional: true
'@esbuild/win32-arm64@0.18.20': '@esbuild/win32-arm64@0.18.20':
optional: true optional: true
'@esbuild/win32-arm64@0.25.8':
optional: true
'@esbuild/win32-ia32@0.18.20': '@esbuild/win32-ia32@0.18.20':
optional: true optional: true
'@esbuild/win32-ia32@0.25.8':
optional: true
'@esbuild/win32-x64@0.18.20': '@esbuild/win32-x64@0.18.20':
optional: true optional: true
'@esbuild/win32-x64@0.25.8':
optional: true
'@eslint-community/eslint-utils@4.4.0(eslint@8.53.0)': '@eslint-community/eslint-utils@4.4.0(eslint@8.53.0)':
dependencies: dependencies:
eslint: 8.53.0 eslint: 8.53.0
@ -8440,6 +8686,35 @@ snapshots:
'@esbuild/win32-ia32': 0.18.20 '@esbuild/win32-ia32': 0.18.20
'@esbuild/win32-x64': 0.18.20 '@esbuild/win32-x64': 0.18.20
esbuild@0.25.8:
optionalDependencies:
'@esbuild/aix-ppc64': 0.25.8
'@esbuild/android-arm': 0.25.8
'@esbuild/android-arm64': 0.25.8
'@esbuild/android-x64': 0.25.8
'@esbuild/darwin-arm64': 0.25.8
'@esbuild/darwin-x64': 0.25.8
'@esbuild/freebsd-arm64': 0.25.8
'@esbuild/freebsd-x64': 0.25.8
'@esbuild/linux-arm': 0.25.8
'@esbuild/linux-arm64': 0.25.8
'@esbuild/linux-ia32': 0.25.8
'@esbuild/linux-loong64': 0.25.8
'@esbuild/linux-mips64el': 0.25.8
'@esbuild/linux-ppc64': 0.25.8
'@esbuild/linux-riscv64': 0.25.8
'@esbuild/linux-s390x': 0.25.8
'@esbuild/linux-x64': 0.25.8
'@esbuild/netbsd-arm64': 0.25.8
'@esbuild/netbsd-x64': 0.25.8
'@esbuild/openbsd-arm64': 0.25.8
'@esbuild/openbsd-x64': 0.25.8
'@esbuild/openharmony-arm64': 0.25.8
'@esbuild/sunos-x64': 0.25.8
'@esbuild/win32-arm64': 0.25.8
'@esbuild/win32-ia32': 0.25.8
'@esbuild/win32-x64': 0.25.8
escalade@3.1.1: {} escalade@3.1.1: {}
escape-string-regexp@1.0.5: {} escape-string-regexp@1.0.5: {}
@ -8681,7 +8956,7 @@ snapshots:
esno@4.0.0: esno@4.0.0:
dependencies: dependencies:
tsx: 4.1.1 tsx: 4.20.3
espree@9.6.1: espree@9.6.1:
dependencies: dependencies:
@ -8945,6 +9220,10 @@ snapshots:
call-bind: 1.0.5 call-bind: 1.0.5
get-intrinsic: 1.2.2 get-intrinsic: 1.2.2
get-tsconfig@4.10.1:
dependencies:
resolve-pkg-maps: 1.0.0
get-tsconfig@4.7.2: get-tsconfig@4.7.2:
dependencies: dependencies:
resolve-pkg-maps: 1.0.0 resolve-pkg-maps: 1.0.0
@ -10958,11 +11237,10 @@ snapshots:
tslib@2.6.2: {} tslib@2.6.2: {}
tsx@4.1.1: tsx@4.20.3:
dependencies: dependencies:
esbuild: 0.18.20 esbuild: 0.25.8
get-tsconfig: 4.7.2 get-tsconfig: 4.10.1
source-map-support: 0.5.21
optionalDependencies: optionalDependencies:
fsevents: 2.3.3 fsevents: 2.3.3

2
scripts/Dockerfile

@ -7,7 +7,7 @@ ENV PATH="$PNPM_HOME:$PATH"
ENV NODE_OPTIONS=--max-old-space-size=8192 ENV NODE_OPTIONS=--max-old-space-size=8192
ENV TZ=Asia/Shanghai ENV TZ=Asia/Shanghai
RUN npm install -g pnpm@10.7.0 RUN npm install -g pnpm@10.14.0
WORKDIR /app WORKDIR /app
COPY . . COPY . .

6
src/api/alert/model/models.ts

@ -9,6 +9,8 @@ enum Api {
CALCULATE_BACK = '/alert/model/data/calculate/', CALCULATE_BACK = '/alert/model/data/calculate/',
OPTIMISTIC = '/alert/optimistic', OPTIMISTIC = '/alert/optimistic',
TRAIN_MODEL = '/alert/model/train', TRAIN_MODEL = '/alert/model/train',
TEST_MODEL = '/alert/model/test',
BOTTOM_MODEL = '/alert/model/bottom/',
} }
export function modelCardListApi(params?: ModelQueryParams) { export function modelCardListApi(params?: ModelQueryParams) {
return defHttp.get<ModelCardItem[]>({ url: Api.MODEL_CARD_LIST, params }) return defHttp.get<ModelCardItem[]>({ url: Api.MODEL_CARD_LIST, params })
@ -34,3 +36,7 @@ export function calculateBackApi(id: any, params: any) {
export const getOptimisticApi = (params: any) => defHttp.get<any>({ url: Api.OPTIMISTIC, params }) export const getOptimisticApi = (params: any) => defHttp.get<any>({ url: Api.OPTIMISTIC, params })
export const trainModelApi = (params: any) => defHttp.post<any>({ url: Api.TRAIN_MODEL, data: params }) export const trainModelApi = (params: any) => defHttp.post<any>({ url: Api.TRAIN_MODEL, data: params })
export const testModelApi = (params: any) => defHttp.post<any>({ url: Api.TEST_MODEL, data: params })
export const bottomModelApi = (id: any) => defHttp.post<any>({ url: Api.BOTTOM_MODEL + id })

120
src/views/model/list/step/Step3.vue

@ -1,14 +1,14 @@
<script lang="ts"> <script lang="ts">
import type { PropType } from 'vue' import type { PropType } from "vue";
import { computed, defineComponent, ref, toRaw, unref } from 'vue' import { computed, defineComponent, ref, toRaw, unref } from "vue";
import { Alert, Descriptions, Divider } from 'ant-design-vue' import { Alert, Descriptions, Divider } from "ant-design-vue";
import type { Recordable } from '@vben/types' import type { Recordable } from "@vben/types";
import { useDebounceFn } from '@vueuse/core' import { useDebounceFn } from "@vueuse/core";
import { step3Schemas } from './data' import { step3Schemas } from "./data";
import { ApiSelect, BasicForm, useForm } from '@/components/Form' import { ApiSelect, BasicForm, useForm } from "@/components/Form";
import { Button } from '@/components/Button' import { Button } from "@/components/Button";
import { pointListApi } from '@/api/alert/model/select' import { pointListApi } from "@/api/alert/model/select";
import { modelSaveApi } from '@/api/alert/model/models' import { modelSaveApi } from "@/api/alert/model/models";
export default defineComponent({ export default defineComponent({
components: { components: {
@ -28,114 +28,118 @@ export default defineComponent({
type: Number, type: Number,
}, },
}, },
emits: ['next', 'prev'], emits: ["next", "prev"],
setup(props, { emit }) { setup(props, { emit }) {
const [register, { appendSchemaByField, removeSchemaByField, validate, setProps }] = useForm({ const [
register,
{ appendSchemaByField, removeSchemaByField, validate, setProps },
] = useForm({
labelWidth: 100, labelWidth: 100,
schemas: step3Schemas, schemas: step3Schemas,
actionColOptions: { actionColOptions: {
span: 14, span: 14,
}, },
resetButtonOptions: { resetButtonOptions: {
text: '上一步', text: "上一步",
}, },
submitButtonOptions: { submitButtonOptions: {
text: '创建模型', text: "创建模型",
}, },
resetFunc: customResetFunc, resetFunc: customResetFunc,
submitFunc: customSubmitFunc, submitFunc: customSubmitFunc,
}) });
const n = ref(4) const n = ref(4);
function add() { function add() {
appendSchemaByField( appendSchemaByField(
[ [
{ {
field: `point${n.value}`, field: `point${n.value}`,
component: 'Input', component: "Input",
label: `参数${n.value}`, label: `参数${n.value}`,
required: true, required: true,
slot: 'remoteSearch', slot: "remoteSearch",
colProps: { colProps: {
span: 23, span: 23,
}, },
}, },
{ {
field: `${n.value}`, field: `${n.value}`,
component: 'Input', component: "Input",
label: ' ', label: " ",
slot: 'add', slot: "add",
colProps: { colProps: {
span: 1, span: 1,
}, },
}, },
], ],
'', ""
) );
n.value++ n.value++;
} }
function del(field) { function del(field) {
removeSchemaByField([`point${field}`, `${field}`]) removeSchemaByField([`point${field}`, `${field}`]);
n.value-- n.value--;
} }
async function customResetFunc() { async function customResetFunc() {
emit('prev') emit("prev");
} }
async function customSubmitFunc() { async function customSubmitFunc() {
try { try {
const values = await validate() const values = await validate();
const pointInfo = [] const pointInfo = [];
for (const key in values) { for (const key in values) {
if (key.startsWith('point')) { if (key.startsWith("point")) {
const point = values[key].split('|') const point = values[key].split("|");
const p = { const p = {
description: point[0], description: point[0],
pointId: point[1], pointId: point[1],
unit: point[2], unit: point[2],
Lower: point[3], Lower: point[3],
Upper: point[4], Upper: point[4],
} dead: true,
pointInfo.push(p) limit: false,
};
pointInfo.push(p);
} }
} }
const modelInfo = toRaw(props.beforeData) const modelInfo = toRaw(props.beforeData);
modelInfo.pointInfo = pointInfo modelInfo.pointInfo = pointInfo;
const modelId = await modelSaveApi(modelInfo) const modelId = await modelSaveApi(modelInfo);
setProps({ setProps({
submitButtonOptions: { submitButtonOptions: {
loading: true, loading: true,
}, },
}) });
setTimeout(() => { setTimeout(() => {
setProps({ setProps({
submitButtonOptions: { submitButtonOptions: {
loading: false, loading: false,
}, },
}) });
emit('next', modelId) emit("next", modelId);
}, 1500) }, 1500);
} } catch (error) {
catch (error) { console.error(error);
console.error(error)
} }
} }
const keyword = ref<string>('') const keyword = ref<string>("");
const searchParams = computed<Recordable>(() => { const searchParams = computed<Recordable>(() => {
return { keyword: unref(keyword) } return { keyword: unref(keyword) };
}) });
function onSearch(value: string) { function onSearch(value: string) {
keyword.value = value keyword.value = value;
} }
async function searchPoint(params) { async function searchPoint(params) {
if (params.keyword) { if (params.keyword) {
const data = await pointListApi(params) const data = await pointListApi(params);
return data return data;
} }
} }
@ -147,11 +151,11 @@ export default defineComponent({
searchParams, searchParams,
searchPoint, searchPoint,
handleReset: () => { handleReset: () => {
keyword.value = '' keyword.value = "";
}, },
} };
}, },
}) });
</script> </script>
<template> <template>
@ -190,20 +194,16 @@ export default defineComponent({
/> />
</template> </template>
<template #add="{ field }"> <template #add="{ field }">
<Button v-if="Number(field) === 0" @click="add"> <Button v-if="Number(field) === 0" @click="add"> + </Button>
+ <Button v-if="field > 0" @click="del(field)"> - </Button>
</Button>
<Button v-if="field > 0" @click="del(field)">
-
</Button>
</template> </template>
</BasicForm> </BasicForm>
</div> </div>
</template> </template>
<style lang="less" scoped> <style lang="less" scoped>
.step3 { .step3 {
width: 450px; width: 450px;
margin: 0 auto; margin: 0 auto;
} }
</style> </style>

529
src/views/model/train/index.vue

@ -3,12 +3,13 @@ import type { ComponentPublicInstance } from 'vue'
import type { Dayjs } from 'dayjs' import type { Dayjs } from 'dayjs'
import { debounce } from 'lodash-es' import { debounce } from 'lodash-es'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { computed, defineComponent, onMounted, ref, watch } from 'vue' import { computed, defineComponent, onMounted, ref, toRaw, watch } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { import {
Button, Button,
Card, Card,
Checkbox, Checkbox,
Col,
Descriptions, Descriptions,
Divider, Divider,
Form, Form,
@ -17,17 +18,27 @@ import {
InputNumber, InputNumber,
Modal, Modal,
RangePicker, RangePicker,
Row,
Spin,
Steps, Steps,
Tabs, Tabs,
Transfer,
} from 'ant-design-vue' } from 'ant-design-vue'
import VueECharts from 'vue-echarts' import VueECharts from 'vue-echarts'
import { func } from 'vue-types'
import { pointTableSchema, sampleInfoTableSchema } from './data' import { pointTableSchema, sampleInfoTableSchema } from './data'
import { BasicTable, useTable } from '@/components/Table' import { BasicTable, useTable } from '@/components/Table'
import { PageWrapper } from '@/components/Page' import { PageWrapper } from '@/components/Page'
import { modelInfoApi, trainModelApi, updateModelInfo } from '@/api/alert/model/models' import {
bottomModelApi,
modelInfoApi,
testModelApi,
trainModelApi,
updateModelInfo,
} from '@/api/alert/model/models'
import { getExaHistorys } from '@/api/alert/exa/index' import { getExaHistorys } from '@/api/alert/exa/index'
import { useECharts } from '@/hooks/web/useECharts' import { useECharts } from '@/hooks/web/useECharts'
import { useMessage } from '@/hooks/web/useMessage'
import { pointListApi } from '@/api/alert/model/select'
export default defineComponent({ export default defineComponent({
components: { components: {
@ -50,23 +61,30 @@ export default defineComponent({
ACheckbox: Checkbox, ACheckbox: Checkbox,
AInputNumber: InputNumber, AInputNumber: InputNumber,
AButton: Button, AButton: Button,
ASpin: Spin,
ATransfer: Transfer,
ARow: Row,
ACol: Col,
}, },
setup() { setup() {
const { createMessage } = useMessage()
const route = useRoute() const route = useRoute()
const id = route.params.id const id = route.params.id
const model = ref(null) const model = ref(null)
const brushActivated = ref<Set<number>>(new Set()) const brushActivated = ref<Set<number>>(new Set())
const spinning = ref(false)
let trainTimeCopy = ''
const fetchModelInfo = async () => { const fetchModelInfo = async () => {
const modelInfo = await modelInfoApi(id) const modelInfo = await modelInfoApi(id)
model.value = modelInfo model.value = modelInfo
trainTimeCopy = JSON.stringify(model.value.trainTime)
getHistory() getHistory()
} }
const pointData = computed(() => model.value?.pointInfo || []) const pointData = computed(() => model.value?.pointInfo || [])
const [pointTable] = useTable({ const [pointTable] = useTable({
columns: pointTableSchema, columns: pointTableSchema,
pagination: false, pagination: true,
dataSource: pointData, dataSource: pointData,
scroll: { y: 300 }, scroll: { y: 300 },
}) })
@ -74,7 +92,6 @@ export default defineComponent({
const trainTime = computed(() => model.value?.trainTime || []) const trainTime = computed(() => model.value?.trainTime || [])
const [trainTimeTable] = useTable({ const [trainTimeTable] = useTable({
columns: sampleInfoTableSchema, columns: sampleInfoTableSchema,
pagination: false,
dataSource: trainTime, dataSource: trainTime,
scroll: { y: 300 }, scroll: { y: 300 },
}) })
@ -83,7 +100,10 @@ export default defineComponent({
type RangeValue = [Dayjs, Dayjs] type RangeValue = [Dayjs, Dayjs]
const currentDate: Dayjs = dayjs() const currentDate: Dayjs = dayjs()
const lastMonthDate: Dayjs = currentDate.subtract(1, 'day') const lastMonthDate: Dayjs = currentDate.subtract(1, 'day')
const rangeValue: RangeValue = [dayjs('2023-10-28 00:00:00'), dayjs('2023-10-28 23:59:59')] const rangeValue: RangeValue = [
lastMonthDate,
currentDate,
]
const historyTime = ref<RangeValue>(rangeValue) const historyTime = ref<RangeValue>(rangeValue)
const historyList = ref<any[]>([]) const historyList = ref<any[]>([])
const echartsRefs = ref<any[]>([]) const echartsRefs = ref<any[]>([])
@ -91,33 +111,103 @@ export default defineComponent({
async function getHistory() { async function getHistory() {
if (!historyTime.value) if (!historyTime.value)
return return
spinning.value = true
if (model.value.para) {
getTestData()
}
else {
const params = { const params = {
startTime: historyTime.value[0].format('YYYY-MM-DD HH:mm:ss'), startTime: historyTime.value[0].format('YYYY-MM-DD HH:mm:ss'),
endTime: historyTime.value[1].format('YYYY-MM-DD HH:mm:ss'), endTime: historyTime.value[1].format('YYYY-MM-DD HH:mm:ss'),
itemName: model.value?.pointInfo.map(item => item.pointId).join(','), itemName: model.value?.pointInfo
.map(item => item.pointId)
.join(','),
interval: model.value.sampling,
} }
console.log(params)
const history = await getExaHistorys(params) const history = await getExaHistorys(params)
historyList.value = history.map((item, index) => { historyList.value = history.map((item, index) => {
const point = model.value?.pointInfo[index] const point = model.value?.pointInfo[index]
return { return {
data: item, data: [item],
name: `${index}.${point?.description}(${point?.pointId})`, name: `${index + 1}.${point?.description}(${point?.pointId})`,
} }
}) })
echartsRefs.value = Array.from({ length: historyList.value.length }) echartsRefs.value = Array.from({ length: historyList.value.length })
console.log('echartsRefs', echartsRefs.value)
brushActivated.value = new Set() brushActivated.value = new Set()
} }
function getOption(item: any) { spinning.value = false
console.log('getOption', item) }
async function getTestData() {
const params = {
Model_id: 530,
version: model.value?.Cur_Version ? model.value?.Cur_Version : 'v-test',
Test_Data: {
time: historyTime.value
.map(t => dayjs(t).format('YYYY-MM-DD HH:mm:ss'))
.join(','),
points: model.value.pointInfo.map(t => t.pointId).join(','),
interval: model.value.sampling * 1000,
},
}
const result = await testModelApi(params)
const sampleData = result.sampleData
const reconData = result.reconData
const xData = generateTimeList(
historyTime.value,
model.value.sampling * 1000,
)
historyList.value = sampleData.map((item, index) => {
const point = model.value?.pointInfo[index]
return { return {
data: [
item.map((t, i) => {
return [xData[i], t]
}),
reconData[index].map((t, i) => {
return [xData[i], t]
}),
],
name: `${index + 1}.${point?.description}(${point?.pointId})`,
}
})
brushActivated.value = new Set()
}
function generateTimeList(time: RangeValue, intervalMs: number) {
const [t1, t2] = time
const count = Math.floor(t2.diff(t1, 'millisecond') / intervalMs) + 1
return Array.from({ length: count }, (_, i) => t1.add(i * intervalMs, 'millisecond').valueOf())
}
function getOption(item: any) {
const name = ['测量值', '模型值', '']
const color = ['blue', '#ff6f00', 'red']
const yIndex = [0, 0, 1]
const option = {
xAxis: { xAxis: {
type: 'time', type: 'time',
axisLabel: {
formatter(value) {
const date = new Date(value)
return date.toLocaleString()
}, },
yAxis: { type: 'value' }, },
series: [{ data: item.data, type: 'line', smooth: true, symbol: 'none' }], },
yAxis: [{ type: 'value' }, { type: 'value', max: 10, show: false }],
series: item.data.map((item, index) => {
return {
data: item,
type: 'line',
smooth: true,
symbol: 'none',
name: name[index],
color: color[index],
yAxisIndex: yIndex[index],
}
}),
legend: {},
dataZoom: [{}], dataZoom: [{}],
brush: { brush: {
toolbox: ['lineX'], toolbox: ['lineX'],
@ -133,6 +223,7 @@ export default defineComponent({
}, },
], ],
} }
return option
} }
function setChartRef( function setChartRef(
@ -161,7 +252,6 @@ export default defineComponent({
const chart = echartsRefs.value[index] const chart = echartsRefs.value[index]
if (!chart) if (!chart)
return return
console.log('chart', index, chart)
chart.dispatchAction({ chart.dispatchAction({
type: 'takeGlobalCursor', type: 'takeGlobalCursor',
key: 'brush', key: 'brush',
@ -173,7 +263,10 @@ export default defineComponent({
const areas = (model.value?.trainTime || []).map(row => ({ const areas = (model.value?.trainTime || []).map(row => ({
brushType: 'lineX', brushType: 'lineX',
xAxisIndex: 0, xAxisIndex: 0,
coordRange: [dayjs(row.st).valueOf(), dayjs(row.et).valueOf()], coordRange: [
dayjs(row.st).format('YYYY-MM-DD HH:mm:ss'),
dayjs(row.et).format('YYYY-MM-DD HH:mm:ss'),
],
})) }))
chart.dispatchAction({ chart.dispatchAction({
type: 'brush', type: 'brush',
@ -191,7 +284,6 @@ export default defineComponent({
isInitBrush.value = false isInitBrush.value = false
return return
} }
console.log('brush selected:', params.batch)
const selected = params.batch[0].selected const selected = params.batch[0].selected
if (selected.length > 0) { if (selected.length > 0) {
const areas = mergeAreas(params.batch[0].areas).map(area => ({ const areas = mergeAreas(params.batch[0].areas).map(area => ({
@ -200,7 +292,10 @@ export default defineComponent({
coordRange: area.coordRange, coordRange: area.coordRange,
})) }))
const trainTime = areas.map((area) => { const trainTime = areas.map((area) => {
const [st, et] = area.coordRange const [stRaw, etRaw] = area.coordRange
const st = typeof stRaw === 'string' ? dayjs(stRaw).valueOf() : stRaw
const et = typeof etRaw === 'string' ? dayjs(etRaw).valueOf() : etRaw
console.log('Selected area:', { st, et }, area)
return { return {
st: dayjs(st).format('YYYY-MM-DD HH:mm:ss'), st: dayjs(st).format('YYYY-MM-DD HH:mm:ss'),
et: dayjs(et).format('YYYY-MM-DD HH:mm:ss'), et: dayjs(et).format('YYYY-MM-DD HH:mm:ss'),
@ -210,7 +305,11 @@ export default defineComponent({
mode: '', // mode: '', //
} }
}) })
console.log('Selected train time:', trainTime)
if (trainTimeCopy === JSON.stringify(trainTime))
return
model.value.trainTime = trainTime model.value.trainTime = trainTime
trainTimeCopy = JSON.stringify(trainTime)
echartsRefs.value.forEach((chart, index) => { echartsRefs.value.forEach((chart, index) => {
if (chart) { if (chart) {
chart.dispatchAction({ chart.dispatchAction({
@ -220,6 +319,7 @@ export default defineComponent({
isInitBrush.value = true isInitBrush.value = true
} }
}) })
updateModelInfoDebounced()
} }
}, 300) }, 300)
@ -257,23 +357,12 @@ export default defineComponent({
} }
// //
const updateModelInfoDebounced = debounce((val) => { const updateModelInfoDebounced = debounce(() => {
const val = toRaw(model.value)
if (val && val.id) if (val && val.id)
updateModelInfo(val) updateModelInfo(val)
}, 500) }, 500)
// model
watch(
model,
(newVal, oldVal) => {
console.log('model changed:', newVal, oldVal)
if (oldVal === null)
return
updateModelInfoDebounced(newVal)
},
{ deep: true },
)
function handleDeleteTrainTime(index: number) { function handleDeleteTrainTime(index: number) {
if (!model.value?.trainTime) if (!model.value?.trainTime)
return return
@ -297,6 +386,12 @@ export default defineComponent({
isInitBrush.value = true isInitBrush.value = true
} }
}) })
updateModelInfoDebounced()
}
async function clearModel() {
model.value.para = null
updateModelInfoDebounced()
await getHistory()
} }
async function trainModel() { async function trainModel() {
@ -311,24 +406,46 @@ export default defineComponent({
return return
} }
const params = { const params = {
condition: '1==1', conditon: modelInfo.alarmmodelset?.alarmcondition || '1==1',
Hyper_para: { Hyper_para: {
percent: modelInfo.rate, percent: modelInfo.rate,
}, },
Train_Data: { Train_Data: {
points: pointInfo.map(item => item.pointId).join(','), points: pointInfo.map(item => item.pointId).join(','),
dead: pointInfo.map(item => item.dead ? '1' : '0').join(','), dead: pointInfo.map(item => (item.dead ? '1' : '0')).join(','),
limit: pointInfo.map(item => item.limit ? '1' : '0').join(','), limit: pointInfo.map(item => (item.limit ? '1' : '0')).join(','),
uplow: pointInfo.map(item => `${item.Upper},${item.Lower}`).join(';'), uplow: pointInfo
.map(
item =>
`${item.Upper ? item.Upper : null},${
item.Lower ? item.Lower : null
}`,
)
.join(';'),
interval: modelInfo.sampling * 1000, interval: modelInfo.sampling * 1000,
time: modelInfo.trainTime.map(item => `${item.st},${item.et}`).join(';'), time: modelInfo.trainTime
.map(item => `${item.st},${item.et}`)
.join(';'),
}, },
type: 'PCA', type: 'PCA',
smote_config: '[]', smote_config: [],
smote: true, smote: true,
} }
spinning.value = true
try {
const response = await trainModelApi(params) const response = await trainModelApi(params)
console.log('模型训练结果:', response) model.value.para = response
model.value.principal = response.Model_info.K
updateModelInfoDebounced()
getTestData()
createMessage.success('模型训练成功')
}
catch (error) {
console.error('模型训练失败:', error)
createMessage.error('模型训练失败')
}
spinning.value = false
} }
const editForm = ref({ const editForm = ref({
index: -1, index: -1,
@ -336,14 +453,13 @@ export default defineComponent({
Lower: '', Lower: '',
lowerBound: '', lowerBound: '',
upperBound: '', upperBound: '',
dead: false, dead: true,
limit: true, limit: false,
}) })
const openEditPointModal = ref<boolean>(false) const openEditPointModal = ref<boolean>(false)
let pointEditRecord = null let pointEditRecord = null
function editPoint() { function editPoint() {
// //
console.log('编辑点')
model.value.pointInfo[editForm.value.index] = { model.value.pointInfo[editForm.value.index] = {
...model.value.pointInfo[editForm.value.index], ...model.value.pointInfo[editForm.value.index],
Upper: editForm.value.Upper, Upper: editForm.value.Upper,
@ -353,6 +469,7 @@ export default defineComponent({
dead: editForm.value.dead, dead: editForm.value.dead,
limit: editForm.value.limit, limit: editForm.value.limit,
} }
updateModelInfoDebounced()
pointEditRecord.Upper = editForm.value.Upper pointEditRecord.Upper = editForm.value.Upper
pointEditRecord.Lower = editForm.value.Lower pointEditRecord.Lower = editForm.value.Lower
pointEditRecord.lowerBound = editForm.value.lowerBound pointEditRecord.lowerBound = editForm.value.lowerBound
@ -363,21 +480,27 @@ export default defineComponent({
} }
function openPointModal(index, record) { function openPointModal(index, record) {
// index
const pageIndex = index
// index
const globalIndex = model.value.pointInfo.findIndex(
item => item.pointId === record.pointId,
)
openEditPointModal.value = true openEditPointModal.value = true
pointEditRecord = record pointEditRecord = record
editForm.value = { editForm.value = {
index, index: globalIndex,
Upper: record?.Upper ?? '', Upper: record?.Upper ?? '',
Lower: record?.Lower ?? '', Lower: record?.Lower ?? '',
lowerBound: record?.lowerBound ?? '', lowerBound: record?.lowerBound ?? '',
upperBound: record?.upperBound ?? '', upperBound: record?.upperBound ?? '',
dead: record?.dead ?? false, dead: !!record?.dead,
limit: record?.limit ?? true, limit: !!record?.limit,
} }
} }
const mode = ref({ const mode = ref({
alarmcondition: '1=1', alarmcondition: '1==1',
alarmname: '全工况运行', alarmname: '全工况运行',
}) })
const openEditModeModal = ref<boolean>(false) const openEditModeModal = ref<boolean>(false)
@ -385,7 +508,7 @@ export default defineComponent({
function openEditMode() { function openEditMode() {
openEditModeModal.value = true openEditModeModal.value = true
mode.value = { mode.value = {
alarmcondition: model.value?.alarmmodelset?.alarmcondition || '1=1', alarmcondition: model.value?.alarmmodelset?.alarmcondition || '1==1',
alarmname: model.value?.alarmmodelset?.alarmname || '全工况运行', alarmname: model.value?.alarmmodelset?.alarmname || '全工况运行',
} }
} }
@ -394,10 +517,107 @@ export default defineComponent({
} }
function handleEditMode() { function handleEditMode() {
// //
console.log('编辑模式')
model.value.alarmmodelset = mode.value model.value.alarmmodelset = mode.value
updateModelInfoDebounced()
closeEditMode() closeEditMode()
} }
const openEditModelModal = ref(false)
const editModelForm = ref({
sampling: 0,
rate: 0,
selectedKeys: [],
})
// 穿
const transferData = ref([]) // 穿
//
async function fetchAllPoints(keyword = '') {
// keyword
// const res = await fetchPointsApi({ keyword })
//
const data = await pointListApi({ keyword })
console.log('Fetched points:', data)
transferData.value = transferData.value.filter(item => editModelForm.value.selectedKeys.includes(item.key))
.concat(data.map(item => ({
key: item.id,
title: item.name,
})))
console.log('Transfer data:', transferData.value)
}
onMounted(() => {
fetchAllPoints()
})
function handleTransferSearch(dir, value) {
if (dir === 'left') {
//
fetchAllPoints(value)
}
else {
//
transferData.value = (model.value?.pointInfo || [])
.filter(item =>
editModelForm.value.selectedKeys.includes(`${item.description}|${item.pointId}|${item.unit}|${item.Lower}|${item.Upper}`)
&& (`${item.description || ''}(${item.pointId})`).includes(value),
)
.map(item => ({
key: `${item.description}|${item.pointId}|${item.unit}|${item.Lower}|${item.Upper}`,
title: `${item.description || ''} (${item.pointId})`,
}))
}
}
function openEditModel() {
editModelForm.value.sampling = model.value?.sampling || 0
editModelForm.value.rate = model.value?.rate || 0
editModelForm.value.selectedKeys = (model.value?.pointInfo || []).map(item => `${item.description}|${item.pointId}|${item.unit}|${item.Lower}|${item.Upper}`)
transferData.value = (model.value?.pointInfo || []).map(item => ({
key: `${item.description}|${item.pointId}|${item.unit}|${item.Lower}|${item.Upper}`,
title: `${item.description || ''} (${item.pointId})`,
}))
console.log('transferData:', transferData.value)
openEditModelModal.value = true
}
function handleEditModelOk() {
model.value.sampling = editModelForm.value.sampling
model.value.rate = editModelForm.value.rate
model.value.pointInfo = editModelForm.value.selectedKeys.map((key) => {
const [description, pointId, unit, Lower, Upper] = key.split('|')
return {
description,
pointId,
unit,
Lower,
Upper,
dead: true,
limit: false,
}
})
clearModel()
openEditModelModal.value = false
}
function handleEditModelCancel() {
openEditModelModal.value = false
}
async function bottomModel() {
if (!model.value.para) {
createMessage.error('模型未训练,无法下装')
return
}
try {
const response = await bottomModelApi(model.value.id)
model.value = response
createMessage.success('模型下装成功')
}
catch (error) {
console.error('底层模型获取失败:', error)
createMessage.error('底层模型获取失败')
}
}
return { return {
pointTable, pointTable,
model, model,
@ -423,6 +643,16 @@ export default defineComponent({
closeEditMode, closeEditMode,
handleEditMode, handleEditMode,
mode, mode,
spinning,
clearModel,
openEditModelModal,
editModelForm,
transferData,
handleTransferSearch,
openEditModel,
handleEditModelOk,
handleEditModelCancel,
bottomModel,
} }
}, },
}) })
@ -432,21 +662,15 @@ export default defineComponent({
<PageWrapper content-background> <PageWrapper content-background>
<div> <div>
<a-card title="模型信息" :bordered="false"> <a-card title="模型信息" :bordered="false">
<template #extra>
<a-button> 下装 </a-button>
<a-button type="primary" style="margin-left: 6px">
修改模型
</a-button>
</template>
<a-descriptions size="small" :column="4" bordered> <a-descriptions size="small" :column="4" bordered>
<a-descriptions-item label="模型名称"> <a-descriptions-item label="模型名称">
{{ model?.name }} {{ model?.name }}
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="描述"> <a-descriptions-item label="描述">
{{ model?.description || '暂无描述' }} {{ model?.description || "暂无描述" }}
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="版本"> <a-descriptions-item label="版本">
{{ model?.Cur_Version || 'v-test' }} {{ model?.Cur_Version || "v-test" }}
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="评估报告"> <a-descriptions-item label="评估报告">
暂无 暂无
@ -458,22 +682,22 @@ export default defineComponent({
{{ model?.creatTime }} {{ model?.creatTime }}
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="最近修改人"> <a-descriptions-item label="最近修改人">
{{ model?.Modifier || '暂无' }} {{ model?.Modifier || "暂无" }}
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="最近修改时间"> <a-descriptions-item label="最近修改时间">
{{ model?.modifiedTime || '暂无' }} {{ model?.modifiedTime || "暂无" }}
</a-descriptions-item> </a-descriptions-item>
</a-descriptions> </a-descriptions>
<a-divider /> <a-divider />
<a-descriptions size="small" :column="4" bordered> <a-descriptions size="small" :column="4" bordered>
<a-descriptions-item label="算法"> <a-descriptions-item label="算法">
{{ model?.algorithm || 'PCA' }} {{ model?.algorithm || "PCA" }}
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="训练采样间隔"> <a-descriptions-item label="训练采样间隔">
{{ model?.sampling }} {{ model?.sampling }}
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="参数个数"> <a-descriptions-item label="参数个数">
{{ model?.pointInfo.length || '暂无' }} {{ model?.pointInfo.length || "暂无" }}
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="最小主元贡献率"> <a-descriptions-item label="最小主元贡献率">
{{ model?.rate }} {{ model?.rate }}
@ -485,14 +709,25 @@ export default defineComponent({
{{ model?.precision }} {{ model?.precision }}
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="训练总时长(h)"> <a-descriptions-item label="训练总时长(h)">
{{ (model?.trainTime.reduce((total, item) => total + item.duration, 0) / 3600).toFixed(2) || '暂无' }} {{
(
model?.trainTime.reduce(
(total, item) => total + item.duration,
0,
) / 3600
).toFixed(2) || "暂无"
}}
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="有效样本数"> <a-descriptions-item label="有效样本数">
{{ model?.principal }} {{ model?.principal }}
</a-descriptions-item> </a-descriptions-item>
</a-descriptions> </a-descriptions>
</a-card> </a-card>
<a-card title="模式" :bordered="false" style="margin-top: 16px;margin-bottom: -20px;"> <a-card
title="模式"
:bordered="false"
style="margin-top: 16px; margin-bottom: -20px"
>
<a-button size="large" @click="openEditMode"> <a-button size="large" @click="openEditMode">
{{ model?.alarmmodelset.alarmname }} {{ model?.alarmmodelset.alarmname }}
</a-button> </a-button>
@ -503,7 +738,11 @@ export default defineComponent({
<a-tab-pane key="1" tab="训练采样时间"> <a-tab-pane key="1" tab="训练采样时间">
<BasicTable @register="trainTimeTable"> <BasicTable @register="trainTimeTable">
<template #action="{ record, index }"> <template #action="{ record, index }">
<a-button type="link" danger @click="handleDeleteTrainTime(index)"> <a-button
type="link"
danger
@click="handleDeleteTrainTime(index)"
>
删除 删除
</a-button> </a-button>
</template> </template>
@ -522,46 +761,101 @@ export default defineComponent({
</a-card> </a-card>
<a-card title="智能训练" :bordered="false"> <a-card title="智能训练" :bordered="false">
<div style="display: flex; align-items: center;"> <div style="display: flex; align-items: center">
<a-form layout="inline" style="flex: 1;"> <a-form layout="inline" style="flex: 1">
<a-form-item label="模型预览时间范围"> <a-form-item label="模型预览时间范围">
<a-range-picker v-model:value="historyTime" show-time @change="getHistory" /> <a-range-picker
v-model:value="historyTime"
show-time
@change="getHistory"
/>
</a-form-item> </a-form-item>
</a-form> </a-form>
<a-button type="primary" style="margin-left: auto;" @click="trainModel"> <a-button
type="primary"
style="margin-left: auto"
@click="trainModel"
>
模型训练 模型训练
</a-button> </a-button>
<a-button
type="primary"
style="margin-left: 10px"
@click="clearModel"
>
清除训练结果
</a-button>
<a-button type="primary" style="margin-left: 6px" @click="openEditModel">
修改模型
</a-button>
<a-button
danger
style="margin-left: 10px"
@click="bottomModel"
>
下装
</a-button>
</div> </div>
<a-divider /> <a-divider />
<div v-for="(item, index) in historyList" :key="index" class="echart-box"> <a-spin :spinning="spinning" size="large">
<a-card :bordered="false" style="margin-bottom: 16px;"> <div
v-for="(item, index) in historyList"
:key="index"
class="echart-box"
style="width: 100%"
>
<a-card :bordered="false" style="margin-bottom: 16px">
<template #title> <template #title>
<span style="font-size: 20px;">{{ item.name }}</span> <span style="font-size: 20px">{{ item.name }}</span>
</template> </template>
<VueECharts <VueECharts
:ref="(el) => setEchartsRef(el, index)" :option="getOption(item)" autoresize :ref="(el) => setEchartsRef(el, index)"
style="width: 100%; height: 300px" @finished="() => onChartFinished(index)" :option="getOption(item)"
autoresize
style="width: 100%; height: 200px"
@finished="() => onChartFinished(index)"
@brush-selected="onBrushSelected" @brush-selected="onBrushSelected"
/> />
</a-card> </a-card>
</div> </div>
</a-spin>
</a-card> </a-card>
</div> </div>
<a-modal v-model:open="openEditPointModal" title="更改上下限" @ok="editPoint"> <a-modal
<a-form :model="editForm" :label-col="{ span: 7 }" :wrapper-col="{ span: 15 }"> v-model:open="openEditPointModal"
title="更改上下限"
@ok="editPoint"
>
<a-form
:model="editForm"
:label-col="{ span: 7 }"
:wrapper-col="{ span: 15 }"
>
<a-form-item label="上限"> <a-form-item label="上限">
<a-input-number v-model:value="editForm.Upper" placeholder="请输入上限" /> <a-input-number
v-model:value="editForm.Upper"
placeholder="请输入上限"
/>
</a-form-item> </a-form-item>
<a-form-item label="下限"> <a-form-item label="下限">
<a-input-number v-model:value="editForm.Lower" placeholder="请输入下限" /> <a-input-number
v-model:value="editForm.Lower"
placeholder="请输入下限"
/>
</a-form-item> </a-form-item>
<a-form-item label="残差上限"> <a-form-item label="残差上限">
<a-input-number v-model:value="editForm.upperBound" placeholder="请输入残差上限" /> <a-input-number
v-model:value="editForm.upperBound"
placeholder="请输入残差上限"
/>
</a-form-item> </a-form-item>
<a-form-item label="残差下限"> <a-form-item label="残差下限">
<a-input-number v-model:value="editForm.lowerBound" placeholder="请输入残差下限" /> <a-input-number
v-model:value="editForm.lowerBound"
placeholder="请输入残差下限"
/>
</a-form-item> </a-form-item>
<a-form-item label="清洗方式" style="margin-top: 16px;"> <a-form-item label="清洗方式" style="margin-top: 16px">
<a-checkbox v-model:checked="editForm.dead"> <a-checkbox v-model:checked="editForm.dead">
死区清洗 死区清洗
</a-checkbox> </a-checkbox>
@ -571,16 +865,83 @@ export default defineComponent({
</a-form-item> </a-form-item>
</a-form> </a-form>
</a-modal> </a-modal>
<a-modal v-model:open="openEditModeModal" title="编辑模式" @ok="handleEditMode" @cancel="closeEditMode"> <a-modal
<a-form :model="mode" :label-col="{ span: 7 }" :wrapper-col="{ span: 15 }"> v-model:open="openEditModeModal"
title="编辑模式"
@ok="handleEditMode"
@cancel="closeEditMode"
>
<a-form
:model="mode"
:label-col="{ span: 7 }"
:wrapper-col="{ span: 15 }"
>
<a-form-item label="模式名称"> <a-form-item label="模式名称">
<a-input v-model:value="mode.alarmname" placeholder="请输入模式名称" /> <a-input
v-model:value="mode.alarmname"
placeholder="请输入模式名称"
/>
</a-form-item> </a-form-item>
<a-form-item label="报警条件"> <a-form-item label="报警条件">
<a-input v-model:value="mode.alarmcondition" placeholder="请输入报警条件" /> <a-input
v-model:value="mode.alarmcondition"
placeholder="请输入报警条件"
/>
</a-form-item> </a-form-item>
</a-form> </a-form>
</a-modal> </a-modal>
<a-modal
v-model:open="openEditModelModal"
title="编辑模型"
width="1200px"
@ok="handleEditModelOk"
@cancel="handleEditModelCancel"
>
<a-form
:model="editModelForm"
:label-col="{ span: 7 }"
:wrapper-col="{ span: 15 }"
>
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="训练采样间隔" required>
<a-input-number
v-model:value="editModelForm.sampling"
placeholder="请输入训练采样间隔"
style="width: 100%"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="最小主元贡献率" required>
<a-input-number
v-model:value="editModelForm.rate"
placeholder="请输入最小主元贡献率"
style="width: 100%"
/>
</a-form-item>
</a-col>
</a-row>
<div style="display: flex; justify-content: center; margin-top: 24px;margin-bottom: 10px;">
<a-transfer
v-model:target-keys="editModelForm.selectedKeys"
:data-source="transferData"
:render="item => item.title"
:row-key="(item) => item.key"
:pagination="false"
:show-search="true"
:filter="true"
search-placeholder="搜索测点"
:titles="['可选测点', '已选测点']"
:list-style="{
width: '500px',
height: '450px',
}"
@search="handleTransferSearch"
/>
</div>
</a-form>
</a-modal>
</PageWrapper> </PageWrapper>
</template> </template>

Loading…
Cancel
Save