cxmo 8 ヶ月 前
コミット
a124a5e140

+ 1 - 1
.env.development

@@ -1,5 +1,5 @@
 # 接口地址
-VITE_APP_API_URL="/v1"
+VITE_APP_API_URL="http://8.136.199.33:7007/adminapi"
 # 路由根地址
 VITE_APP_BASE_URL="/"
 # 打包输入文件名

+ 1 - 0
package.json

@@ -16,6 +16,7 @@
     "highcharts": "^11.4.3",
     "js-base64": "^3.7.7",
     "js-md5": "^0.8.3",
+    "lodash": "^4.17.21",
     "normalize.css": "^8.0.1",
     "vue": "^3.4.21",
     "vue-router": "^4.3.2"

+ 60 - 53
pnpm-lock.yaml

@@ -1,5 +1,9 @@
 lockfileVersion: '6.0'
 
+settings:
+  autoInstallPeers: true
+  excludeLinksFromLockfile: false
+
 dependencies:
   '@element-plus/icons-vue':
     specifier: ^2.3.1
@@ -19,6 +23,9 @@ dependencies:
   js-md5:
     specifier: ^0.8.3
     version: 0.8.3
+  lodash:
+    specifier: ^4.17.21
+    version: 4.17.21
   normalize.css:
     specifier: ^8.0.1
     version: 8.0.1
@@ -114,7 +121,7 @@ packages:
     dev: false
 
   /@esbuild/aix-ppc64@0.20.2:
-    resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==}
+    resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==, tarball: https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [ppc64]
     os: [aix]
@@ -123,7 +130,7 @@ packages:
     optional: true
 
   /@esbuild/android-arm64@0.20.2:
-    resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==}
+    resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==, tarball: https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [android]
@@ -132,7 +139,7 @@ packages:
     optional: true
 
   /@esbuild/android-arm@0.20.2:
-    resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==}
+    resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==, tarball: https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [arm]
     os: [android]
@@ -141,7 +148,7 @@ packages:
     optional: true
 
   /@esbuild/android-x64@0.20.2:
-    resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==}
+    resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==, tarball: https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [android]
@@ -150,7 +157,7 @@ packages:
     optional: true
 
   /@esbuild/darwin-arm64@0.20.2:
-    resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==}
+    resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==, tarball: https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [darwin]
@@ -159,7 +166,7 @@ packages:
     optional: true
 
   /@esbuild/darwin-x64@0.20.2:
-    resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==}
+    resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==, tarball: https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [darwin]
@@ -168,7 +175,7 @@ packages:
     optional: true
 
   /@esbuild/freebsd-arm64@0.20.2:
-    resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==}
+    resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [freebsd]
@@ -177,7 +184,7 @@ packages:
     optional: true
 
   /@esbuild/freebsd-x64@0.20.2:
-    resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==}
+    resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==, tarball: https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [freebsd]
@@ -186,7 +193,7 @@ packages:
     optional: true
 
   /@esbuild/linux-arm64@0.20.2:
-    resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==}
+    resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [linux]
@@ -195,7 +202,7 @@ packages:
     optional: true
 
   /@esbuild/linux-arm@0.20.2:
-    resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==}
+    resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==, tarball: https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [arm]
     os: [linux]
@@ -204,7 +211,7 @@ packages:
     optional: true
 
   /@esbuild/linux-ia32@0.20.2:
-    resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==}
+    resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==, tarball: https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [ia32]
     os: [linux]
@@ -213,7 +220,7 @@ packages:
     optional: true
 
   /@esbuild/linux-loong64@0.20.2:
-    resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==}
+    resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==, tarball: https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [loong64]
     os: [linux]
@@ -222,7 +229,7 @@ packages:
     optional: true
 
   /@esbuild/linux-mips64el@0.20.2:
-    resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==}
+    resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==, tarball: https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [mips64el]
     os: [linux]
@@ -231,7 +238,7 @@ packages:
     optional: true
 
   /@esbuild/linux-ppc64@0.20.2:
-    resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==}
+    resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==, tarball: https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [ppc64]
     os: [linux]
@@ -240,7 +247,7 @@ packages:
     optional: true
 
   /@esbuild/linux-riscv64@0.20.2:
-    resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==}
+    resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==, tarball: https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [riscv64]
     os: [linux]
@@ -249,7 +256,7 @@ packages:
     optional: true
 
   /@esbuild/linux-s390x@0.20.2:
-    resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==}
+    resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==, tarball: https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [s390x]
     os: [linux]
@@ -258,7 +265,7 @@ packages:
     optional: true
 
   /@esbuild/linux-x64@0.20.2:
-    resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==}
+    resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==, tarball: https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [linux]
@@ -267,7 +274,7 @@ packages:
     optional: true
 
   /@esbuild/netbsd-x64@0.20.2:
-    resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==}
+    resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==, tarball: https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [netbsd]
@@ -276,7 +283,7 @@ packages:
     optional: true
 
   /@esbuild/openbsd-x64@0.20.2:
-    resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==}
+    resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==, tarball: https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [openbsd]
@@ -285,7 +292,7 @@ packages:
     optional: true
 
   /@esbuild/sunos-x64@0.20.2:
-    resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==}
+    resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==, tarball: https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [sunos]
@@ -294,7 +301,7 @@ packages:
     optional: true
 
   /@esbuild/win32-arm64@0.20.2:
-    resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==}
+    resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==, tarball: https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [win32]
@@ -303,7 +310,7 @@ packages:
     optional: true
 
   /@esbuild/win32-ia32@0.20.2:
-    resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==}
+    resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==, tarball: https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [ia32]
     os: [win32]
@@ -312,7 +319,7 @@ packages:
     optional: true
 
   /@esbuild/win32-x64@0.20.2:
