Просмотр исходного кода

Merge remote-tracking branch 'refs/remotes/origin/master'

# Conflicts:
#	src/views/file/FileDetail.vue
10702 4 лет назад
Родитель
Сommit
fda58d936b

+ 38 - 15
package-lock.json

@@ -321,7 +321,8 @@
     "node_modules/colorette": {
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
-      "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w=="
+      "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
+      "dev": true
     },
     "node_modules/consolidate": {
       "version": "0.16.0",
@@ -422,6 +423,7 @@
       "version": "0.12.9",
       "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.9.tgz",
       "integrity": "sha512-MWRhAbMOJ9RJygCrt778rz/qNYgA4ZVj6aXnNPxFjs7PmIpb0fuB9Gmg5uWrr6n++XKwwm/RmSz6RR5JL2Ocsw==",
+      "dev": true,
       "bin": {
         "esbuild": "bin/esbuild"
       }
@@ -448,6 +450,7 @@
       "version": "2.3.2",
       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
       "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "dev": true,
       "optional": true,
       "os": [
         "darwin"
@@ -459,7 +462,8 @@
     "node_modules/function-bind": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
     },
     "node_modules/generic-names": {
       "version": "2.0.1",
@@ -474,6 +478,7 @@
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
       "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dev": true,
       "dependencies": {
         "function-bind": "^1.1.1"
       },
@@ -509,6 +514,7 @@
       "version": "2.4.0",
       "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz",
       "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==",
+      "dev": true,
       "dependencies": {
         "has": "^1.0.3"
       }
@@ -592,6 +598,7 @@
       "version": "3.1.23",
       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
       "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==",
+      "dev": true,
       "bin": {
         "nanoid": "bin/nanoid.cjs"
       },
@@ -607,12 +614,14 @@
     "node_modules/path-parse": {
       "version": "1.0.7",
       "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
-      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+      "dev": true
     },
     "node_modules/postcss": {
       "version": "8.3.5",
       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.5.tgz",
       "integrity": "sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA==",
+      "dev": true,
       "dependencies": {
         "colorette": "^1.2.2",
         "nanoid": "^3.1.23",
@@ -733,6 +742,7 @@
       "version": "1.20.0",
       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
       "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+      "dev": true,
       "dependencies": {
         "is-core-module": "^2.2.0",
         "path-parse": "^1.0.6"
@@ -742,6 +752,7 @@
       "version": "2.52.3",
       "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.52.3.tgz",
       "integrity": "sha512-QF3Sju8Kl2z0osI4unyOLyUudyhOMK6G0AeqJWgfiyigqLAlnNrfBcDWDx+f1cqn+JU2iIYVkDrgQ6/KtwEfrg==",
+      "dev": true,
       "bin": {
         "rollup": "dist/bin/rollup"
       },
@@ -769,6 +780,7 @@
       "version": "0.6.2",
       "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz",
       "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==",
+      "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
@@ -808,6 +820,7 @@
       "version": "2.3.7",
       "resolved": "https://registry.npmjs.org/vite/-/vite-2.3.7.tgz",
       "integrity": "sha512-Y0xRz11MPYu/EAvzN94+FsOZHbSvO6FUvHv127CyG7mV6oDoay2bw+g5y9wW3Blf8OY3chaz3nc/DcRe1IQ3Nw==",
+      "dev": true,
       "dependencies": {
         "esbuild": "^0.12.5",
         "postcss": "^8.3.0",
@@ -1034,8 +1047,7 @@
     "@vitejs/plugin-vue": {
       "version": "1.10.2",
       "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-1.10.2.tgz",
-      "integrity": "sha512-/QJ0Z9qfhAFtKRY+r57ziY4BSbGUTGsPRMpB/Ron3QPwBZM4OZAZHdTa4a8PafCwU5DTatXG8TMDoP8z+oDqJw==",
-      "requires": {}
+      "integrity": "sha512-/QJ0Z9qfhAFtKRY+r57ziY4BSbGUTGsPRMpB/Ron3QPwBZM4OZAZHdTa4a8PafCwU5DTatXG8TMDoP8z+oDqJw=="
     },
     "@vue/compiler-core": {
       "version": "3.1.2",
@@ -1163,7 +1175,8 @@
     "colorette": {
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
-      "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w=="
+      "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
+      "dev": true
     },
     "consolidate": {
       "version": "0.16.0",
@@ -1242,7 +1255,8 @@
     "esbuild": {
       "version": "0.12.9",
       "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.9.tgz",
-      "integrity": "sha512-MWRhAbMOJ9RJygCrt778rz/qNYgA4ZVj6aXnNPxFjs7PmIpb0fuB9Gmg5uWrr6n++XKwwm/RmSz6RR5JL2Ocsw=="
+      "integrity": "sha512-MWRhAbMOJ9RJygCrt778rz/qNYgA4ZVj6aXnNPxFjs7PmIpb0fuB9Gmg5uWrr6n++XKwwm/RmSz6RR5JL2Ocsw==",
+      "dev": true
     },
     "estree-walker": {
       "version": "2.0.2",
@@ -1258,12 +1272,14 @@
       "version": "2.3.2",
       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
       "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "dev": true,
       "optional": true
     },
     "function-bind": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
     },
     "generic-names": {
       "version": "2.0.1",
@@ -1278,6 +1294,7 @@
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
       "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dev": true,
       "requires": {
         "function-bind": "^1.1.1"
       }
@@ -1298,13 +1315,13 @@
       "version": "5.1.0",
       "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
       "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
-      "dev": true,
-      "requires": {}
+      "dev": true
     },
     "is-core-module": {
       "version": "2.4.0",
       "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz",
       "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==",
+      "dev": true,
       "requires": {
         "has": "^1.0.3"
       }
@@ -1381,7 +1398,8 @@
     "nanoid": {
       "version": "3.1.23",
       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
-      "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw=="
+      "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==",
+      "dev": true
     },
     "normalize-wheel": {
       "version": "1.0.1",
@@ -1391,12 +1409,14 @@
     "path-parse": {
       "version": "1.0.7",
       "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
-      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+      "dev": true
     },
     "postcss": {
       "version": "8.3.5",
       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.5.tgz",
       "integrity": "sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA==",
+      "dev": true,
       "requires": {
         "colorette": "^1.2.2",
         "nanoid": "^3.1.23",
@@ -1423,8 +1443,7 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
       "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
-      "dev": true,
-      "requires": {}
+      "dev": true
     },
     "postcss-modules-local-by-default": {
       "version": "4.0.0",
@@ -1485,6 +1504,7 @@
       "version": "1.20.0",
       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
       "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+      "dev": true,
       "requires": {
         "is-core-module": "^2.2.0",
         "path-parse": "^1.0.6"
@@ -1494,6 +1514,7 @@
       "version": "2.52.3",
       "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.52.3.tgz",
       "integrity": "sha512-QF3Sju8Kl2z0osI4unyOLyUudyhOMK6G0AeqJWgfiyigqLAlnNrfBcDWDx+f1cqn+JU2iIYVkDrgQ6/KtwEfrg==",
+      "dev": true,
       "requires": {
         "fsevents": "~2.3.2"
       }
@@ -1511,7 +1532,8 @@
     "source-map-js": {
       "version": "0.6.2",
       "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz",
-      "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug=="
+      "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==",
+      "dev": true
     },
     "sourcemap-codec": {
       "version": "1.4.8",
@@ -1545,6 +1567,7 @@
       "version": "2.3.7",
       "resolved": "https://registry.npmjs.org/vite/-/vite-2.3.7.tgz",
       "integrity": "sha512-Y0xRz11MPYu/EAvzN94+FsOZHbSvO6FUvHv127CyG7mV6oDoay2bw+g5y9wW3Blf8OY3chaz3nc/DcRe1IQ3Nw==",
+      "dev": true,
       "requires": {
         "esbuild": "^0.12.5",
         "fsevents": "~2.3.1",

+ 233 - 233
src/api/config.js

@@ -31,146 +31,146 @@ export const getAllConfig = payload => {
   const {uid} = payload;
   console.log("payload",payload);
   console.log("uid",uid);
-  // return axios.get(`${CONFIG_MODULE}/get/all?userId=${uid}`).then(res => {
-  //
-  //   return res.data;
-  // });
-  return Promise.resolve({
-    "timestamp": 1649419361037,
-    "status": 200,
-    "data": [
-      {
-        "fileId": "1",
-        "fileName": "event_data",
-        "configId": "1",
-        "modelTypeId": "2",
-        "modelTypeName": "决策树",
-        "confName": "config1",
-        "featureList": [
-          {
-            "id": 105,
-            "fileInfoId": 1,
-            "fieldName": "road",
-            "aliasName": "",
-            "fieldDes": "",
-            "nullsRatio": 0.0,
-            "conOrDis": 0,
-            "fieldType": "string",
-            "valueInfo": "[\"R\",\"L\"]"
-          },
-          {
-            "id": 106,
-            "fileInfoId": 1,
-            "fieldName": "lane",
-            "aliasName": "",
-            "fieldDes": "",
-            "nullsRatio": 0.0,
-            "conOrDis": 0,
-            "fieldType": "string",
-            "valueInfo": "[\"r\",\"m\",\"l\"]"
-          },
-          {
-            "id": 107,
-            "fileInfoId": 1,
-            "fieldName": "vehicle_class",
-            "aliasName": "",
-            "fieldDes": "",
-            "nullsRatio": 0.0,
-            "conOrDis": 0,
-            "fieldType": "string",
-            "valueInfo": "[\"car\",\"truck\",\"bus\"]"
-          },
-          {
-            "id": 110,
-            "fileInfoId": 1,
-            "fieldName": "duration",
-            "aliasName": "",
-            "fieldDes": "",
-            "nullsRatio": 0.0,
-            "conOrDis": 0,
-            "fieldType": "string",
-            "valueInfo": "[\"48,60\",\"24,36\",\"36,48\",\"12,24\",\"0,12\"]"
-          },
-          {
-            "id": 109,
-            "fileInfoId": 1,
-            "fieldName": "event_type",
-            "aliasName": "",
-            "fieldDes": "",
-            "nullsRatio": 0.0,
-            "conOrDis": 0,
-            "fieldType": "string",
-            "valueInfo": "[\"cruise\",\"overdrive\"]"
-          }
-        ]
-      },
-      {
-        "fileId": "1",
-        "fileName": "event_data",
-        "configId": "3",
-        "modelTypeId": "9",
-        "modelTypeName": "K-均值",
-        "confName": "Kmeans-Test",
-        "featureList": [
-          {
-            "id": 105,
-            "fileInfoId": 1,
-            "fieldName": "road",
-            "aliasName": "",
-            "fieldDes": "",
-            "nullsRatio": 0.0,
-            "conOrDis": 0,
-            "fieldType": "string",
-            "valueInfo": "[\"R\",\"L\"]"
-          },
-          {
-            "id": 106,
-            "fileInfoId": 1,
-            "fieldName": "lane",
-            "aliasName": "",
-            "fieldDes": "",
-            "nullsRatio": 0.0,
-            "conOrDis": 0,
-            "fieldType": "string",
-            "valueInfo": "[\"r\",\"m\",\"l\"]"
-          },
-          {
-            "id": 107,
-            "fileInfoId": 1,
-            "fieldName": "vehicle_class",
-            "aliasName": "",
-            "fieldDes": "",
-            "nullsRatio": 0.0,
-            "conOrDis": 0,
-            "fieldType": "string",
-            "valueInfo": "[\"car\",\"truck\",\"bus\"]"
-          },
-          {
-            "id": 110,
-            "fileInfoId": 1,
-            "fieldName": "duration",
-            "aliasName": "",
-            "fieldDes": "",
-            "nullsRatio": 0.0,
-            "conOrDis": 0,
-            "fieldType": "string",
-            "valueInfo": "[\"48,60\",\"24,36\",\"36,48\",\"12,24\",\"0,12\"]"
-          },
-          {
-            "id": 109,
-            "fileInfoId": 1,
-            "fieldName": "event_type",
-            "aliasName": "",
-            "fieldDes": "",
-            "nullsRatio": 0.0,
-            "conOrDis": 0,
-            "fieldType": "string",
-            "valueInfo": "[\"cruise\",\"overdrive\"]"
-          }
-        ]
-      }
-    ]
-  })
+  return axios.get(`${CONFIG_MODULE}/get/all?userId=${uid}`).then(res => {
+
+    return res.data;
+  });
+  // return Promise.resolve({
+  //   "timestamp": 1649419361037,
+  //   "status": 200,
+  //   "data": [
+  //     {
+  //       "fileId": "1",
+  //       "fileName": "event_data",
+  //       "configId": "1",
+  //       "modelTypeId": "2",
+  //       "modelTypeName": "决策树",
+  //       "confName": "config1",
+  //       "featureList": [
+  //         {
+  //           "id": 105,
+  //           "fileInfoId": 1,
+  //           "fieldName": "road",
+  //           "aliasName": "",
+  //           "fieldDes": "",
+  //           "nullsRatio": 0.0,
+  //           "conOrDis": 0,
+  //           "fieldType": "string",
+  //           "valueInfo": "[\"R\",\"L\"]"
+  //         },
+  //         {
+  //           "id": 106,
+  //           "fileInfoId": 1,
+  //           "fieldName": "lane",
+  //           "aliasName": "",
+  //           "fieldDes": "",
+  //           "nullsRatio": 0.0,
+  //           "conOrDis": 0,
+  //           "fieldType": "string",
+  //           "valueInfo": "[\"r\",\"m\",\"l\"]"
+  //         },
+  //         {
+  //           "id": 107,
+  //           "fileInfoId": 1,
+  //           "fieldName": "vehicle_class",
+  //           "aliasName": "",
+  //           "fieldDes": "",
+  //           "nullsRatio": 0.0,
+  //           "conOrDis": 0,
+  //           "fieldType": "string",
+  //           "valueInfo": "[\"car\",\"truck\",\"bus\"]"
+  //         },
+  //         {
+  //           "id": 110,
+  //           "fileInfoId": 1,
+  //           "fieldName": "duration",
+  //           "aliasName": "",
+  //           "fieldDes": "",
+  //           "nullsRatio": 0.0,
+  //           "conOrDis": 0,
+  //           "fieldType": "string",
+  //           "valueInfo": "[\"48,60\",\"24,36\",\"36,48\",\"12,24\",\"0,12\"]"
+  //         },
+  //         {
+  //           "id": 109,
+  //           "fileInfoId": 1,
+  //           "fieldName": "event_type",
+  //           "aliasName": "",
+  //           "fieldDes": "",
+  //           "nullsRatio": 0.0,
+  //           "conOrDis": 0,
+  //           "fieldType": "string",
+  //           "valueInfo": "[\"cruise\",\"overdrive\"]"
+  //         }
+  //       ]
+  //     },
+  //     {
+  //       "fileId": "1",
+  //       "fileName": "event_data",
+  //       "configId": "3",
+  //       "modelTypeId": "9",
+  //       "modelTypeName": "K-均值",
+  //       "confName": "Kmeans-Test",
+  //       "featureList": [
+  //         {
+  //           "id": 105,
+  //           "fileInfoId": 1,
+  //           "fieldName": "road",
+  //           "aliasName": "",
+  //           "fieldDes": "",
+  //           "nullsRatio": 0.0,
+  //           "conOrDis": 0,
+  //           "fieldType": "string",
+  //           "valueInfo": "[\"R\",\"L\"]"
+  //         },
+  //         {
+  //           "id": 106,
+  //           "fileInfoId": 1,
+  //           "fieldName": "lane",
+  //           "aliasName": "",
+  //           "fieldDes": "",
+  //           "nullsRatio": 0.0,
+  //           "conOrDis": 0,
+  //           "fieldType": "string",
+  //           "valueInfo": "[\"r\",\"m\",\"l\"]"
+  //         },
+  //         {
+  //           "id": 107,
+  //           "fileInfoId": 1,
+  //           "fieldName": "vehicle_class",
+  //           "aliasName": "",
+  //           "fieldDes": "",
+  //           "nullsRatio": 0.0,
+  //           "conOrDis": 0,
+  //           "fieldType": "string",
+  //           "valueInfo": "[\"car\",\"truck\",\"bus\"]"
+  //         },
+  //         {
+  //           "id": 110,
+  //           "fileInfoId": 1,
+  //           "fieldName": "duration",
+  //           "aliasName": "",
+  //           "fieldDes": "",
+  //           "nullsRatio": 0.0,
+  //           "conOrDis": 0,
+  //           "fieldType": "string",
+  //           "valueInfo": "[\"48,60\",\"24,36\",\"36,48\",\"12,24\",\"0,12\"]"
+  //         },
+  //         {
+  //           "id": 109,
+  //           "fileInfoId": 1,
+  //           "fieldName": "event_type",
+  //           "aliasName": "",
+  //           "fieldDes": "",
+  //           "nullsRatio": 0.0,
+  //           "conOrDis": 0,
+  //           "fieldType": "string",
+  //           "valueInfo": "[\"cruise\",\"overdrive\"]"
+  //         }
+  //       ]
+  //     }
+  //   ]
+  // })
 }
 
 //   console.log("uid",uid);
@@ -257,94 +257,94 @@ export const getOneConfig = payload => {
   const { configId } = payload;
   console.log("configId",configId);
   console.log("payload",payload);
-  // return axios.get(`${CONFIG_MODULE}/get/one/config?configId=${configId}`).then(res => {
-  //
-  //   return res.data;});
-    return Promise.resolve({
-      "timestamp": 1649473724362,
-      "status": 200,
-      "data": {
-        "configId": "1",
-        "modelTypeId": "6",
-        "modelTypeName": "多层感知器分类器",
-        "modelDes": "",
-        "modelDetileDes": "",
-        "featureList": [
-          {
-            "id": 105,
-            "fileInfoId": 1,
-            "fieldName": "road",
-            "aliasName": "",
-            "fieldDes": "",
-            "nullsRatio": 0.0,
-            "conOrDis": 0,
-            "fieldType": "string",
-            "valueInfo": "[\"R\",\"L\"]"
-          },
-          {
-            "id": 106,
-            "fileInfoId": 1,
-            "fieldName": "lane",
-            "aliasName": "",
-            "fieldDes": "",
-            "nullsRatio": 0.0,
-            "conOrDis": 0,
-            "fieldType": "string",
-            "valueInfo": "[\"r\",\"m\",\"l\"]"
-          },
-          {
-            "id": 107,
-            "fileInfoId": 1,
-            "fieldName": "vehicle_class",
-            "aliasName": "",
-            "fieldDes": "",
-            "nullsRatio": 0.0,
-            "conOrDis": 0,
-            "fieldType": "string",
-            "valueInfo": "[\"car\",\"truck\",\"bus\"]"
-          },
-          {
-            "id": 110,
-            "fileInfoId": 1,
-            "fieldName": "duration",
-            "aliasName": "",
-            "fieldDes": "",
-            "nullsRatio": 0.0,
-            "conOrDis": 0,
-            "fieldType": "string",
-            "valueInfo": "[\"48,60\",\"24,36\",\"36,48\",\"12,24\",\"0,12\"]"
-          },
-          {
-            "id": 109,
-            "fileInfoId": 1,
-            "fieldName": "event_type",
-            "aliasName": "",
-            "fieldDes": "",
-            "nullsRatio": 0.0,
-            "conOrDis": 0,
-            "fieldType": "string",
-            "valueInfo": "[\"cruise\",\"overdrive\"]"
-          }
-        ],
-        "modelInfos": [
-          {
-            "modelName": "event_data",
-            "modelDetailName": "DecisionTree",
-            "trainedStatus": 1
-          },
-          {
-            "modelName": "event_data2",
-            "modelDetailName": "DecisionTree",
-            "trainedStatus": -1
-          },
-          {
-            "modelName": "event_data3",
-            "modelDetailName": "MultilayerPerceptronClassifier",
-            "trainedStatus": -1
-          }
-        ]
-      }
-    });
+  return axios.get(`${CONFIG_MODULE}/get/one/config?configId=${configId}`).then(res => {
+
+    return res.data;});
+    // return Promise.resolve({
+    //   "timestamp": 1649473724362,
+    //   "status": 200,
+    //   "data": {
+    //     "configId": "1",
+    //     "modelTypeId": "6",
+    //     "modelTypeName": "多层感知器分类器",
+    //     "modelDes": "",
+    //     "modelDetileDes": "",
+    //     "featureList": [
+    //       {
+    //         "id": 105,
+    //         "fileInfoId": 1,
+    //         "fieldName": "road",
+    //         "aliasName": "",
+    //         "fieldDes": "",
+    //         "nullsRatio": 0.0,
+    //         "conOrDis": 0,
+    //         "fieldType": "string",
+    //         "valueInfo": "[\"R\",\"L\"]"
+    //       },
+    //       {
+    //         "id": 106,
+    //         "fileInfoId": 1,
+    //         "fieldName": "lane",
+    //         "aliasName": "",
+    //         "fieldDes": "",
+    //         "nullsRatio": 0.0,
+    //         "conOrDis": 0,
+    //         "fieldType": "string",
+    //         "valueInfo": "[\"r\",\"m\",\"l\"]"
+    //       },
+    //       {
+    //         "id": 107,
+    //         "fileInfoId": 1,
+    //         "fieldName": "vehicle_class",
+    //         "aliasName": "",
+    //         "fieldDes": "",
+    //         "nullsRatio": 0.0,
+    //         "conOrDis": 0,
+    //         "fieldType": "string",
+    //         "valueInfo": "[\"car\",\"truck\",\"bus\"]"
+    //       },
+    //       {
+    //         "id": 110,
+    //         "fileInfoId": 1,
+    //         "fieldName": "duration",
+    //         "aliasName": "",
+    //         "fieldDes": "",
+    //         "nullsRatio": 0.0,
+    //         "conOrDis": 0,
+    //         "fieldType": "string",
+    //         "valueInfo": "[\"48,60\",\"24,36\",\"36,48\",\"12,24\",\"0,12\"]"
+    //       },
+    //       {
+    //         "id": 109,
+    //         "fileInfoId": 1,
+    //         "fieldName": "event_type",
+    //         "aliasName": "",
+    //         "fieldDes": "",
+    //         "nullsRatio": 0.0,
+    //         "conOrDis": 0,
+    //         "fieldType": "string",
+    //         "valueInfo": "[\"cruise\",\"overdrive\"]"
+    //       }
+    //     ],
+    //     "modelInfos": [
+    //       {
+    //         "modelName": "event_data",
+    //         "modelDetailName": "DecisionTree",
+    //         "trainedStatus": 1
+    //       },
+    //       {
+    //         "modelName": "event_data2",
+    //         "modelDetailName": "DecisionTree",
+    //         "trainedStatus": -1
+    //       },
+    //       {
+    //         "modelName": "event_data3",
+    //         "modelDetailName": "MultilayerPerceptronClassifier",
+    //         "trainedStatus": -1
+    //       }
+    //     ]
+    //   }
+    // });
 
 }
 
@@ -369,10 +369,10 @@ export const changeConfig = payload => {
  * @param {*} payload
  * @returns
  */
-export const deleteModelByModelId = payload => {
-  console.log("deletepara",payload);
-  const { configId } = payload;
-  return axios.get(`${CONFIG_MODULE}/delete/${configId}`).then(res => {
+export const deleteModelByModelId = configId => {
+  //console.log("deletepara",payload);
+  //const { configId } = payload;
+  return axios.get(`${CONFIG_MODULE}/delete?configId=${configId}`).then(res => {
 
     return res.data;
   });
@@ -385,7 +385,7 @@ export const deleteModelByModelId = payload => {
  */
 export const getFeatureSelection = payload => {
   const { fileId,fieldName } = payload;
-  return axios.get(`${CONFIG_MODULE}/get/features/${fileId}?fieldName=${fieldName}`).then(res => {
+  return axios.get(`${CONFIG_MODULE}/get/features?fileId=${fileId}&fieldName=${fieldName}`).then(res => {
 
     return res.data;
   });

+ 88 - 79
src/api/file.js

@@ -213,84 +213,93 @@ export const deleteFile = fileId => {
  * @returns
  */
 export const analysisFile = (fieldIds,funcId) => {
-    console.log("analysisFile: "+fieldIds+"  "+funcId);
-    // return axios.get(`${FILE_MODULE}//analysis/fields`, {params:{fieldIds:fieldIds,funcId:funcId}}).then(res => {
-    //     return res.data;
-    // });
-    if (funcId==1){
-        return Promise.resolve({
-            "timestamp": 1649561125585,
-            "status": 200,
-            "data": {
-                "105_statistical": {
-                    "R": 330.0,
-                    "L": 424.0
-                },
-                "105_distribution": {
-                    "R": 0.4376657824933687,
-                    "L": 0.5623342175066314
-                }
-            }
-        });
+    //fieldIds=JSON.stringify(fieldIds)
+    console.log(fieldIds)
+    fieldIds=JSON.parse(fieldIds)
+    console.log(fieldIds)
+    let url=`${FILE_MODULE}/analysis/fields?funcId=${funcId}`
+    for(let i=0;i<fieldIds.length;i++){
+        let fieldId=fieldIds[i]
+        url+=`&fieldIds=${fieldId}`
     }
-    if (funcId==2){
-        return Promise.resolve({
-            "timestamp": 1649561125585,
-            "status": 200,
-            "data":{
-                "103": [
-                    79.0,
-                    737.0,
-                    753.0],
-                "104": [
-                    3.16,
-                    29.48,
-                    30.12],
-                "108": [
-                    20.0,
-                    291.0,
-                    318.0]
-            }
-        });
-    }
-    if (funcId==3){
-        return Promise.resolve({
-            "timestamp": 1649561321298,
-            "status": 200,
-            "data": {
-                "frame_index": {
-                    "max": 89992.0,
-                    "variance": 6.474726567563616E8,
-                    "mean": 45439.82360742705,
-                    "stddev": 25445.484014975264
-                }
-            }
-        })
-    }
-    if (funcId==4){
-        return Promise.resolve({
-            "timestamp": 1649561409955,
-            "status": 200,
-            "data": {
-                "103": {
-                    "skewness": -0.010820149962232854,
-                    "kurtosis": -1.0998405481091291
-                }
-            }
-        })
-    }
-    if (funcId==5){
-        return Promise.resolve({
-            "timestamp": 1649561470265,
-            "status": 200,
-            "data": {
-                "Corr": 0.9999999999999994
-            }
-        })
-    }
-    return Promise.resolve({
-        "timestamp": 1649561470265,
-        "status": 400,
-        "data": ""
-    })
+    console.log(url)
+    return axios.get(url).then(res => {
+        return res.data;
+    });
+    // if (funcId==1){
+    //     return Promise.resolve({
+    //         "timestamp": 1649561125585,
+    //         "status": 200,
+    //         "data": {
+    //             "105_statistical": {
+    //                 "R": 330.0,
+    //                 "L": 424.0
+    //             },
+    //             "105_distribution": {
+    //                 "R": 0.4376657824933687,
+    //                 "L": 0.5623342175066314
+    //             }
+    //         }
+    //     });
+    // }
+    // if (funcId==2){
+    //     return Promise.resolve({
+    //         "timestamp": 1649561125585,
+    //         "status": 200,
+    //         "data":{
+    //             "103": [
+    //                 79.0,
+    //                 737.0,
+    //                 753.0],
+    //             "104": [
+    //                 3.16,
+    //                 29.48,
+    //                 30.12],
+    //             "108": [
+    //                 20.0,
+    //                 291.0,
+    //                 318.0]
+    //         }
+    //     });
+    // }
+    // if (funcId==3){
+    //     return Promise.resolve({
+    //         "timestamp": 1649561321298,
+    //         "status": 200,
+    //         "data": {
+    //             "frame_index": {
+    //                 "max": 89992.0,
+    //                 "variance": 6.474726567563616E8,
+    //                 "mean": 45439.82360742705,
+    //                 "stddev": 25445.484014975264
+    //             }
+    //         }
+    //     })
+    // }
+    // if (funcId==4){
+    //     return Promise.resolve({
+    //         "timestamp": 1649561409955,
+    //         "status": 200,
+    //         "data": {
+    //             "103": {
+    //                 "skewness": -0.010820149962232854,
+    //                 "kurtosis": -1.0998405481091291
+    //             }
+    //         }
+    //     })
+    // }
+    // if (funcId==5){
+    //     return Promise.resolve({
+    //         "timestamp": 1649561470265,
+    //         "status": 200,
+    //         "data": {
+    //             "Corr": 0.9999999999999994
+    //         }
+    //     })
+    // }
+    // return Promise.resolve({
+    //     "timestamp": 1649561470265,
+    //     "status": 400,
+    //     "data": ""
+    // })
 }

+ 1 - 1
src/api/model.js

@@ -49,7 +49,7 @@ export const deleteModel=async modelId=>{
      */
     export const getAllModel = async userId => {
         const res = await axios.get(`${MODEL_MODULE}/get/all`, {params: {userId: userId}})
-        return res//response
+        return res.data//response
     }
     /**
      * 获取深度学习模型 GET /model/get/all/dl

+ 1 - 1
src/components/Header.vue

@@ -5,7 +5,7 @@
             <i v-if="!collapse" class="el-icon-s-fold"></i>
             <i v-else class="el-icon-s-unfold"></i>
         </div>
-        <div class="logo">后台管理系统</div>
+        <div class="logo">轻量级AI平台</div>
         <div class="header-right">
             <div class="header-user-con">
                 <!-- 消息中心 -->

+ 23 - 2
src/components/Sidebar.vue

@@ -63,16 +63,37 @@ export default {
               index: "/config",
               title: "模型配置",
           },
+
+
           {
-            icon: "el-icon-lx-redpacket_fill",
+            icon: "el-icon-star-off",
+            index: "/modelDetail",
+            title: "模型训练",
+          },
+          {
+            icon: "el-icon-coin",
             index: "/modelList",
-            title:"深度学习",
+            title:"机器学习模型",
           },
+          {
+            icon: "el-icon-coin",
+            index: "/dlModelList",
+            title:"深度学习模型",
+
+          },
+
           {
             icon: "el-icon-pie-chart",
             index: "/charts",
             title: "训练结果",
           },
+
+          {
+            icon: "el-icon-lx-redpacket_fill",
+            index: "/modelList",
+            title:"深度学习",
+          },
+
           {
               icon: "el-icon-lx-copy",
               index: "/message",

+ 20 - 2
src/router/index.js

@@ -24,10 +24,28 @@ const routes = [
                 path: "/modelList",
                 name: "modelList",
                 meta: {
-                    title: '模型列表'
+                    title: '机器学习模型'
                 },
-                component: () => import ( /* webpackChunkName: "dashboard" */ "../views/modelList.vue")
+                component: () => import ( /* webpackChunkName: "dashboard" */ "../views/ModelList.vue")
             },
+            // {
+            //     path: "/dlModelList",
+            //     name: "dlModelList",
+            //     meta: {
+            //         title: '深度学习模型'
+            //     },
+            //     component: () => import ( /* webpackChunkName: "dashboard" */ "../views/DLModelList.vue")
+            // },
+
+            {
+                path: "/modelDetail",
+                name: "modelDetail",
+                meta: {
+                    title: '模型训练'
+                },
+                component: () => import ( /* webpackChunkName: "dashboard" */ "../views/modelDetail.vue")
+            },
+
             {
                 path: "/fileDetail",
                 name: "fileDetail",

+ 64 - 6
src/views/ConfigDetail.vue

@@ -29,7 +29,6 @@
             </el-form-item>
             <el-form-item label="特征字段:" >
               <el-table :data="tableData" border class="table" ref="fieldTable" header-cell-class-name="table-header" @selection-change="handleSelectChange">
-                <el-table-column width="50" type="selection" ></el-table-column>
                 <el-table-column label="字段名">
                   <template #default="scope"><span>{{ scope.row.fieldName }}</span></template>
                 </el-table-column>
@@ -57,7 +56,6 @@
 
             <el-form-item label="模型列表:" >
             <el-table :data="modelData" border class="table" ref="fieldTable" header-cell-class-name="table-header" @selection-change="handleSelectChange">
-              <el-table-column width="50" type="selection" ></el-table-column>
               <el-table-column label="模型名">
                 <template #default="scope"><span>{{ scope.row.modelName }}</span></template>
               </el-table-column>
@@ -70,7 +68,7 @@
               <el-table-column label="操作" width="180" align="center">
                 <template #default="scope">
 
-                  <router-link :to="{path:'/ConfigDetail',query:{configId:scope.row.configId}}">
+                  <router-link :to="{path:'/ModelDetail',query:{modelId:scope.row.id}}">
                     <el-button type="text" icon="el-icon-edit" >查看模型
                     </el-button>
                   </router-link>
@@ -113,7 +111,7 @@
               <el-form-item label="TrainSetOccupy" v-model="showTrainingSetOccupy" v-if="showTrainingSetOccupy===true">
                 <el-input v-model="form.TrainingSetOccupy"></el-input>
               </el-form-item>
-              <el-form-item label="DataSetOccupy" v-model="showTrainingDataSetOccupy" v-if="showTrainingSetOccupy===true">
+              <el-form-item label="DataSetOccupy" v-model="showTrainingDataSetOccupy" v-if="showTrainingDataSetOccupy===true">
                 <el-input v-model="form.TrainingDataSetOccupy"></el-input>
               </el-form-item>
               <el-form-item label="NumOfCluster" v-model="showNumOfCluster" v-if="showNumOfCluster===true">
@@ -158,6 +156,7 @@ import { fetchData } from "../api/index";
 import {getFileDetail} from "../api/file";
 import {getOneConfig} from "../api/config";
 import {useRoute}from "vue-router";
+import {addModel} from "../api/model";
 export default {
   name: "configDetail",
   //训练特征
@@ -300,10 +299,68 @@ export default {
 
     const saveModel = () => {
       modelVisiable.value = false;
-      ElMessage.success(`已成功生成模型`);
+
       //todo: 调用Model相关接口
       console.log("savemodel",form);
-      console.log(form);
+      const payload={modelTypeId:form.modelTypeId,
+                     configId:form.configId,
+                      fileInfoId:form.fileInfoId,
+                      modelName:form.modelName,
+                      argument:[]
+      }
+      const arg1={
+        MaxIter:form.MaxIter,
+        RegParam:form.RegParam,
+        ElasticNetParam:form.ElasticNetParam
+      }
+      const arg2={
+        Category:form.Category,
+        TrainingDataSetOccupy:form.TrainingDataSetOccupy
+      }
+      const arg3={
+        MaxIter:form.MaxIter,
+        RegParam:form.RegParam,
+        ElasticNetParam:form.ElasticNetParam
+      }
+      const arg4={
+        Category:form.Category,
+        TrainingDataSetOccupy:form.TrainingDataSetOccupy
+      }
+      const arg5={
+        NumOfCluster:form.NumOfCluster,
+        Seed:form.Seed
+      }
+      switch (config.value.modelTypeId){
+        case '1':
+          payload.argument=arg1;
+          break;
+        case '2':
+          payload.argument=arg2;
+          break;
+        case '3'||'4':
+          payload.argument=arg3;
+          break;
+        case '6'||'7'||'8':
+          payload.argument=arg4;
+
+          break;
+        case '9':
+          payload.argument=arg5;
+
+      }
+      // console.log("here",payload);
+      addModel(payload).then(res=>{
+
+        if(res.status===200) {
+          ElMessage.success(`已成功生成模型`);
+
+        }
+        else ElMessage.error(`生成模型失败`);
+      })
+
+
+
+
 
     };
     let idx = -1;
@@ -341,6 +398,7 @@ export default {
       showTrainingSetOccupy,
       showNumOfCluster,
       showSeed,
+      showTrainingDataSetOccupy,
       selectData,
       handleSelectChange,
       handleSearch,

+ 9 - 8
src/views/ConfigList.vue

@@ -10,7 +10,7 @@
 
         <div class="container">
             <div class="handle-box">
-                <el-select v-model="query.file" placeholder="模型类别" class="handle-select mr10">
+                <el-select v-model="query.file" placeholder="模型类别" class="handle-select mr10" >
                     <el-option key="0" label="所有" value="0"></el-option>
                     <el-option key="1" label="逻辑回归" value="1"></el-option>
                     <el-option key="2" label="决策树" value="2"></el-option>
@@ -36,7 +36,6 @@
                 @selection-change="handleSelectionChange"
                 @row-dblclick="getConfigDetail"
             >
-                <el-table-column width="50" type="selection"></el-table-column>
                 <el-table-column prop="confName" label="配置名"></el-table-column>
                 <el-table-column label="模型类别">
                     <template #default="scope">{{ scope.row.modelTypeName }}</template>
@@ -69,7 +68,7 @@
                     <template #default="scope">
 
                       <router-link :to="{path:'/ConfigDetail',query:{configId:scope.row.configId}}">
-                        <el-button type="text" icon="el-icon-edit" >查看详情
+                        <el-button type="text" icon="el-icon-view" >查看详情
                         </el-button>
                       </router-link>
                         <el-button type="text" icon="el-icon-delete" class="red"
@@ -214,12 +213,14 @@ export default {
                     // ElMessage.success("删除成功");
                     // tableData.value.splice(index, 1);
                   console.log("删除");
-                  let idx=tableData._rawValue[index].id;
+                  let idx=tableData.value[index].configId;
                   console.log(idx);
-                  deleteModelByModelId({
-                    configId:idx
-                  }).then(res=>{
-                    console.log("deleteres",res);
+                  deleteModelByModelId(idx
+                  ).then(res=>{
+                    //console.log("deleteres",res);
+                    if(res.status===200){
+                      location.reload();
+                    }
                   });
 
                 })

+ 339 - 0
src/views/ModelDetail.vue

@@ -0,0 +1,339 @@
+<template>
+    <div>
+        <div class="crumbs">
+            <el-breadcrumb separator="/">
+                <el-breadcrumb-item>
+                    <i class="el-icon-lx-cascades"></i> 模型训练使用
+                </el-breadcrumb-item>
+            </el-breadcrumb>
+        </div>
+
+        <div class="container">
+            <div class="handle-box">
+                <el-select v-model="query.file" placeholder="模型信息" class="handle-select mr10">
+                    <el-option key="0" label="所有" value="0"></el-option>
+                    <el-option key="1" label="逻辑回归" value="1"></el-option>
+                    <el-option key="2" label="决策树" value="2"></el-option>
+                    <el-option key="3" label="随机森林" value="3"></el-option>
+                    <el-option key="4" label="梯度提升决策树" value="4"></el-option>
+                  <el-option key="5" label="多层感知器分类器" value="5"></el-option>
+                  <el-option key="6" label="朴素贝叶斯" value="6"></el-option>
+                  <el-option key="7" label="随机森林回归" value="7"></el-option>
+                  <el-option key="8" label="K-均值" value="8"></el-option>
+                </el-select>
+                <!-- <el-input v-model="query.name" placeholder="模型Id" class="handle-input mr10"></el-input>
+                <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button> -->
+            </div>
+            <el-table
+                :data="tableData" border class="table" ref="multipleTable"
+                header-cell-class-name="table-header"
+                @selection-change="handleSelectionChange"
+                @row-dblclick="getConfigDetail"
+            >
+                <el-table-column width="50" type="selection"></el-table-column>
+                <el-table-column prop="confName" label="模型Id"></el-table-column>
+                <el-table-column label="模型信息">
+                    <template #default="scope">{{ scope.row.modelTypeName }}</template>
+                </el-table-column>
+              <el-table-column prop="fileName" label="待测试文件">
+                    <template #default="scope">
+                      <router-link :to="{path:'/ConfigDetail',query:{configId:scope.row.configId}}">
+                        <el-button type="text" icon="el-icon-upload" >选择文件
+                        </el-button>
+                      </router-link>
+                    </template>
+              </el-table-column>
+
+                <el-table-column label="模型训练" width="180" align="center">
+                    <template #default="scope">
+                        <el-button type="text" icon="el-icon-video-play" class="green"
+                            @click="handleDelete(scope.$index, scope.row)">模型训练</el-button> 
+                    </template>
+                </el-table-column>
+                <!-- 如果已经训练了,那么就告诉她您已经训练过该模型,但还是感觉应该放在模型配置里面,配置就可以让他进行训练! -->
+
+
+                <el-table-column label="操作" width="180" align="center">
+                    <template #default="scope">
+                        <el-button type="text" icon="el-icon-mouse" class="blue"
+                            @click="handleDelete(scope.$index, scope.row)">模型使用</el-button>
+                    </template>
+                </el-table-column>
+            </el-table>
+            <div class="pagination">
+                <el-pagination background layout="total, prev, pager, next" :current-page="query.pageIndex"
+                    :page-size="query.pageSize" :total="pageTotal" @current-change="handlePageChange"></el-pagination>
+            </div>
+        </div>
+
+        <!-- 编辑弹出框 -->
+        <el-dialog title="编辑" v-model="editVisible" min-width="30%">
+            <el-form label-width="150px">
+                <el-form-item label="配置名称" required>
+                    <el-input v-model="form.name"></el-input>
+                </el-form-item>
+                <el-form-item label="训练文件" required>
+                    <el-input v-model="form.file"></el-input>
+                </el-form-item>
+                <el-form-item label="选择模型类别" required>
+                  <el-radio-group v-model="modelSty.resource">
+                  <el-radio label="分类"></el-radio>
+                  <el-radio label="聚类"></el-radio>
+                  <el-radio label="回归"></el-radio>
+                  <el-radio label="自动化分类器"></el-radio>
+                  </el-radio-group>
+                </el-form-item>
+
+                <el-form-item label="特征选择方式" required>
+<!--                    <el-checkbox v-for="f in featureList" :key="f" :label="f"></el-checkbox>-->
+                  <el-radio-group v-model="featureSty.resource">
+                    <el-radio label="手动选择"></el-radio>
+                    <el-radio label="自动选择"></el-radio>
+                  </el-radio-group>
+                </el-form-item>
+
+<!--              <el-form-item label="单选框" prop="resource">-->
+<!--                <el-radio-group v-model="form.resource">-->
+<!--                  <el-radio label="步步高"></el-radio>-->
+<!--                  <el-radio label="小天才"></el-radio>-->
+<!--                  <el-radio label="imoo"></el-radio>-->
+<!--                </el-radio-group>-->
+<!--              </el-form-item>-->
+
+                <el-form-item label="选择特征字段" required>
+                  <el-alert type="info" description="您下列选择的第一个字段为分类模型的目标字段"
+                            show-icon style="height: 40px;"></el-alert>
+                </el-form-item>
+            </el-form>
+            <template #footer>
+                <span class="dialog-footer">
+                    <el-button @click="editVisible = false">取 消</el-button>
+                    <el-button type="primary" @click="saveEdit">确 定</el-button>
+                </span>
+            </template>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import { ref, reactive } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { fetchData } from "../api/index";
+import {addConfig, deleteModelByModelId, getAllConfig} from "../api/config";
+
+export default {
+    name: "config",
+    //训练特征
+  // data(){
+  //     return{
+  //       form:{
+  //         name:"",
+  //         file:"",
+  //       }
+  //     }
+  // },
+  setup() {
+    const featureSty = reactive({
+
+      resource: "小天才",
+
+    });
+    const modelSty = reactive({
+
+      resource: "小天才",
+
+    });
+        const query = reactive({
+            file: "",
+            name: "",
+            pageIndex: 1,
+            pageSize: 10,
+        });
+
+        //new TODO
+        const typeList=["所有","分类","聚类","回归","自动分类器"];
+        const featureList=["所有","手动选择","自动选择"];
+        const multipleSelection =ref([]);
+
+        // const tableData = ref([]);
+    const tableData = ref([
+      ]);
+
+        const pageTotal = ref(0);
+        // 获取表格数据
+
+    const getpage=()=> {
+      // console.log("getpage");
+      getAllConfig({
+        uid: 1
+      }).then(res => {
+        console.log("res",res);
+        tableData.value = res.data;
+
+      })
+    };
+     getpage();
+
+
+
+    // 查询操作
+        const handleSearch = () => {
+            query.pageIndex = 1;
+            getData();
+        };
+        // 分页导航
+        const handlePageChange = (val) => {
+            query.pageIndex = val;
+            getData();
+        };
+
+        // 删除操作(单个)
+        const handleDelete = (index) => {
+            // 二次确认删除
+            ElMessageBox.confirm("确定要删除吗?", "提示", {
+                type: "warning",
+            })
+                .then(() => {
+                    // ElMessage.success("删除成功");
+                    // tableData.value.splice(index, 1);
+                  console.log("删除");
+                  let idx=tableData._rawValue[index].id;
+                  console.log(idx);
+                  deleteModelByModelId({
+                    configId:idx
+                  }).then(res=>{
+                    console.log("deleteres",res);
+                  });
+
+                })
+                .catch(() => {});
+        };
+
+        //TODO
+        const handleSelectionChange = (val) => {
+          multipleSelection.value = val
+        };
+
+        //TODO 批量删除
+        const handleBatchDelete =()=>{
+          // 二次确认
+          if(multipleSelection.value.length<=0){
+            ElMessageBox.alert("请先勾选要删除的模型", '提示', {
+              confirmButtonText: '好的'
+            })
+          }
+          else{
+            ElMessageBox.confirm("确定要删除这些模型吗?", "提示", {
+              type: "warning",
+            })
+                .then(() => {
+                  let idList=[];
+                  for(let i=0;i<multipleSelection.value.length;i++){
+                    let id=multipleSelection.value[i]['id'];
+                    idList.push(id);
+                  }
+                  idList.sort();
+                  console.log(idList);
+                  for (let i = idList[idList.length-1]; i >=0 ; i--) {
+                    tableData.value.splice(i,1);
+                  }
+                  ElMessage.success("删除成功");
+                })
+                .catch(() => {});
+          }
+        };
+
+        const getConfigDetail=(row,column,event)=>{
+          var configId=row.configId;
+          //todo:双击跳转到config界面
+          console.log("跳转到config详情界面")
+        }
+        // 表格编辑时弹窗和保存
+        const editVisible = ref(false);
+        let form = reactive({
+            name: "",
+            file: "",
+          // classification:"",
+          // feature:"",
+        });
+        let idx = -1;
+        const handleEdit = (index, row) => {
+            idx = index;
+            Object.keys(form).forEach((item) => {
+                form[item] = row[item];
+            });
+            editVisible.value = true;
+        };
+
+        const saveEdit = () => {
+            editVisible.value = false;
+            // ElMessage.success(`修改第 ${idx + 1} 行成功`);
+            // Object.keys(form).forEach((item) => {
+            //     tableData.value[idx][item] = form[item];
+            // });
+          // console.log("here",featureSty.resource);
+          // const { , ,confName , fieldIds} = payload;
+
+          addConfig({
+            fileInfoId:form.file,
+            userId:0,
+            modelTypeId:modelSty.resource,
+            confName:form.name,
+            fieldIds:featureSty.resource
+            }).then(res=>{
+              console.log(res);
+            });
+        };
+
+        return {
+            query,
+            tableData,
+            pageTotal,
+            editVisible,
+            form,
+            handleSearch,
+            handlePageChange,
+            handleDelete,
+          handleSelectionChange,
+            handleBatchDelete,
+            handleEdit,
+            saveEdit,
+          getConfigDetail,
+            featureSty,
+          modelSty,
+          getpage,
+        };
+    },
+};
+</script>
+
+<style scoped>
+.handle-box {
+    margin-bottom: 20px;
+}
+
+.handle-select {
+    width: 120px;
+}
+
+.handle-input {
+    width: 300px;
+    display: inline-block;
+}
+.table {
+    width: 100%;
+    font-size: 14px;
+}
+.red {
+    color: #ff0000;
+}
+.mr10 {
+    margin-right: 10px;
+}
+.table-td-thumb {
+    display: block;
+    margin: auto;
+    width: 40px;
+    height: 40px;
+}
+</style>

+ 323 - 78
src/views/ModelList.vue

@@ -2,107 +2,352 @@
   <div class="">
     <div class="crumbs">
       <el-breadcrumb separator="/">
-        <el-breadcrumb-item><i class="el-icon-lx-file"></i> 我的模型</el-breadcrumb-item>
+        <el-breadcrumb-item>
+          <i class="el-icon-lx-cascades"></i> 我的模型
+        </el-breadcrumb-item>
       </el-breadcrumb>
     </div>
+
     <div class="container">
-      <el-tabs v-model="message">
-        <el-tab-pane :label="`我的模型列表`" name="first">
-          <el-table :data="state.unread" :show-header="false" style="width: 100%">
-            <el-table-column>
-              <template #default="scope">
-                <span class="message-title">{{scope.row.title}}</span>
-              </template>
-            </el-table-column>
-            <el-table-column prop="date" width="180"></el-table-column>
-            <el-table-column width="120">
-              <template #default="scope">
-                <!----------------------------todo------------------------------->
-                <!----------------------------获取文件详细信息、跳转到响应页面;删除文件------------------------------->
-                <router-link to="/dashboard">
-                <el-button size="small" @click="handleRead(scope.$index)">获取详情</el-button>
-
-                </router-link>
-                <el-button size="small" @click="handleRead(scope.$index)">删除</el-button>
-              </template>
-            </el-table-column>
-          </el-table>
-        </el-tab-pane>
-      </el-tabs>
-<!--          <div class="handle-row">-->
-<!--            <el-button type="primary">全部标为已读</el-button>-->
-<!--          </div>-->
-
-<!--            <button class="el-button el-button&#45;&#45;primary" type="button" data-v-4eda24fc="">&lt;!&ndash;v-if&ndash;&gt;<i class="el-icon-upload"></i><span>上传</span></button>-->
-
-<!--            <router-link to="/config">-->
-<!--&lt;!&ndash;            <button class="el-button el-button&#45;&#45;primary" type="button" data-v-4eda24fc="">&lt;!&ndash;v-if&ndash;&gt;<i class="el-icon-s-home"></i><span>添加模型</span></button>&ndash;&gt;-->
-<!--              <el-button type="primary" size="large">配置模型</el-button>-->
-<!--            </router-link>-->
+      <div class="handle-box">
+        <el-select v-model="query.file" placeholder="模型类别" class="handle-select mr10">
+          <el-option key="0" label="所有" value="0"></el-option>
+          <el-option key="1" label="逻辑回归" value="1"></el-option>
+          <el-option key="2" label="决策树" value="2"></el-option>
+          <el-option key="3" label="随机森林" value="3"></el-option>
+          <el-option key="4" label="梯度提升决策树" value="4"></el-option>
+          <el-option key="5" label="多层感知器分类器" value="5"></el-option>
+          <el-option key="6" label="朴素贝叶斯" value="6"></el-option>
+          <el-option key="7" label="随机森林回归" value="7"></el-option>
+          <el-option key="8" label="K-均值" value="8"></el-option>
+        </el-select>
+        <el-input v-model="query.name" placeholder="模型名" class="handle-input mr10"></el-input>
+        <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
+      </div>
+      <el-table
+          :data="tableData" border class="table" ref="multipleTable"
+          header-cell-class-name="table-header"
+          @selection-change="handleSelectionChange"
+          @row-dblclick="getConfigDetail"
+      >
+        <el-table-column prop="modelName" label="模型名"></el-table-column>
+        <el-table-column prop="configName" label="配置名"></el-table-column>
+        <el-table-column label="模型类别">
+          <template #default="scope">{{ scope.row.modelTypeName }}</template>
+        </el-table-column>
+        <el-table-column prop="arguments" label="参数值">
+          <template #default="scope">
+            <div v-for="(item,index) in scope.row.arguments" :key="index">{{item}}</div>
+          </template>
+        </el-table-column>
+        <el-table-column prop="trainedStatus" label="训练状态">
+          <template #default="scope">
+            <div v-if="scope.row.trainedStatus==='已训练'" >已经训练</div>
+            <div v-else>
+              <el-button type="text" icon="el-icon-video-play" class="green"
+                       @click="handleTrain(scope.$index, scope.row)">模型训练</el-button>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" width="180" align="center">
+          <template #default="scope">
+
+              <el-button type="text" icon="el-icon-mouse" 
+              @click="editUseModel(scope.$index, scope.row)">模型使用
+              </el-button>
+            <el-button type="text" icon="el-icon-delete" class="red"
+                       @click="handleDelete(scope.$index, scope.row)">删除</el-button>
 
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="pagination">
+        <el-pagination background layout="total, prev, pager, next" :current-page="query.pageIndex"
+                       :page-size="query.pageSize" :total="pageTotal" @current-change="handlePageChange"></el-pagination>
+      </div>
     </div>
+
+      <el-dialog
+        v-model="useModelVisible"
+        title="模型使用"
+        width="30%"
+        :before-close="handleClose"
+      >
+            <el-form :model="useform" width="300px">
+              <el-form-item label="选择文件" >
+                <el-select v-model="useform.file" :label-width="formLabelWidth" placeholder="请选择您要使用的文件">
+                  <el-option
+                    v-for="item in fileList"
+                    :key="item.id"
+                    :label="item.name"
+                    :value="item.id"
+                  />
+                </el-select>
+              </el-form-item>
+            </el-form>
+        <template #footer>
+          <span class="dialog-footer">
+            <el-button @click="useModelVisible = false">取消</el-button>
+            <el-button type="primary" 
+            @click="useModel()"
+              >使用模型</el-button
+            >
+          </span>
+        </template>
+      </el-dialog>
+
   </div>
+
 </template>
 
 <script>
 import { ref, reactive } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import {getAllModel,train,use} from "../api/model";
+
 export default {
-  name: "tabs",
+  name: "model",
   setup() {
-    const message = ref("first");
-    const state = reactive({
-      unread: [
-        {
-          date: "2018-04-19 20:00:00",
-          title: "文件1",
-        },
-        {
-          date: "2018-04-19 21:00:00",
-          title: "文件2",
-        },
-      ],
-      read: [
-        {
-          date: "2018-04-19 20:00:00",
-          title: "【系统通知】该系统将于今晚凌晨2点到5点进行升级维护",
-        },
-      ],
-      recycle: [
-        {
-          date: "2018-04-19 20:00:00",
-          title: "【系统通知】该系统将于今晚凌晨2点到5点进行升级维护",
-        },
-      ],
+    const useModelVisible = ref(false)
+    const formLabelWidth='120px';
+    const featureSty = reactive({
+
+      resource: "小天才",
+
+    });
+    const modelSty = reactive({
+
+      resource: "小天才",
+
     });
+    const query = reactive({
+      file: "",
+      name: "",
+      pageIndex: 1,
+      pageSize: 10,
+    });
+
+    const fileList=[{
+          id: '选项1',
+          name: '文件1'
+        }, {
+          id: '选项2',
+          name: '文件2'
+        }, {
+          id: '选项3',
+          name: '文件3'
+        }, {
+          id: '选项4',
+          name: '文件4'
+        }, {
+          id: '选项5',
+          name: '文件5'
+        }];
+
+    const typeList=["所有","分类","聚类","回归","自动分类器"];
+    const featureList=["所有","手动选择","自动选择"];
+    const multipleSelection =ref([]);
 
-    const handleRead = (index) => {
-      const item = state.unread.splice(index, 1);
-      console.log(item);
-      state.read = item.concat(state.read);
+    // const tableData = ref([]);
+    const tableData = ref();
+
+    const pageTotal = ref(0);
+    // 获取表格数据
+
+    const getpage=()=> {
+      // console.log("getpage");
+      const uid=1;
+      getAllModel(
+        uid
+      ).then(res => {
+        console.log("res",res);
+        tableData.value = res.data;
+        pageTotal.value=tableData.value.length
+        for(let i=0;i<tableData.value.length;i++) {
+          const reg=new RegExp("\"","g");
+          tableData.value[i].arguments = ((JSON.stringify(tableData.value[i].arguments))+"")
+              .replace(reg,"")
+              .replace("{","")
+              .replace("}","")
+              .split(",");
+          if(tableData.value[i].trainedStatus===1){
+            tableData.value[i].trainedStatus="已训练";
+          }else{
+            tableData.value[i].trainedStatus="未训练";
+          }
+        }
+      })
     };
-    const handleDel = (index) => {
-      const item = state.read.splice(index, 1);
-      state.recycle = item.concat(state.recycle);
+    getpage();
+    // 查询操作
+    const handleSearch = () => {
+      query.pageIndex = 1;
+      getData();
     };
-    const handleRestore = (index) => {
-      const item = state.recycle.splice(index, 1);
-      state.read = item.concat(state.read);
+    // 分页导航
+    const handlePageChange = (val) => {
+      query.pageIndex = val;
+      getData();
+    };
+    //todo模型训练
+    const handleTrain = (index) => {
+      ElMessageBox.confirm("要进行训练吗?", "提示", {
+        type: "info",
+      })
+          .then(() => {
+            console.log(tableData)
+            let modelId=tableData.value[index].modelId
+            
+            ElMessage.success("模型"+modelId+"训练成功");
+
+          })
+          .catch(() => {});
+    };
+
+let usemodelId;
+    //todo模型使用
+     const editUseModel = (index) => {
+      console.log(useModelVisible)
+      useModelVisible.value=true;
+      usemodelId=tableData.value[index].modelId
+    };
+
+    let useform = reactive({
+      file: "",
+    });
+        //todo模型使用
+     const useModel = (data) => {
+      console.log("模型使用")
+      useModelVisible.value=false;
+      console.log(useform.file+" "+usemodelId)
+      // use() todo
+      ElMessageBox.alert("成功使用模型,快去查看结果吧",{type:"success"})
+    };
+
+    // 删除操作(单个)
+    const handleDelete = (index) => {
+      // 二次确认删除
+      ElMessageBox.confirm("确定要删除吗?", "提示", {
+        type: "warning",
+      })
+          .then(() => {
+            // ElMessage.success("删除成功");
+            // tableData.value.splice(index, 1);
+            console.log("删除");
+            let idx=tableData.value[index].id;
+            console.log(idx);
+
+          })
+          .catch(() => {});
+    };
+
+    //TODO
+    const handleSelectionChange = (val) => {
+      multipleSelection.value = val
+    };
+
+    //TODO 批量删除
+    const handleBatchDelete =()=>{
+      // 二次确认
+      if(multipleSelection.value.length<=0){
+        ElMessageBox.alert("请先勾选要删除的模型", '提示', {
+          confirmButtonText: '好的'
+        })
+      }
+      else{
+        ElMessageBox.confirm("确定要删除这些模型吗?", "提示", {
+          type: "warning",
+        })
+            .then(() => {
+              let idList=[];
+              for(let i=0;i<multipleSelection.value.length;i++){
+                let id=multipleSelection.value[i]['id'];
+                idList.push(id);
+              }
+              idList.sort();
+              console.log(idList);
+              for (let i = idList[idList.length-1]; i >=0 ; i--) {
+                tableData.value.splice(i,1);
+              }
+              ElMessage.success("删除成功");
+            })
+            .catch(() => {});
+      }
+    };
+
+    const editVisible = ref(false);
+    let form = reactive({
+      name: "",
+      file: "",
+      // classification:"",
+      // feature:"",
+    });
+    let idx = -1;
+    const handleEdit = (index, row) => {
+      idx = index;
+      Object.keys(form).forEach((item) => {
+        form[item] = row[item];
+      });
+      editVisible.value = true;
     };
 
     return {
-      message,
-      state,
-      handleRead,
-      handleDel,
-      handleRestore,
+      query,
+      tableData,
+      pageTotal,
+      fileList,
+      useModelVisible,
+      formLabelWidth,
+      editVisible,
+      form,
+      useform,
+      handleSearch,
+      handlePageChange,
+      handleTrain,
+      editUseModel,
+      useModel,
+      handleDelete,
+      handleSelectionChange,
+      handleBatchDelete,
+      handleEdit,
+      featureSty,
+      modelSty,
+      getpage,
     };
   },
 };
 </script>
 
-<style>
-.message-title {
-  cursor: pointer;
+<style scoped>
+.handle-box {
+  margin-bottom: 20px;
+}
+
+.handle-select {
+  width: 120px;
 }
-</style>
 
+.handle-input {
+  width: 300px;
+  display: inline-block;
+}
+.table {
+  width: 100%;
+  font-size: 14px;
+}
+.red {
+  color: #ff0000;
+}
+.green {
+  color: rgb(32, 220, 88)
+}
+.mr10 {
+  margin-right: 10px;
+}
+.table-td-thumb {
+  display: block;
+  margin: auto;
+  width: 40px;
+  height: 40px;
+}
+</style>

+ 163 - 0
src/views/Upload.vue

@@ -0,0 +1,163 @@
+<template>
+    <div>
+        <div class="crumbs">
+            <el-breadcrumb separator="/">
+                <el-breadcrumb-item>
+                    <i class="el-icon-lx-calendar"></i> 表单
+                </el-breadcrumb-item>
+                <el-breadcrumb-item>图片上传</el-breadcrumb-item>
+            </el-breadcrumb>
+        </div>
+        <div class="container">
+            <div class="content-title">支持拖拽</div>
+            <!--<div class="plugins-tips">
+                Element UI自带上传组件。
+                访问地址:
+                <a href="http://element.eleme.io/#/zh-CN/component/upload" target="_blank">Element UI Upload</a>
+            </div>-->
+            <el-upload class="upload-demo" drag action=""
+                       accept=".jpg,.png,.csv"
+                       :limit="10"
+                       :on-exceed="handleExceed"
+                       :on-remove="handleRemove"
+                       :before-remove="beforeRemove"
+                       :auto-upload="false" multiple>
+                <i class="el-icon-upload"></i>
+                <div class="el-upload__text">
+                    将文件拖到此处,或
+                    <em>点击上传</em>
+                </div>
+                <template #tip>
+                    <div class="el-upload__tip">请上传jpg/png图像文件或csv结构化文件,且不超过 500kb,一次最多上传10个文件</div>
+                </template>
+            </el-upload>
+            <!--<div class="content-title">支持裁剪</div>
+            <div class="plugins-tips">
+                vue-cropperjs:一个封装了 cropperjs 的 Vue 组件。
+                访问地址:
+                <a href="https://github.com/Agontuk/vue-cropperjs" target="_blank">vue-cropperjs</a>
+            </div>-->
+        </div>
+    </div>
+</template>
+
+<script>
+import { ref } from "vue";
+import VueCropper from "vue-cropperjs";
+import "cropperjs/dist/cropper.css";
+import defaultSrc from "../assets/img/img.jpg";
+import { ElMessage, ElMessageBox } from "element-plus"
+
+export default {
+    name: "upload",
+    components: {
+        VueCropper,
+    },
+    setup() {
+        const imgSrc = ref("");
+        const cropImg = ref(defaultSrc);
+        const dialogVisible = ref(false);
+        const cropper = ref(null);
+
+        const setImage = (e) => {
+            const file = e.target.files[0];
+            if (!file.type.includes("image/")) {
+                return;
+            }
+            const reader = new FileReader();
+            reader.onload = (event) => {
+                dialogVisible.value = true;
+                imgSrc.value = event.target.result;
+                cropper.value && cropper.value.replace(event.target.result);
+            };
+            reader.readAsDataURL(file);
+        };
+        const cropImage = () => {
+            cropImg.value = cropper.value.getCroppedCanvas().toDataURL();
+        };
+        const cancelCrop = () => {
+            dialogVisible.value = false;
+            cropImg.value = defaultSrc;
+        };
+
+        //todo:
+        const handleExceed=(files,fileList)=>{
+            console.log("handleExceed")
+            console.log(files)
+            console.log(fileList)
+            ElMessage.warning(
+              `一次最多上传10个文件, 你一次上传了${files.length}个文件`
+          )
+        }
+        const handleRemove=(file,fileList)=>{
+          console.log("handleRemove")
+          console.log(file)
+          console.log(fileList)
+        }
+      const beforeRemove = (file, filelist) => {
+        return ElMessageBox.confirm(
+            `取消上传${file.name} ?`
+        ).then(
+            () => true,
+            () => false
+        )
+      }
+        return {
+            cropper,
+            imgSrc,
+            cropImg,
+            dialogVisible,
+            setImage,
+            cropImage,
+            cancelCrop,
+            handleExceed,
+            handleRemove,
+            beforeRemove
+        };
+    },
+};
+</script>
+
+<style scoped>
+.content-title {
+    font-weight: 400;
+    line-height: 50px;
+    margin: 10px 0;
+    font-size: 22px;
+    color: #1f2f3d;
+}
+
+.pre-img {
+    width: 100px;
+    height: 100px;
+    background: #f8f8f8;
+    border: 1px solid #eee;
+    border-radius: 5px;
+}
+.crop-demo {
+    display: flex;
+    align-items: flex-end;
+}
+.crop-demo-btn {
+    position: relative;
+    width: 100px;
+    height: 40px;
+    line-height: 40px;
+    padding: 0 20px;
+    margin-left: 30px;
+    background-color: #409eff;
+    color: #fff;
+    font-size: 14px;
+    border-radius: 4px;
+    box-sizing: border-box;
+}
+.crop-input {
+    position: absolute;
+    width: 100px;
+    height: 40px;
+    left: 0;
+    top: 0;
+    opacity: 0;
+    cursor: pointer;
+}
+</style>

+ 76 - 34
src/views/file/FileDetail.vue

@@ -7,14 +7,17 @@
         </el-breadcrumb-item>
       </el-breadcrumb>
     </div>
-
     <div class="container">
-      <div class="handle-box" style="width:50%;">
-        <el-button plain icon="el-icon-lx-file" @click="handleFileSelect" >选择文件</el-button>
-
-        <el-button type="success" icon="el-icon-search" @click="handleAnalysis">数理分析</el-button>
+      <div class="handle-box">
+        <router-link to="/fileList">
+        <el-button type="primary" plain icon="el-icon-lx-file" >选择文件</el-button>
+        </router-link>
+        <el-button type="primary" icon="el-icon-thumb" @click="handleAnalysis">数理分析</el-button>
 
         <el-button type="primary" icon="el-icon-thumb" @click="createConfig">生成配置文件</el-button>
+
+        <el-button type="primary" icon="el-icon-thumb" @click="getFeature">自动特征选择</el-button>
+
       </div>
 
       <el-table :data="tableData" border class="table" ref="fieldTable" header-cell-class-name="table-header" @selection-change="handleSelectChange">
@@ -48,10 +51,10 @@
       </div>
     </div>
 
-    <el-dialog title="选择字段" v-model="analysisVisible" width="30%">
+    <el-dialog title="选择字段" v-model="analysisVisible" width="50%">
       <el-form label-width="120px">
         <el-form-item label="分析方法" required>
-          <el-select v-model="form.type" placeholder="分析方法" class="handle-select mr10" >
+          <el-select v-model="form.type" placeholder="分析方法" class="handle-select mr10" @change="changeMethodMsg">
             <el-option key="1" label="数据分布" value="1"></el-option>
             <el-option key="2" label="散点图" value="2"></el-option>
             <el-option key="3" label="数据统计" value="3"></el-option>
@@ -59,6 +62,8 @@
             <el-option key="5" label="皮尔森相关系数" value="5"></el-option>
           </el-select>
         </el-form-item>
+        <el-alert type="info"
+                  show-icon style="height: 40px;">{{methodMsg.valueOf()}}</el-alert>
         <el-form-item label="方法和字段要求" required>
           <text>皮尔森相关系数需要两个int/double字段,散点图可以传入2-3个字段,其他的方法只需一个字段。除了数据分布可以传入string字段,其他方法请传入int/double字段</text>
         </el-form-item>
@@ -109,13 +114,13 @@
       </template>
     </el-dialog>
 
-    <el-dialog title="新建配置" v-model="configCreate" width="30%">
+    <el-dialog title="新建配置" v-model="configCreate" width="50%">
       <el-form label-width="120px">
         <el-form-item label="配置名" required>
           <el-input v-model="form.name"></el-input>
         </el-form-item>
         <el-form-item label="模型类别" required>
-          <el-select v-model="form.type" placeholder="模型类别" class="handle-select mr10" >
+          <el-select v-model="form.type" placeholder="模型类别" class="handle-select mr10" @change="selectModelTypeChange">
             <el-option key="0" label="所有" value="0"></el-option>
             <el-option key="1" label="逻辑回归" value="1"></el-option>
             <el-option key="2" label="决策树" value="2"></el-option>
@@ -127,7 +132,11 @@
             <el-option key="8" label="K-均值" value="8"></el-option>
           </el-select>
         </el-form-item>
-        <el-form-item label="已选择字段" required>
+        <el-form-item label="已选择字段" >
+          <el-alert type="info" description="您下列选择的最后一个字段为分类模型的目标字段" v-if="featureTip===1"
+                    show-icon style="height: 40px;"></el-alert>
+          <el-alert type="info" description="k-means模型没有目标字段" v-if="featureTip===2"
+                    show-icon style="height: 40px;"></el-alert>
           <el-table :data="selectData" border class="table"  header-cell-class-name="table-header" >
             <el-table-column label="字段名">
               <template #default="scope"><span>{{ scope.row.fieldName }}</span></template>
@@ -154,12 +163,14 @@ import {getFileDetail,analysisFile} from "../../api/file";
 import {useRoute}from "vue-router";
 import {useRouter}from "vue-router";
 import { toRaw } from '@vue/reactivity'
+import {addConfig,getFeatureSelection} from "../../api/config";
 
 export default {
   name: "config",
   //训练特征
   setup() {
     const router=useRouter();
+    const methodMsg=ref("不同方法仅适用于特定特征字段")
     const query = reactive({
       address: "",
       name: "",
@@ -184,11 +195,6 @@ export default {
     let analysisData=reactive([])
     const pageTotal = ref(0);
 
-    const handleFileSelect=()=>{
-      router.push('/fileList')
-    }
-
-
     // 获取表格数据
     const getData = () => {
       const route=useRoute()
@@ -211,7 +217,21 @@ export default {
 
     };
     getData();
+    const getFeature=()=>{
+      if(selectData.value.length===0){ElMessage.error("请先选择目标字段");return;}
+      if(selectData.value.length>1){ElMessage.error("目标字段仅可选择一个");return;}
+      getFeatureSelection({"fileId":fileId,"fieldName":selectData.value[0].fieldName}).then(
+          res=>{
+            console.log(res)
+            res=res.data
+            for(let i=0;i<res.length;i++){
+              selectData.value.unshift(res[i])
+            }
+            createConfig()
+          }
 
+      )
+    }
     // 查询操作
     const handleSearch = () => {
       query.pageIndex = 1;
@@ -250,14 +270,26 @@ export default {
     const handleAnalysis = () => {
       analysisVisible.value = true;
     };
-
+    const changeMethodMsg=(value)=>{
+      console.log(value)
+      if(value===1){
+        methodMsg.value="数据分布无特殊限制"
+      }else if(value===2){
+        methodMsg.value="散点图可以传入2-3个int/double字段"
+      }else if(value===3){
+        methodMsg.value="请传入1个int/double字段"
+      }else if(value===4){
+        methodMsg.value="请传入1个int/double字段"
+      }else if(value===5){
+        methodMsg.value="请传入2个int/double字段"
+      }
+    }
     const startAnalysis = () => {
       analysisVisible.value = false;
       //todo: 数理分析相关
 
       console.log(form.type);
       console.log(toRaw(selectData.value));
-
       let selectList=[];
       let fieldIds=[];
       for (var i=0; i<selectData.value.length;i++){
@@ -279,7 +311,7 @@ export default {
         });
         return ;
       };
-      analysisFile(fieldIds,form.type).then(res=>{
+      analysisFile(JSON.stringify(fieldIds),form.type).then(res=>{
         console.log(res.data)
         if (res.status!=200){
           ElMessageBox.confirm("分析产生错误,请检查您的分析方法和字段选择是否合理", "错误", {
@@ -326,28 +358,34 @@ export default {
 
     };
     let resultVisible= ref(false);
-
-
+  let featureTip=ref(0);
+    const selectModelTypeChange=(selectValue)=>{
+      if(selectValue==="8")featureTip.value=2;
+      else featureTip.value=1;
+      console.log(featureTip.value)
+    }
     const configCreate = ref(false);
     const createConfig =() => {
       const fieldTable = ref(null)
       //console.log(fieldTable)
       console.log(selectData.value)
-       onMounted(() => {
-        console.log(fieldTable.value.selection)
-      })
-
       configCreate.value = true;
     };
-
-    const saveConfig = () => {
-      configCreate.value = false;
-      ElMessage.success(`已成功生成配置`);
-      //todo: 调用Config相关接口
-
-
-
-    };
+    const saveConfig=()=>{
+      const route=useRoute()
+      const payload={fileInfoId:selectData.value[0].fileInfoId,userId:1, modelTypeId:form.type, confName:form.name , fieldIds:[]}
+      for(let i=0;i<selectData.value.length;i++){
+        payload.fieldIds.push(selectData.value[i].id);
+      }
+      addConfig(payload).then(res=>{
+        if(res.status===200) {
+          ElMessage.success(`已成功生成配置`);
+          configCreate.value = false;
+        }
+        else ElMessage.error(`生成配置失败`);
+      })
+      console.log(payload)
+    }
     const handleSelectChange=val=>{
       selectData.value=val;
     };
@@ -363,15 +401,19 @@ export default {
       configCreate,
       createConfig,
       saveConfig,
+      getFeature,
       selectData,
       analysisData,
-      handleFileSelect,
+      featureTip,
+      methodMsg,
+      selectModelTypeChange,
       handleSelectChange,
       handleSearch,
       handlePageChange,
       handleDelete,
       handleAnalysis,
       startAnalysis,
+      changeMethodMsg
     };
   },
 };

+ 6 - 1
vite.config.js

@@ -16,6 +16,11 @@ export default {
             //     // rewrite: path => path.replace(/^\/api/, '')
             // }
         }
-    }
+    },
+    devServer: {
+        port: 3000,
+        open: true,
+        hot: true,//自动保存
+      },
 
 }