-    resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==}
+    resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==, tarball: https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [win32]
@@ -408,7 +415,7 @@ packages:
     dev: true
 
   /@pkgjs/parseargs@0.11.0:
-    resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
+    resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==, tarball: https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz}
     engines: {node: '>=14'}
     requiresBuild: true
     dev: true
@@ -429,7 +436,7 @@ packages:
     dev: true
 
   /@rollup/rollup-android-arm-eabi@4.18.0:
-    resolution: {integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==}
+    resolution: {integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz}
     cpu: [arm]
     os: [android]
     requiresBuild: true
@@ -437,7 +444,7 @@ packages:
     optional: true
 
   /@rollup/rollup-android-arm64@4.18.0:
-    resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==}
+    resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==, tarball: https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz}
     cpu: [arm64]
     os: [android]
     requiresBuild: true
@@ -445,7 +452,7 @@ packages:
     optional: true
 
   /@rollup/rollup-darwin-arm64@4.18.0:
-    resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==}
+    resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==, tarball: https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz}
     cpu: [arm64]
     os: [darwin]
     requiresBuild: true
@@ -453,7 +460,7 @@ packages:
     optional: true
 
   /@rollup/rollup-darwin-x64@4.18.0:
-    resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==}
+    resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==, tarball: https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz}
     cpu: [x64]
     os: [darwin]
     requiresBuild: true
@@ -461,7 +468,7 @@ packages:
     optional: true
 
   /@rollup/rollup-linux-arm-gnueabihf@4.18.0:
-    resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==}
+    resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz}
     cpu: [arm]
     os: [linux]
     libc: [glibc]
@@ -470,7 +477,7 @@ packages:
     optional: true
 
   /@rollup/rollup-linux-arm-musleabihf@4.18.0:
-    resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==}
+    resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz}
     cpu: [arm]
     os: [linux]
     libc: [musl]
@@ -479,7 +486,7 @@ packages:
     optional: true
 
   /@rollup/rollup-linux-arm64-gnu@4.18.0:
-    resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==}
+    resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz}
     cpu: [arm64]
     os: [linux]
     libc: [glibc]
@@ -488,7 +495,7 @@ packages:
     optional: true
 
   /@rollup/rollup-linux-arm64-musl@4.18.0:
-    resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==}
+    resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz}
     cpu: [arm64]
     os: [linux]
     libc: [musl]
@@ -497,7 +504,7 @@ packages:
     optional: true
 
   /@rollup/rollup-linux-powerpc64le-gnu@4.18.0:
-    resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==}
+    resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz}
     cpu: [ppc64]
     os: [linux]
     libc: [glibc]
@@ -506,7 +513,7 @@ packages:
     optional: true
 
   /@rollup/rollup-linux-riscv64-gnu@4.18.0:
-    resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==}
+    resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz}
     cpu: [riscv64]
     os: [linux]
     libc: [glibc]
@@ -515,7 +522,7 @@ packages:
     optional: true
 
   /@rollup/rollup-linux-s390x-gnu@4.18.0:
-    resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==}
+    resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz}
     cpu: [s390x]
     os: [linux]
     libc: [glibc]
@@ -524,7 +531,7 @@ packages:
     optional: true
 
   /@rollup/rollup-linux-x64-gnu@4.18.0:
-    resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==}
+    resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz}
     cpu: [x64]
     os: [linux]
     libc: [glibc]
@@ -533,7 +540,7 @@ packages:
     optional: true
 
   /@rollup/rollup-linux-x64-musl@4.18.0:
-    resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==}
+    resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==, tarball: https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz}
     cpu: [x64]
     os: [linux]
     libc: [musl]
@@ -542,7 +549,7 @@ packages:
     optional: true
 
   /@rollup/rollup-win32-arm64-msvc@4.18.0:
-    resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==}
+    resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz}
     cpu: [arm64]
     os: [win32]
     requiresBuild: true
@@ -550,7 +557,7 @@ packages:
     optional: true
 
   /@rollup/rollup-win32-ia32-msvc@4.18.0:
-    resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==}
+    resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz}
     cpu: [ia32]
     os: [win32]
     requiresBuild: true
@@ -558,7 +565,7 @@ packages:
     optional: true
 
   /@rollup/rollup-win32-x64-msvc@4.18.0:
-    resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==}
+    resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==, tarball: https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz}
     cpu: [x64]
     os: [win32]
     requiresBuild: true
@@ -566,7 +573,7 @@ packages:
     optional: true
 
   /@sxzz/popperjs-es@2.11.7:
-    resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==}
+    resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==, tarball: https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz}
     dev: false
 
   /@trysound/sax@0.2.0:
@@ -727,7 +734,7 @@ packages:
     dev: true
 
   /ansi-regex@5.0.1:
-    resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+    resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, tarball: https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz}
     engines: {node: '>=8'}
     dev: true
 
@@ -742,7 +749,7 @@ packages:
     dev: true
 
   /ansi-styles@4.3.0:
-    resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+    resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, tarball: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz}
     engines: {node: '>=8'}
     dependencies:
       color-convert: 2.0.1
@@ -878,7 +885,7 @@ packages:
     dev: true
 
   /bare-events@2.4.2:
-    resolution: {integrity: sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==}
+    resolution: {integrity: sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==, tarball: https://registry.npmmirror.com/bare-events/-/bare-events-2.4.2.tgz}
     requiresBuild: true
     dev: true
     optional: true
@@ -1040,14 +1047,14 @@ packages:
     dev: true
 
   /color-convert@2.0.1:
-    resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+    resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, tarball: https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz}
     engines: {node: '>=7.0.0'}
     dependencies:
       color-name: 1.1.4
     dev: true
 
   /color-name@1.1.4:
-    resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+    resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, tarball: https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz}
     dev: true
 
   /combined-stream@1.0.8:
@@ -1339,7 +1346,7 @@ packages:
     dev: false
 
   /emoji-regex@8.0.0:
-    resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+    resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, tarball: https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz}
     dev: true
 
   /emoji-regex@9.2.2:
@@ -1683,7 +1690,7 @@ packages:
     dev: true
 
   /fsevents@2.3.3:
-    resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+    resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, tarball: https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz}
     engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
     os: [darwin]
     requiresBuild: true
@@ -2010,7 +2017,7 @@ packages:
     dev: true
 
   /is-fullwidth-code-point@3.0.0:
-    resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+    resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, tarball: https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz}
     engines: {node: '>=8'}
     dev: true
 
@@ -2254,7 +2261,7 @@ packages:
     dev: false
 
   /lodash@4.17.21:
-    resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+    resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==, tarball: https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz}
 
   /lru-cache@10.2.2:
     resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==}
@@ -3007,7 +3014,7 @@ packages:
     dev: true
 
   /string-width@4.2.3:
-    resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+    resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, tarball: https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz}
     engines: {node: '>=8'}
     dependencies:
       emoji-regex: 8.0.0
@@ -3071,7 +3078,7 @@ packages:
     dev: true
 
   /strip-ansi@6.0.1:
-    resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+    resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, tarball: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz}
     engines: {node: '>=8'}
     dependencies:
       ansi-regex: 5.0.1
@@ -3570,7 +3577,7 @@ packages:
     dev: true
 
   /wrap-ansi@7.0.0:
-    resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+    resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, tarball: https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz}
     engines: {node: '>=10'}
     dependencies:
       ansi-styles: 4.3.0

+ 35 - 0
src/api/author/common.js

@@ -0,0 +1,35 @@
+import { get, post } from "@/api/index";
+
+export default {
+    /**
+     * 获取研究员列表
+     * @param {Object} params
+     * @param {Number} params.PageSize
+     * @param {Number} params.CurrentIndex
+     * @returns 
+     */
+    getAuthorList: params => {
+        return get('/analyst/list', params)
+    },
+    /**
+     * 上传研究员头像
+     * @param {Object} params
+     * @param {File} params.File
+     * @returns res.Data {Url:'',FileName:''}
+     */
+    uploadAuthorPic: params => {
+        return post('/analyst/uploadImage',params)
+    },
+    /**
+     * 编辑研究员
+     * @param {Object} params 
+     * @param {Number} params.Id
+     * @param {String} params.HeadImgUrl
+     * @param {String} params.Introduction
+     * @returns 
+     */
+    editAuthor: params => {
+        return post('/analyst/edit',params)
+    }
+
+};

+ 4 - 0
src/api/author/index.js

@@ -0,0 +1,4 @@
+import apiAuthor from './common'
+export {
+    apiAuthor
+}

+ 13 - 47
src/api/customer/modules/user.js

@@ -1,51 +1,17 @@
 import { get, post } from "@/api/index";
 
 export default {
-  //用户列表数据
-  userList: params => {
-    return get("/user/list", params);
-  },
-  userInfo: params => {
-    return get("/user/detail", params);
-  },
-  // 新增用户进行校验
-  userAddCheck:params=>{
-    return post("/user/check", params);
-  },
-  // 新增用户
-  userAdd:params=>{
-    return post("/user/add", params);
-  },
-  // 编辑用户
-  userEdit:params=>{
-    return post("/user/edit", params);
-  },
-  userPermissionData:params=>{
-    return get('/chart_permission/list',params)
-  },
-  // 用户操作记录
-  userOperationRecord:params=>{
-    return get('/user/change_list',params)
-  },
-  // 启用\禁用用户
-  setUserStatus:params=>{
-    return post('/user/editEnabled',params)
-  },
-  //删除用户
-  userDelete:params=>{
-    return post('/user/delete',params)
-  },
-  // 潜在用户列表
-  potentialUserList:params=>{
-    return get('/user/potential/list',params)
-  },
-  //潜在用户转客户
-  potentialUserEdit:params=>{
-    return post('/user/potential/edit',params)
-  },
-  // 客户全局搜索
-  userGlobalSearch:params=>{
-    return get('/user/global/list',params)
-  }
-  
+    /**
+     * 临时用户列表
+     * @param {Object} params
+     * @param {Number} params.PageSize
+     * @param {Number} params.CurrentIndex
+     * @param {Number} params.Keyword
+     * @param {Number} params.SortParam 0:注册时间,1:阅读数,2:最近一次阅读时间
+     * @param {Number} params.SortType 0:倒序,1:正序
+     * @returns 
+     */
+    getTempCustomList:params=>{
+        return get('/user/temporary/list',params)
+    },
 };

+ 49 - 0
src/api/media/audio.js

@@ -0,0 +1,49 @@
+import { get, post } from "@/api/index";
+export default{
+    /**
+     * 获取音频列表
+     * @param {Object} params
+     * @param {Object} params.CurrentIndex
+     * @param {Object} params.PageSize
+     * @param {Object} params.SortType asc dec
+     * @returns 
+     */
+    getAudioList: params => {
+        return get('/media/audioList',params)
+    },
+    /**
+     * 上传音频文件
+     * @param {Object} params
+     * @param {File} params.File
+     * @returns res.Data {Url:'',FileName:''}
+     */
+    uploadAudioFile: params => {
+        return post('/media/uploadAudio',params)
+    },
+    /**
+     * 添加音频
+     * @param {Object} params
+     * @param {Object} params.AudioName 音频标题
+     * @param {Object} params.AnalystId 
+     * @param {Object} params.AnalystName
+     * @param {Object} params.SrcUrl
+     * @param {Object} params.PermissionIds 所属二级品种,用,隔开
+     * @param {Object} params.DurationMillisecond 音频长度 单位毫秒
+     * @returns 
+     */
+    addAudio: params => {
+        return post('/media/addAudio',params)
+    },
+    editAudio: params => {
+        return post('/media/editAudio',params)
+    },
+    /**
+     * 删除音频
+     * @param {Object} params 
+     * @param {Number} params.AudioId
+     * @returns 
+     */
+    deleteAudio: params => {
+        return post('/media/deleteAudio',params)
+    }
+}

+ 11 - 0
src/api/media/common.js

@@ -0,0 +1,11 @@
+import { get, post } from "@/api/index";
+export default{
+    /**
+     * 获取品种列表
+     * @param {*} params 
+     * @returns 
+     */
+    getPermissionList: params => {
+        return get('/chart_permission/list',params)
+    }
+}

+ 6 - 0
src/api/media/index.js

@@ -0,0 +1,6 @@
+import apiAudio from './audio'
+import apiMediaCommon from './common'
+export {
+    apiAudio,
+    apiMediaCommon
+}

+ 0 - 0
src/api/media/video.js


+ 59 - 48
src/components/ImageUpload.vue

@@ -1,6 +1,6 @@
 <script setup>
 import { ref, reactive, watch } from 'vue'
-import { Plus } from '@element-plus/icons-vue'
+import { Plus, Delete } from '@element-plus/icons-vue'
 
 const props = defineProps({
     width:{
@@ -18,6 +18,10 @@ const props = defineProps({
     text:{
         type:String,
         default:'点击上传图片'
+    },
+    uploadHint:{
+        type:String,
+        default:''
     }
 })
 
@@ -31,7 +35,7 @@ function handleRemove() {
     emits('remove')
 }
 function showImage(){
-    emits('showImage',[this.imgUrl])
+    emits('showImage',[props.imgUrl])
 }
 </script>
 
@@ -40,7 +44,6 @@ function showImage(){
         :key="uploadKey">
         <div class="upload-box" :style="{'width':props.width,'height':props.height}">
             <template v-if="!imgUrl.length">
-                <!-- <i class="el-icon-plus" style="font-size: 24px;"></i> -->
                 <el-icon :size="24"><Plus /></el-icon>
                 <p class="form-hint">{{ text }}</p>
             </template>
@@ -48,65 +51,73 @@ function showImage(){
                 <img class="upload-img" :src="imgUrl" alt="配图">
                 <span class="upload-mask" @click.stop="showImage">
                     <span class="mask-icon" @click.stop="handleRemove">
-                        <i class="el-icon-delete"></i>
+                        <el-icon :size="24"><Delete /></el-icon>
                     </span>
                 </span>
             </template>
         </div>
     </el-upload>
+    <span class="upload-hint" v-if="props.uploadHint.length">{{ props.uploadHint }}</span>
 </template>
 
 <style scoped lang="scss">
 .el-upload {
-        .upload-box {
-            position: relative;
-            /* width: 120px;
-            height: 120px; */
-            background-color: #F5F7F9;
-            border: 1px dashed #DCDFE6;
-            display: flex;
-            flex-direction: column;
-            align-items: center;
-            justify-content: center;
-            box-sizing: border-box;
-            padding: 4px;
-            overflow: hidden;
+    flex-wrap: wrap;
+    .upload-box {
+        position: relative;
+        /* width: 120px;
+        height: 120px; */
+        background-color: #F5F7F9;
+        border: 1px dashed #DCDFE6;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        box-sizing: border-box;
+        padding: 4px;
+        overflow: hidden;
 
-            &:hover {
-                border: 1px dashed #3375e1;
+        &:hover {
+            border: 1px dashed #3375e1;
 
-                .upload-mask {
-                    opacity: 1;
-                }
-            }
-            .form-hint {
-                margin-top: 10px;
-                font-size: 12px;
-                color: #999999;
-            }
-
-            .upload-img,
             .upload-mask {
-                width: 100%;
-                height: 100%;
+                opacity: 1;
             }
-            .upload-mask {
-                position: absolute;
-                left: 0;
-                top: 0;
-                cursor: default;
-                text-align: center;
-                color: #fff;
-                opacity: 0;
-                font-size: 20px;
-                background-color: rgba(0, 0, 0, .5);
-                transition: opacity .3s;
-                z-index: 2;
-                line-height: 120px;
-                .mask-icon {
-                    cursor: pointer;
-                }
+        }
+        .form-hint {
+            margin-top: 10px;
+            font-size: 12px;
+            color: #999999;
+        }
+
+        .upload-img,
+        .upload-mask {
+            width: 100%;
+            height: 100%;
+        }
+        .upload-mask {
+            position: absolute;
+            left: 0;
+            top: 0;
+            cursor: default;
+            text-align: center;
+            color: #fff;
+            opacity: 0;
+            font-size: 20px;
+            background-color: rgba(0, 0, 0, .5);
+            transition: opacity .3s;
+            z-index: 2;
+            line-height: 120px;
+            .mask-icon {
+                cursor: pointer;
             }
         }
     }
+}
+.upload-hint{
+    display: block;
+    width:100%;
+    color:#DCDCDC;
+    font-size: 12px;
+}
 </style>

+ 2 - 2
src/layout/components/LeftWrap.vue

@@ -75,10 +75,10 @@ function getNavList(){
             ]
         },
     ]
-    return 
+    
   apiSystemRole.menuData().then(res=>{
     if(res.Ret===200){
-      navList.value=res.Data||[]
+      //navList.value=res.Data||[]
     }
   })
 }

+ 2 - 2
src/views/Login.vue

@@ -22,8 +22,6 @@ async function submitForm(formEl) {
   await formEl.validate((valid, fields) => {
     if (valid) {
       console.log('submit!')
-      router.replace('/customer/tempUserList')
-      return 
       const t = new Date().getTime()
       const md5key = 'MiQM9YUdf89T2uIH'
       apiSystemCommon.login({
@@ -53,6 +51,8 @@ async function submitForm(formEl) {
 // 获取菜单跳转到第一个菜单
 function getMenuList() {
   apiSystemRole.menuData().then(res => {
+    router.replace('/customer/tempUserList')
+    return 
     if (res.Ret === 200) {
       const arr = res.Data || []
       if (arr.length === 0) {

+ 73 - 26
src/views/author/List.vue

@@ -1,6 +1,9 @@
 <script setup>
 import { ref, reactive } from 'vue'
 import { Search } from '@element-plus/icons-vue'
+import { ElMessage } from 'element-plus'
+import { apiAuthor } from '@/api/author';
+import {cloneDeep} from 'lodash'
 
 const tableQuery = reactive({
     keyWord:'',
@@ -12,26 +15,29 @@ const tableQuery = reactive({
 })
 
 const tableColumns = [
-    {label:'研究员名称',key:'name',},
-    {label:'简介',key:'intor'},
-    {label:'照片',key:'cover',},
-    {label:'添加时间',key:'time',width:250,sortable:true},
+    {label:'研究员名称',key:'Name',},
+    {label:'简介',key:'Introduction'},
+    {label:'照片',key:'HeadImgURL',},
+    {label:'添加时间',key:'CreatedTime',width:250},
 ]
 let modifyAuthorShow = ref(false)
 let curAuthorData = ref({})
 function handleModifyAuthorShow(data){
-    curAuthorData.value = data
+    curAuthorData.value = cloneDeep(data)
+    formRef.value?.clearValidate()
     modifyAuthorShow.value = true
 }
 const tableData = ref([])
 function getTableData(){
-    tableData.value = [
-        {
-            name:'aaa',
-            time:'2024-08-02 12:30',
-            cover:'https://hongze.oss-accelerate.aliyuncs.com/static/images/202207/20220720/K6rmSx3MNUwnJxhlPMV62swe3FLV.jpg'
-        }
-    ]
+    apiAuthor.getAuthorList({
+        PageSize:tableQuery.pageSize,
+        CurrentIndex:tableQuery.currentPage,
+        Keyword:tableQuery.keyWord
+    }).then(res=>{
+        if(res.Ret!==200) return 
+        tableData.value = res.Data.List||[]
+        tableQuery.totals = res.Data.Paging.Totals||0
+    })
 }
 getTableData()
 function handlePageChange(page){
@@ -41,11 +47,45 @@ function handlePageChange(page){
 
 function handlePreviewPic(){}
 
-function handleSaveAuthor(){}
-
-function handleSortChange({order,prop}){
-    // ascending 
+function handleUploadImg(file){
+    //图片大小和格式限制
+    const {size,type} = file.file
+    const sizeLimit = 200
+    if(!['image/png','image/jpeg'].includes(type)){
+        ElMessage.warning('仅支持png、jpg格式的图片')
+        return
+    }
+    if(size>sizeLimit){
+        ElMessage.warning('研究员头像不能超过200kb')
+        return
+    }
+    let form = new FormData();
+    form.append('File',file.file);
+    apiAuthor.uploadAuthorPic(form).then(res=>{
+        if(res.Ret!==200) return 
+        curAuthorData.value.HeadImgURL = res.Data?.Url||''
+    })
 }
+const rules = {
+    //Introduction:[{required:true,message:'请输入简介'}],
+    HeadImgURL:[{required:true,message:'请上传头像'}]
+}
+const formRef = ref(null)
+async function handleSaveAuthor(){
+    try{
+        await formRef.value?.validate()
+    }catch(e){ return }
+    const {Id,HeadImgURL,Introduction,Name} = curAuthorData.value
+    apiAuthor.editAuthor({
+        Id,HeadImgUrl:HeadImgURL,Introduction,Name
+    }).then(res=>{
+        if(res.Ret!==200) return 
+        ElMessage.success('配置成功')
+        getTableData()
+        modifyAuthorShow.value = false
+    })
+}
+
 </script>
 
 <template>
@@ -56,23 +96,26 @@ function handleSortChange({order,prop}){
                 :prefix-icon="Search" 
                 clearable 
                 style="width:426px;" 
-                placeholder="研究员名称"></el-input>
+                placeholder="研究员名称" 
+                @input="handlePageChange(1)"/>
         </div>
         <div class="table-box">
-            <el-table stripe border :data="tableData" @sort-change="handleSortChange">
+            <el-table stripe border :data="tableData">
                 <el-table-column 
                     align="center"
                     v-for="column in tableColumns" :key="column.key"
                     :prop="column.key" :label="column.label" :sortable="column.sortable" :width="column.width">
                     <template #default="{row}">
-                        <div v-if="column.key==='cover'" @click="handlePreviewPic(row)" style="color:#086CE0;cursor: pointer;">
+                        <div v-if="column.key==='HeadImgURL'" @click="handlePreviewPic(row)" style="color:#086CE0;cursor: pointer;">
                             <el-image 
+                                v-if="row[column.key]"
                                 fit="cover"
                                 :src="row[column.key]||''" 
                                 :preview-src-list="[row[column.key]||'']" 
                                 style="display: inline-block;width:60px;height: 60px;" preview-teleported/>
+                            <span v-else style="display: inline-block;width:60px;height: 60px;line-height: 60px;">-</span> 
                         </div>
-                        <span v-else>{{ row[column.key] }}</span>
+                        <span v-else>{{ row[column.key]||'-' }}</span>
                     </template>
                 </el-table-column>
                 <el-table-column label="操作" align="center">
@@ -84,7 +127,7 @@ function handleSortChange({order,prop}){
             <el-pagination
                 background
                 layout="total,prev,pager,next,jumper"
-                :current-page="tableQuery.page"
+                :current-page="tableQuery.currentPage"
                 :page-size="tableQuery.pageSize"
                 :total="tableQuery.totals"
                 @current-change="handlePageChange"
@@ -94,17 +137,21 @@ function handleSortChange({order,prop}){
     </div>
     <el-dialog v-model="modifyAuthorShow" title="编辑作者" width="646px" draggable>
         <div class="content-wrap">
-            <el-form label-width="95px" label-position="left">
+            <el-form label-width="95px" label-position="left" :rules="rules" ref="formRef" :model="curAuthorData">
                 <el-form-item label="研究员名称">
-                    张三
+                    {{ curAuthorData.Name||'-' }}
                 </el-form-item>
-                <el-form-item label="简介">
-                    <el-input type="textarea" placeholder="请输入作者简介"></el-input>
+                <el-form-item label="简介" prop="Introduction">
+                    <el-input type="textarea" placeholder="请输入作者简介" v-model="curAuthorData.Introduction"></el-input>
                 </el-form-item>
-                <el-form-item label="照片">
+                <el-form-item label="照片" prop="HeadImgURL">
                     <ImageUpload
+                        :imgUrl="curAuthorData.HeadImgURL"
+                        uploadHint="支持jpg、jpeg、png等格式,建议上传宽高比例为1:1的图片"
                         width="120px"
                         height="120px"
+                        @upload="handleUploadImg"
+                        @remove="curAuthorData.HeadImgURL=''"
                     ></ImageUpload>
                 </el-form-item>
             </el-form>

+ 29 - 7
src/views/customer/TempUserList.vue

@@ -1,23 +1,24 @@
 <script setup>
 import { ref, reactive } from 'vue'
 import { Search } from '@element-plus/icons-vue'
+import {apiCustomerUser} from '@/api/customer'
 
 const tableColumns = [
     {
         label:'手机号',
-        key:'mobile',
+        key:'Mobile',
         sortable:false
     },{
         label:'最近一次阅读时间',
-        key:'lastReadTime',
+        key:'LastReadTime',
         sortable:true
     },{
         label:'累计阅读次数',
-        key:'readNum',
+        key:'ReadCount',
         sortable:true
     },{
         label:'注册时间',
-        key:'loginTime',
+        key:'CreatedTime',
         sortable:true
     }
 ]
@@ -32,7 +33,18 @@ const tableQuery = reactive({
 })
 const tableData = ref([])
 function getTableData(){
-    tableData.value = [{mobile:'123456'},{mobile:'123456'}]
+    apiCustomerUser.getTempCustomList({
+        Keyword:tableQuery.keyWord,
+        CurrentIndex:tableQuery.currentPage,
+        PageSize:tableQuery.pageSize,
+        SortParam:tableQuery.sortParam,
+        SortType:tableQuery.sortType
+    }).then(res=>{
+        if(res.Ret!==200) return 
+
+        tableData.value = res.Data.List||[]
+        tableQuery.totals = res.Data.Paging.Totals||0
+    })
 }
 getTableData()
 function handlePageChange(page){
@@ -41,6 +53,14 @@ function handlePageChange(page){
 }
 function handleSortChange({order,prop}){
     // ascending 
+    const propMap = {
+        0:'CreatedTime',
+        1:'ReadCount',
+        2:'LastReadTime',
+    }
+    tableQuery.sortParam = propMap[prop]||2
+    tableQuery.sortType = order==='ascending'?1:0
+    getTableData()
 }
 </script>
 
@@ -51,7 +71,9 @@ function handleSortChange({order,prop}){
                 v-model="tableQuery.keyWord"
                 :prefix-icon="Search" clearable
                 style="width:400px"
-                placeholder="请输入手机号"></el-input>
+                placeholder="请输入手机号" 
+                @input="handlePageChange(1)"
+                />
         </div>
         <div class="table-box">
             <el-table stripe border :data="tableData" @sort-change="handleSortChange">
@@ -63,7 +85,7 @@ function handleSortChange({order,prop}){
             <el-pagination
                 background
                 layout="total,prev,pager,next,jumper"
-                :current-page="tableQuery.page"
+                :current-page="tableQuery.currentPage"
                 :page-size="tableQuery.pageSize"
                 :total="tableQuery.totals"
                 @current-change="handlePageChange"

+ 42 - 27
src/views/media/AudioList.vue

@@ -5,6 +5,8 @@ import { Search,Plus } from '@element-plus/icons-vue'
 import MediaUpload from './components/MediaUpload.vue';
 import MediaPlayer from './components/MediaPlayer.vue';
 
+import {apiAudio} from '@/api/media'
+
 
 const tableQuery = reactive({
     keyWord:'',
@@ -16,21 +18,24 @@ const tableQuery = reactive({
 })
 
 const tableColumns = [
-    {label:'音频名称',key:'name',},
-    {label:'研究员',key:'author',},
-    {label:'标签',key:'label',},
-    {label:'添加时间',key:'time',width:250,sortable:true}
+    {label:'音频名称',key:'mediaName',},
+    {label:'研究员',key:'authorName',},
+    {label:'标签',key:'permission_names',},
+    {label:'添加时间',key:'publishedTime',width:250,sortable:true}
 ]
 let mediaUploadShow = ref(false)
 
 const tableData = ref([])
 function getTableData(){
-    tableData.value = [
-        {
-            name:'aaa',
-            time:'2024-08-02 12:30'
-        }
-    ]
+    apiAudio.getAudioList({
+        PageSize:tableQuery.pageSize,
+        CurrentIndex:tableQuery.currentPage,
+        SortType:tableQuery.sortType,
+    }).then(res=>{
+        if(res.Ret!==200) return 
+        tableData.value = res.Data.List||[]
+        tableQuery.totals = res.Data.Paging.Totals||0
+    })
 }
 getTableData()
 function handlePageChange(page){
@@ -39,23 +44,24 @@ function handlePageChange(page){
 }
 
 let mediaPlayerShow = ref(false)
-function handlePreviewAudio(row){
+function handlePreviewAudio(data={}){
+    setCurData(data)
     mediaPlayerShow.value = true
 }
 let curData = ref({})
-function handleUploadShow(data={}){
+function setCurData(data={}){
     curData.value = {
-        fileUrl:data.url||'',
-        mediaName:data.name||'',
-        author:data.author||'',
-        labels:data.labels||'',
-        mediaCover:data.pic||'',
+        fileUrl:data.src||'',
+        mediaName:data.mediaName||'',
+        author:data.authorId||'',
+        labels:data.permissionIds||'',
+        mediaCover:data.coverSrc||'',
     }
-    mediaUploadShow.value = true
 }
 
-function handleEdit(data){
-    handleUploadShow(data)
+function handleEdit(data={}){
+    setCurData(data)
+    mediaUploadShow.value = true
 }
 function handleDelete(data){
     ElMessageBox.confirm(
@@ -68,16 +74,24 @@ function handleDelete(data){
         }
     )
     .then(() => {
-        ElMessage.success('删除成功')
+        apiAudio.deleteAudio({
+            AudioId:data.mediaId
+        }).then(res=>{
+            if(res.Ret!==200) return 
+            ElMessage.success('删除成功')
+            getTableData()
+        })
     }).catch(() => {})
 }
-function handleSortChange({order,prop}){}
+function handleSortChange({order,prop}){
+    tableQuery.sortType = order==='ascending'?1:0
+}
 </script>
 
 <template>
     <div class="audio-list-wrap">
         <div class="top-box">
-            <el-button type="primary" :icon="Plus" @click="handleUploadShow">上传音频</el-button>
+            <el-button type="primary" :icon="Plus" @click="handleEdit">上传音频</el-button>
             <el-input style="width:400px;margin-left: auto;" placeholder="音频名称" v-model="tableQuery.keyWord" :prefix-icon="Search" clearable></el-input>
         </div>
         <div class="table-box">
@@ -86,10 +100,10 @@ function handleSortChange({order,prop}){}
                     v-for="column in tableColumns" :key="column.key"
                     :prop="column.key" :label="column.label" :sortable="column.sortable" :width="column.width">
                     <template #default="{row}">
-                        <span v-if="column.key==='name'" @click="handlePreviewAudio(row)" style="color:#086CE0;cursor: pointer;">
-                            {{ row.name }}
+                        <span v-if="column.key==='mediaName'" @click="handlePreviewAudio(row)" style="color:#086CE0;cursor: pointer;">
+                            {{ row.mediaName }}
                         </span>
-                        <span v-else>{{ row[column.key] }}</span>
+                        <span v-else>{{ row[column.key]||'-' }}</span>
                     </template>
                 </el-table-column>
                 <el-table-column label="操作" >
@@ -118,7 +132,8 @@ function handleSortChange({order,prop}){}
     ></MediaUpload>
     <MediaPlayer 
         v-model:show="mediaPlayerShow"
-        title="123456"
+        :title="curData.mediaName"
+        :src="curData.fileUrl"
         mediaType="audio"
     >
     </MediaPlayer>

+ 7 - 3
src/views/media/components/MediaPlayer.vue

@@ -10,7 +10,11 @@ const props = defineProps({
     mediaType:{
         type:String,
         default:'audio'
-    }
+    },
+    src:{
+        type:String,
+        default:''
+    },
 })
 </script>
 
@@ -19,11 +23,11 @@ const props = defineProps({
         <div class="content-wrap">
             <div class="audio-wrap" v-if="props.mediaType==='audio'">
                 <audio style="width: 100%;outline: none;"
-                    controls autoplay src="https://web-ext-storage.dcloud.net.cn/uni-app/ForElise.mp3"></audio>
+                    controls autoplay :src="props.src"></audio>
             </div>
             <div class="video-wrap" v-if="props.mediaType==='video'">
                 <video style="width: 100%;height: 100%;max-height: 70vh;outline: none;" 
-                    controls src="https://hzstatic.hzinsights.com/static/yb/video/f6f99470ea7f42b61f91d43c1aa12766.mp4" autoplay>
+                    controls :src="props.src" autoplay>
                     您的浏览器暂不支持,请更换浏览器
                 </video>
             </div>

+ 128 - 15
src/views/media/components/MediaUpload.vue

@@ -1,8 +1,10 @@
 <script setup>
-import { objectEach } from 'highcharts';
 import { ref, reactive, computed, watch } from 'vue'
+import {apiAudio,apiMediaCommon} from '@/api/media'
+import { apiAuthor } from '@/api/author'
+import { ElMessage } from 'element-plus'
 
-
+const emits = defineEmits('save')
 const show = defineModel('show', { type: Boolean, default: false })
 const props = defineProps({
     mediaType:{
@@ -17,6 +19,7 @@ const props = defineProps({
             author:'',
             labels:'',
             mediaCover:'',
+            duration:0,
         }
     },
     modifyType:{
@@ -41,12 +44,16 @@ const dialogTitle = computed(()=>{
 const uploadAccept = computed(()=>{
     return props.mediaType==='audio'?'.mp3':'.mp4'
 })
+const uploadType = computed(()=>{
+    return props.mediaType==='audio'?'audio/mpeg':'video/mp4'
+})
 const mediaData = reactive({
     fileUrl:'',
     mediaName:'',
     author:'',
     labels:'',
     mediaCover:'',
+    duration:0,
 })
 watch(show,(newval)=>{
     if(newval){
@@ -58,29 +65,119 @@ watch(show,(newval)=>{
             author:'',
             labels:'',
             mediaCover:'',
+            duration:0
         })
     }
 })
 
+//获取研究员列表
+let authorList = ref([])
+function getAuthorList(){
+    apiAuthor.getAuthorList({
+        PageSize:999,
+        CurrentIndex:1,
+    }).then(res=>{
+        if(res.Ret!==200) return 
+        authorList.value = res.Data.List||[]
+    })
+}
+getAuthorList()
+//获取标签列表
+let labelList = ref([])
+function getLableList(){
+    apiMediaCommon.getPermissionList().then(res=>{
+        if(res.Ret!==200) return
+        labelList.value = res.Data.List||[]
+    })
+}
+getLableList()
 //点击上传按钮
 const uploadRef = ref(null)
 function handleUpload(){
     uploadRef.value?.$el.getElementsByTagName('input')[0].click()
 }
-function handleUploadMedia(file){
-    //console.log('aaa',file)
-    //上传成功后,赋值mediaData.fileUrl
-    mediaData.fileUrl = '123456'
+async function handleUploadMedia(file){
+    //如果是音频,则获取音频长度 单位秒
+    if(props.mediaType==='audio'){
+        mediaData.duration = await getAudioDuration(file)
+    }
+    const {type} = file.file
+    if(type!==uploadType.value){
+        ElMessage.warning(`仅支持${uploadAccept.value}格式的文件`)
+        return 
+    }
+
+    let form = new FormData();
+    form.append('File',file.file);
+    const res = props.mediaType==='audio'
+        ?await apiAudio.uploadAudioFile(form)
+        :'' 
+    if(res.Ret!==200) return 
+    mediaData.fileUrl = res.Data.Url||""
+}
+//获取音频长度
+function getAudioDuration(file){
+    return new Promise((resolve,reject)=>{
+        const audioContext = new AudioContext();
+        const fileReader = new FileReader();
+        fileReader.readAsArrayBuffer(file.file);
+
+        fileReader.onload = function() {
+        audioContext.decodeAudioData(fileReader.result)
+            .then((buffer) => {
+                resolve(buffer.duration||0)
+            })
+        };
+    })
+}
+
+//保存音频/视频
+const formRef = ref(null)
+const rules = {
+    fileUrl:[{required:true,message:'请上传文件'}],
+    mediaName:[{required:true,message:`请输入${mediaName.value}名称`}],
+    author:[{required:true,message:'请选择研究员'}],
+    labels:[{required:true,message:'请选择标签'}],
+    mediaCover:[{required:true,message:'请上传封面图片'}],
 }
+async function handleSave(){
+    try{
+        await formRef.value?.validate()
+    }catch(e){ return }
+    let res = null
+    const params = {
+        AnalystId:mediaData.author.Id,
+        AnalystName:mediaData.author.Name,
+        AudioName:mediaData.mediaName,
+        SrcUrl:mediaData.fileUrl,
+        PermissionIds:Array.isArray(mediaData.labels)?mediaData.labels.join(','):'',
+        DurationMillisecond:parseInt(mediaData.duration*1000)
+    }
+    const otherParams = {
+        AudioId:mediaData.mediaId
+    }
+    if(props.modifyType==='add'){
+        res = props.mediaType==='audio'
+        ? await apiAudio.addAudio(params)
+        : ''
+    }else{
+        res = props.mediaType==='audio'
+        ? await apiAudio.editAudio({...params,...otherParams})
+        : ''
+    }
+    if(res.Ret!==200) return 
+    ElMessage.success(`${props.modifyType==='add'?'添加':'编辑'}成功`)
+    show.value = false
+    emits('save')
 
-function handleSave(){}
+}
 </script>
 
 <template>
     <el-dialog v-model="show" :title="dialogTitle" width="530px" draggable>
         <div class="content-wrap">
-            <el-form label-width="95px" label-position="left">
-                <el-form-item prop="mediaUrl" class="upload-form-item">
+            <el-form label-width="95px" label-position="left" :model="mediaData" :rules="rules" ref="formRef">
+                <el-form-item prop="fileUrl" class="upload-form-item">
                     <el-input placeholder="请上传文件" v-model="mediaData.fileUrl" disabled>
                         <template #append>
                             <el-button 
@@ -100,21 +197,37 @@ function handleSave(){}
                         </template>
                     </el-input>
                 </el-form-item>
-                <el-form-item label="照片" v-if="props.mediaType==='video'">
+                <el-form-item prop="mediaCover" label="照片" v-if="props.mediaType==='video'">
                     <ImageUpload
                         :imgUrl="mediaData.mediaCover"
                         :width="ImageUploadWidth"
                         :height="ImageUploadHeight"
                     ></ImageUpload>
                 </el-form-item>
-                <el-form-item :label="`${mediaName}名称`">
+                <el-form-item  prop="mediaName" :label="`${mediaName}名称`">
                     <el-input v-model="mediaData.mediaName" placeholder="请输入名称"></el-input>
                 </el-form-item>
-                <el-form-item label="研究员名称">
-                    <el-select v-model="mediaData.author"></el-select>
+                <el-form-item prop="author" label="研究员名称">
+                    <el-select v-model="mediaData.author" value-key="Id">
+                        <el-option 
+                            v-for="item in authorList" 
+                            :key="item.Id"
+                            :label="item.Name"
+                            :value="item"></el-option>
+                    </el-select>
                 </el-form-item>
-                <el-form-item label="标签">
-                    <el-cascader style="width: 100%;" v-model="mediaData.labels"></el-cascader>
+                <el-form-item prop="labels" label="标签">
+                    <el-cascader style="width: 100%;" 
+                        v-model="mediaData.labels"
+                        :options="labelList"
+                        :props="{
+                            value:'id',
+                            label:'name',
+                            emitPath:false,
+                            multiple:true
+                        }"
+                        >
+                    </el-cascader>
                 </el-form-item>
             </el-form>
         </div>