Ver código fonte

运行记录优化0929

yuanchao 1 semana atrás
pai
commit
39d32ebf09

+ 157 - 12
pnpm-lock.yaml

@@ -35,6 +35,9 @@ importers:
       '@microsoft/fetch-event-source':
         specifier: ^2.0.1
         version: 2.0.1
+      '@types/echarts':
+        specifier: ^5.0.0
+        version: 5.0.0
       '@videojs-player/vue':
         specifier: ^1.0.0
         version: 1.0.0(@types/video.js@7.3.58)(video.js@7.21.6)(vue@3.5.12(typescript@5.3.3))
@@ -74,21 +77,30 @@ importers:
       crypto-js:
         specifier: ^4.2.0
         version: 4.2.0
+      date-fns:
+        specifier: ^4.1.0
+        version: 4.1.0
+      date.js:
+        specifier: ^0.3.3
+        version: 0.3.3
       dayjs:
         specifier: ^1.11.10
         version: 1.11.13
       diagram-js:
         specifier: ^12.8.0
         version: 12.8.1
+      dingtalk-jsapi:
+        specifier: ^3.1.0
+        version: 3.1.0
       driver.js:
         specifier: ^1.3.1
         version: 1.3.1
       echarts:
-        specifier: ^5.5.0
-        version: 5.5.1
+        specifier: ^5.6.0
+        version: 5.6.0
       echarts-wordcloud:
         specifier: ^2.1.0
-        version: 2.1.0(echarts@5.5.1)
+        version: 2.1.0(echarts@5.6.0)
       element-plus:
         specifier: 2.9.1
         version: 2.9.1(vue@3.5.12(typescript@5.3.3))
@@ -125,6 +137,9 @@ importers:
       mitt:
         specifier: ^3.0.1
         version: 3.0.1
+      moment:
+        specifier: ^2.30.1
+        version: 2.30.1
       nprogress:
         specifier: ^0.2.0
         version: 0.2.0
@@ -134,6 +149,9 @@ importers:
       pinia-plugin-persistedstate:
         specifier: ^3.2.1
         version: 3.2.3(pinia@2.2.8(typescript@5.3.3)(vue@3.5.12(typescript@5.3.3)))
+      pinyin:
+        specifier: ^4.0.0
+        version: 4.0.0
       qrcode:
         specifier: ^1.5.3
         version: 1.5.4
@@ -161,6 +179,9 @@ importers:
       vue-dompurify-html:
         specifier: ^4.1.4
         version: 4.1.4(vue@3.5.12(typescript@5.3.3))
+      vue-echarts:
+        specifier: ^7.0.3
+        version: 7.0.3(@vue/runtime-core@3.5.12)(echarts@5.6.0)(vue@3.5.12(typescript@5.3.3))
       vue-i18n:
         specifier: 9.10.2
         version: 9.10.2(vue@3.5.12(typescript@5.3.3))
@@ -1826,6 +1847,10 @@ packages:
   '@types/d3@7.4.3':
     resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==}
 
+  '@types/echarts@5.0.0':
+    resolution: {integrity: sha512-5uc/16BlYpzH8kU/u8aeRRgY2FV6yRY7RjPnYfUFPowl0F3kvNgfaz09PmeVdLkqdAtMft3XkCfqiJPJjG2DNQ==}
+    deprecated: This is a stub types definition. echarts provides its own type definitions, so you do not need this installed.
+
   '@types/eslint@8.56.12':
     resolution: {integrity: sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==}
 
@@ -2656,6 +2681,10 @@ packages:
     resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
     engines: {node: '>= 0.8'}
 
+  commander@1.1.1:
+    resolution: {integrity: sha512-71Rod2AhcH3JhkBikVpNd0pA+fWsmAaVoti6OR38T76chA7vE3pSerS0Jor4wDw+tOueD2zLVvFOw5H0Rcj7rA==}
+    engines: {node: '>= 0.6.x'}
+
   commander@12.1.0:
     resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
     engines: {node: '>=18'}
@@ -2931,12 +2960,26 @@ packages:
     resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==}
     engines: {node: '>=12'}
 
+  date-fns@4.1.0:
+    resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
+
+  date.js@0.3.3:
+    resolution: {integrity: sha512-HgigOS3h3k6HnW011nAb43c5xx5rBXk8P2v/WIT9Zv4koIaVXiH2BURguI78VVp+5Qc076T7OR378JViCnZtBw==}
+
   dayjs@1.11.13:
     resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
 
   de-indent@1.0.2:
     resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
 
+  debug@3.1.0:
+    resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+
   debug@4.3.7:
     resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
     engines: {node: '>=6.0'}
@@ -2999,6 +3042,9 @@ packages:
   dijkstrajs@1.0.3:
     resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
 
+  dingtalk-jsapi@3.1.0:
+    resolution: {integrity: sha512-2W1XuOR3g/0eYbqXXOMKwmTSUzyIeKNIQ1DDgUrMmf3eNdfOb8ShcQZ02QNvn/j5Vpy6Pd0Yf+uRkWVB3Pl9gA==}
+
   dir-glob@3.0.1:
     resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
     engines: {node: '>=8'}
@@ -3057,8 +3103,8 @@ packages:
     peerDependencies:
       echarts: ^5.0.1
 
-  echarts@5.5.1:
-    resolution: {integrity: sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==}
+  echarts@5.6.0:
+    resolution: {integrity: sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==}
 
   ejs@3.1.10:
     resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==}
@@ -3727,6 +3773,9 @@ packages:
   keycode@2.2.1:
     resolution: {integrity: sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg==}
 
+  keypress@0.1.0:
+    resolution: {integrity: sha512-x0yf9PL/nx9Nw9oLL8ZVErFAk85/lslwEP7Vz7s5SI1ODXZIgit3C5qyWjw4DxOuO/3Hb4866SQh28a1V1d+WA==}
+
   keyv@4.5.4:
     resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
 
@@ -4012,6 +4061,9 @@ packages:
   moddle@6.2.3:
     resolution: {integrity: sha512-bLVN+ZHL3aKnhxc19XtjUfvdJsS3EsiEJC7bT6YPD11qYmTzvsxrGgyYz1Ouof7TZuGw0lDJ1OLmEnxcpQWk3Q==}
 
+  moment@2.30.1:
+    resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
+
   mpd-parser@0.22.1:
     resolution: {integrity: sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==}
     hasBin: true
@@ -4020,6 +4072,9 @@ packages:
     resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==}
     engines: {node: '>=10'}
 
+  ms@2.0.0:
+    resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
+
   ms@2.1.3:
     resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
 
@@ -4252,6 +4307,22 @@ packages:
       typescript:
         optional: true
 
+  pinyin@4.0.0:
+    resolution: {integrity: sha512-vHpV5K+vpp6XUUpZNGRDuHoN+1xcmieM3EWlH4QjSX2kkpG/gVOwpqwV9EOJ9x9c9UERFKeLml5XVSukE/PLgQ==}
+    engines: {install-node: ^18.0.0}
+    hasBin: true
+    peerDependencies:
+      '@node-rs/jieba': ^1.6.0
+      nodejieba: ^3.4.4
+      segmentit: ^2.0.3
+    peerDependenciesMeta:
+      '@node-rs/jieba':
+        optional: true
+      nodejieba:
+        optional: true
+      segmentit:
+        optional: true
+
   pkcs7@1.0.4:
     resolution: {integrity: sha512-afRERtHn54AlwaF2/+LFszyAANTCggGilmcmILUzEjvs3XgFZT+xE6+QWQcAGmu4xajy+Xtj7acLOPdx5/eXWQ==}
     hasBin: true
@@ -4355,6 +4426,9 @@ packages:
     resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
     engines: {node: '>=0.4.0'}
 
+  promise-polyfill@7.1.2:
+    resolution: {integrity: sha512-FuEc12/eKqqoRYIGBrUptCBRhobL19PS2U31vMNTfyck1FxPyMfgsXyW4Mav85y/ZN1hop3hOwRlUDok23oYfQ==}
+
   proxy-from-env@1.1.0:
     resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
 
@@ -5007,6 +5081,17 @@ packages:
       terser:
         optional: true
 
+  vue-demi@0.13.11:
+    resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==}
+    engines: {node: '>=12'}
+    hasBin: true
+    peerDependencies:
+      '@vue/composition-api': ^1.0.0-rc.1
+      vue: ^3.0.0-0 || ^2.6.0
+    peerDependenciesMeta:
+      '@vue/composition-api':
+        optional: true
+
   vue-demi@0.14.10:
     resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
     engines: {node: '>=12'}
@@ -5023,6 +5108,16 @@ packages:
     peerDependencies:
       vue: ^2.7.0 || ^3.0.0
 
+  vue-echarts@7.0.3:
+    resolution: {integrity: sha512-/jSxNwOsw5+dYAUcwSfkLwKPuzTQ0Cepz1LxCOpj2QcHrrmUa/Ql0eQqMmc1rTPQVrh2JQ29n2dhq75ZcHvRDw==}
+    peerDependencies:
+      '@vue/runtime-core': ^3.0.0
+      echarts: ^5.5.1
+      vue: ^2.7.0 || ^3.1.1
+    peerDependenciesMeta:
+      '@vue/runtime-core':
+        optional: true
+
   vue-eslint-parser@9.4.3:
     resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==}
     engines: {node: ^14.17.0 || >=16.0.0}
@@ -5200,8 +5295,8 @@ packages:
   zeebe-bpmn-moddle@1.7.0:
     resolution: {integrity: sha512-eZ6OXSt0c4n9V/oN/46gTlwDIS3GhWQLt9jbM5uS/YryB4yN8wdrrKrtw+TpyNy0SSKWXNDHyC83nCA2blPO3Q==}
 
-  zrender@5.6.0:
-    resolution: {integrity: sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==}
+  zrender@5.6.1:
+    resolution: {integrity: sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==}
 
 snapshots:
 
@@ -6823,6 +6918,10 @@ snapshots:
       '@types/d3-transition': 3.0.9
       '@types/d3-zoom': 3.0.8
 
+  '@types/echarts@5.0.0':
+    dependencies:
+      echarts: 5.6.0
+
   '@types/eslint@8.56.12':
     dependencies:
       '@types/estree': 1.0.6
@@ -7960,6 +8059,10 @@ snapshots:
     dependencies:
       delayed-stream: 1.0.0
 
+  commander@1.1.1:
+    dependencies:
+      keypress: 0.1.0
+
   commander@12.1.0: {}
 
   commander@2.20.3: {}
@@ -8246,10 +8349,22 @@ snapshots:
 
   dargs@8.1.0: {}
 
+  date-fns@4.1.0: {}
+
+  date.js@0.3.3:
+    dependencies:
+      debug: 3.1.0
+    transitivePeerDependencies:
+      - supports-color
+
   dayjs@1.11.13: {}
 
   de-indent@1.0.2: {}
 
+  debug@3.1.0:
+    dependencies:
+      ms: 2.0.0
+
   debug@4.3.7:
     dependencies:
       ms: 2.1.3
@@ -8316,6 +8431,10 @@ snapshots:
 
   dijkstrajs@1.0.3: {}
 
+  dingtalk-jsapi@3.1.0:
+    dependencies:
+      promise-polyfill: 7.1.2
+
   dir-glob@3.0.1:
     dependencies:
       path-type: 4.0.0
@@ -8368,14 +8487,14 @@ snapshots:
 
   eastasianwidth@0.2.0: {}
 
-  echarts-wordcloud@2.1.0(echarts@5.5.1):
+  echarts-wordcloud@2.1.0(echarts@5.6.0):
     dependencies:
-      echarts: 5.5.1
+      echarts: 5.6.0
 
-  echarts@5.5.1:
+  echarts@5.6.0:
     dependencies:
       tslib: 2.3.0
-      zrender: 5.6.0
+      zrender: 5.6.1
 
   ejs@3.1.10:
     dependencies:
@@ -9086,6 +9205,8 @@ snapshots:
 
   keycode@2.2.1: {}
 
+  keypress@0.1.0: {}
+
   keyv@4.5.4:
     dependencies:
       json-buffer: 3.0.1
@@ -9392,6 +9513,8 @@ snapshots:
     dependencies:
       min-dash: 4.2.2
 
+  moment@2.30.1: {}
+
   mpd-parser@0.22.1:
     dependencies:
       '@babel/runtime': 7.26.0
@@ -9401,6 +9524,8 @@ snapshots:
 
   mrmime@2.0.0: {}
 
+  ms@2.0.0: {}
+
   ms@2.1.3: {}
 
   muggle-string@0.3.1: {}
@@ -9588,6 +9713,10 @@ snapshots:
     optionalDependencies:
       typescript: 5.3.3
 
+  pinyin@4.0.0:
+    dependencies:
+      commander: 1.1.1
+
   pkcs7@1.0.4:
     dependencies:
       '@babel/runtime': 7.26.0
@@ -9684,6 +9813,8 @@ snapshots:
 
   progress@2.0.3: {}
 
+  promise-polyfill@7.1.2: {}
+
   proxy-from-env@1.1.0: {}
 
   punycode.js@2.3.1: {}
@@ -10410,6 +10541,10 @@ snapshots:
       sass: 1.81.0
       terser: 5.36.0
 
+  vue-demi@0.13.11(vue@3.5.12(typescript@5.3.3)):
+    dependencies:
+      vue: 3.5.12(typescript@5.3.3)
+
   vue-demi@0.14.10(vue@3.5.12(typescript@5.3.3)):
     dependencies:
       vue: 3.5.12(typescript@5.3.3)
@@ -10422,6 +10557,16 @@ snapshots:
     transitivePeerDependencies:
       - '@vue/composition-api'
 
+  vue-echarts@7.0.3(@vue/runtime-core@3.5.12)(echarts@5.6.0)(vue@3.5.12(typescript@5.3.3)):
+    dependencies:
+      echarts: 5.6.0
+      vue: 3.5.12(typescript@5.3.3)
+      vue-demi: 0.13.11(vue@3.5.12(typescript@5.3.3))
+    optionalDependencies:
+      '@vue/runtime-core': 3.5.12
+    transitivePeerDependencies:
+      - '@vue/composition-api'
+
   vue-eslint-parser@9.4.3(eslint@8.57.1):
     dependencies:
       debug: 4.3.7
@@ -10614,6 +10759,6 @@ snapshots:
 
   zeebe-bpmn-moddle@1.7.0: {}
 
-  zrender@5.6.0:
+  zrender@5.6.1:
     dependencies:
       tslib: 2.3.0

+ 2 - 2
src/api/pms/device/index.ts

@@ -46,8 +46,8 @@ export interface IotDeviceVO {
 
 // 设备台账 API
 export const IotDeviceApi = {
-  getMapDevice: async () => {
-    return await request.get({ url: `/rq/iot-device/map`})
+  getMapDevice: async (params:any) => {
+    return await request.get({ url: `/rq/iot-device/map`, params})
   },
   // 查询设备台账分页
   getIotDevicePage: async (params: any) => {

+ 2 - 2
src/api/pms/failure/index.ts

@@ -59,7 +59,7 @@ export const IotFailureReportApi = {
   exportIotFailureReport: async (params) => {
     return await request.download({ url: `/rq/iot-failure-report/export-excel`, params })
   },
-  updateIotMaintainProcess: async (id:any, type:any,assigneeUserId:any) => {
-    return await request.put({ url: `/rq/iot-failure-report/process-info?id=`+id+"&type="+type+"&assigneeUserId="+assigneeUserId })
+  updateIotMaintainProcess: async (processId:any,id:any, type:any,assigneeUserId:any, trans:any) => {
+    return await request.put({ url: `/rq/iot-failure-report/process-info?processId=`+processId+`&id=`+id+`&type=`+type+`&assigneeUserId=`+assigneeUserId+`&trans=`+ trans})
   },
 }

+ 4 - 0
src/components/UploadFile/src/FileUpload.vue

@@ -135,6 +135,9 @@ import {
 
 // 组件参数 - 保持不变
 const props = defineProps({
+  deviceId:{
+    type: String,
+  },
   allowFolderUpload: {
     type: Boolean,
     default: true
@@ -378,6 +381,7 @@ const startUpload = async () => {
       // 发送请求
       xhr.open('POST', props.uploadUrl, true);
       xhr.setRequestHeader('tenant-id', 1);
+      xhr.setRequestHeader('device-id', props.deviceId);
       xhr.send(formData);
 
     } catch (error) {

+ 2 - 2
src/components/UploadFile/src/useUpload.ts

@@ -74,9 +74,9 @@ export const useUpload = () => {
         })
         .then(() => {
           // 1.4. 记录文件信息到后端(异步)
-          createFile(presignedInfo, fileName, options.file)
+          createFile(presignedInfoPath, fileName, options.file)
           // 通知成功,数据格式保持与后端上传的返回结果一致
-          return { data: presignedInfo.url }
+          return { data: presignedInfoPath.url }
         })
     } else {
       // 模式二:后端上传

+ 11 - 3
src/components/UserSelectForm/index.vue

@@ -42,6 +42,8 @@
 import { defaultProps, handleTree } from '@/utils/tree'
 import * as DeptApi from '@/api/system/dept'
 import * as UserApi from '@/api/system/user'
+import {companyLevelChildrenDepts} from "@/api/system/dept";
+import {companyDeptsEmployee} from "@/api/system/user";
 
 defineOptions({ name: 'UserSelectForm' })
 const emit = defineEmits<{
@@ -78,12 +80,18 @@ const transferUserList = computed(() => {
 const open = async (id: number, selectedList?: any[]) => {
   activityId.value = id
   resetForm()
-
   // 加载部门、用户列表
-  const deptData = await DeptApi.getSimpleDeptList()
+  // const deptData = await DeptApi.getSimpleDeptList()
+  const deptData = await DeptApi.companyLevelChildrenDepts()
   deptList.value = deptData // 保存扁平结构的部门数据
   deptTree.value = handleTree(deptData) // 转换成树形结构
-  userList.value = await UserApi.getSimpleUserList()
+  // userList.value = await UserApi.getSimpleUserList()
+  const ids = deptData.map(item => item.id)
+  const params = {
+    deptIds: ids
+  };
+  debugger
+  userList.value = await UserApi.companyDeptsEmployee(params)
 
   // 初始状态下,过滤列表等于所有用户列表
   filteredUserList.value = [...userList.value]

+ 6 - 2
src/locales/en.ts

@@ -640,7 +640,8 @@ export default {
     save:'Save',
     return:'Return',
     useProject:'useProject',
-    assetOwner:'assetOwnership'
+    assetOwner:'assetOwnership',
+    deptHolder:'please select depart'
   },
   file:{
     name:'FileName',
@@ -911,7 +912,8 @@ export default {
     maintainItem:'Please enter maintainItem',
     kmHour: 'operating km/hour',
     kmHourHolder:'please enter operating km/hour',
-    oaFlowNo:'oaFlowNo'
+    oaFlowNo:'oaFlowNo',
+    quantityHolder:'Please enter quantity',
   },
   workOrderMaterial:{
     materialCode:'MaterialCode',
@@ -927,7 +929,9 @@ export default {
     costCenter:'CostCenter',
     storageLocation:'StorageLocation',
     unit:'Unit',
+    unitHolder:'Please enter unit',
     unitPrice:'UnitPrice',
+    unitPriceHolder:'Please enter unitPrice',
     total:'Total',
     source:'Source',
     ConsumptionQuantity:'ConsumptionQuantity',

+ 6 - 2
src/locales/zh-CN.ts

@@ -637,7 +637,8 @@ export default {
     save:'保存',
     return:'返回',
     useProject:'使用项目',
-    assetOwner:'资产归属'
+    assetOwner:'资产归属',
+    deptHolder:'请选择部门机构'
   },
   file:{
     name:'文件名称',
@@ -907,7 +908,8 @@ export default {
     maintainItem:'维修项目',
     kmHour: '运行公里/小时',
     kmHourHolder:'请输入运转公里/小时',
-    oaFlowNo:'oa流程号'
+    oaFlowNo:'oa流程号',
+    quantityHolder:'请输入数量'
   },
   workOrderMaterial:{
     materialCode:'物料编码',
@@ -923,7 +925,9 @@ export default {
     costCenter:'成本中心',
     storageLocation:'库存地点',
     unit:'单位',
+    unitHolder:'请输入单位',
     unitPrice:'单价',
+    unitPriceHolder:'请输入单价',
     total:'总库存数量',
     source:'来源',
     ConsumptionQuantity:'消耗数量',

+ 1 - 1
src/router/modules/remaining.ts

@@ -982,7 +982,7 @@ const remainingRouter: AppRouteRecordRaw[] = [
       },
       {
         path: 'maintain/edit/:id(\\d+)',
-        component: () => import('@/views/pms/maintain/IotMaintain.vue'),
+        component: () => import('@/views/pms/maintain/IotMaintainAddEdit.vue'),
         name: 'MaintainEdit',
         meta: {
           noCache: true,

+ 32 - 7
src/views/bpm/processInstance/detail/ProcessInstanceOperationButton.vue

@@ -36,7 +36,19 @@
               :rule="approveForm.rule"
             />
           </el-card>
-          <el-form-item label="负责人" prop="assigneeUserId" v-if="processInstance.name==='故障上报流程'||processInstance.name==='委外维修工单流程'">
+
+          <el-form-item label="是否转工单" prop="ifTrans">
+            <el-select v-model="approveReasonForm.ifTrans" placeholder="请选择是否转工单" clearable @change="ifShowApproval">
+              <el-option
+                v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
+                :key="dict.label"
+                :label="dict.label"
+                :value="dict.value"
+              />
+            </el-select>
+          </el-form-item>
+
+          <el-form-item label="负责人" prop="assigneeUserId" v-if="processInstance.name==='故障上报流程'&&approveReasonForm.ifTrans">
             <el-select v-model="approveReasonForm.assigneeUserId" filterable clearable style="width: 100%">
               <el-option
                 v-for="item in deptUsers"
@@ -47,7 +59,7 @@
             </el-select>
           </el-form-item>
 
-          <el-form-item label="维修类型" v-if="processInstance.name==='故障上报流程'" prop="type">
+          <el-form-item label="维修类型" v-if="processInstance.name==='故障上报流程'&&approveReasonForm.ifTrans" prop="type">
             <el-select v-model="approveReasonForm.type">
               <el-option
                 v-for="dict in getStrDictOptions(DICT_TYPE.PMS_MAIN_TYPE)"
@@ -68,7 +80,7 @@
           <el-form-item
             label="下一个节点的审批人"
             prop="nextAssignees"
-            v-if="nextAssigneesActivityNode.length > 0"
+            v-if="ifShow"
           >
             <div class="ml-10px -mt-15px -mb-35px">
               <ProcessInstanceTimeline
@@ -604,6 +616,7 @@ const approveReasonForm = reactive({
   nextAssignees: {},
   type:undefined,
   assigneeUserId: undefined,
+  ifTrans: undefined,
 })
 const approveReasonRule = computed(() => {
   return {
@@ -614,7 +627,15 @@ const approveReasonRule = computed(() => {
     nextAssignees: [{ required: true, message: '审批人不能为空', trigger: 'blur' }]
   }
 })
-
+const ifShow = ref(false)
+const ifShowApproval = ()=>{
+  // if (props.processInstance.name==='故障上报流程') {
+  //   debugger
+  //   ifShow.value = !approveReasonForm.ifTrans
+  // } else {
+    ifShow.value = nextAssigneesActivityNode.value.length > 0&&!approveReasonForm.ifTrans
+  // }
+}
 // 拒绝表单
 const rejectFormRef = ref<FormInstance>()
 const rejectReasonForm = reactive({
@@ -648,6 +669,7 @@ const transferFormRule = reactive<FormRules<typeof transferForm>>({
   reason: [{ required: true, message: '审批意见不能为空', trigger: 'blur' }]
 })
 const transferFormRuleType = reactive<FormRules<typeof transferForm>>({
+  ifTrans: [{ required: true, message: '是否专工单不能为空', trigger: 'change' }],
   type: [{ required: true, message: '维修类型不能为空', trigger: 'change' }],
   reason: [
     { required: reasonRequire.value, message: nodeTypeName + '意见不能为空', trigger: 'blur' }
@@ -815,8 +837,10 @@ const handleAudit = async (pass: boolean, formRef: FormInstance | undefined) =>
     }
 
     if (pass) {
-      const nextAssigneesValid = validateNextAssignees()
-      if (!nextAssigneesValid) return
+      if (props.processInstance.name==='故障上报流程'&&!approveReasonForm.ifTrans) {
+        const nextAssigneesValid = validateNextAssignees()
+        if (!nextAssigneesValid) return
+      }
       const variables = getUpdatedProcessInstanceVariables()
       // 审批通过数据
       const data = {
@@ -913,7 +937,8 @@ const handleTransferType = async (formRef: FormInstance | undefined) => {
     if (!approveFormRef.value) return
     await approveFormRef.value.validate()
     // 1.2 提交转交
-    await IotFailureReportApi.updateIotMaintainProcess(props.processInstance.businessKey, approveReasonForm.type, approveReasonForm.assigneeUserId);
+    debugger
+    await IotFailureReportApi.updateIotMaintainProcess(props.processInstance.id, props.processInstance.businessKey, approveReasonForm.type, approveReasonForm.assigneeUserId,approveReasonForm.ifTrans);
     await handleAudit(true, formRef)
     // await TaskApi.transferTask(data)
     // transferFormRef.value.resetFields()

+ 2 - 1
src/views/pms/iotinfo/IotInfoFormTree.vue

@@ -34,6 +34,7 @@
           @uploadSuccess="handleUploadSuccess"
           @uploadError="handleUploadError"
           @uploadComplete="handleUploadComplete"
+          :deviceId="props.classId"
         />
       </el-form-item>
       <el-form-item :label="t('fileInfo.fileType')" prop="fileType">
@@ -163,6 +164,7 @@ const submitForm = async () => {
     dialogVisible.value = false
     // 发送操作成功的事件
     emit('success')
+    debugger
   } finally {
     formLoading.value = false
   }
@@ -189,7 +191,6 @@ const handleUploadSuccess = (data) => {
     formData.value.folderTree = []
   }
   formData.value.folderTree.push(data.response.data);
-  console.log('777777777777777'+JSON.stringify(formData.value.folderTree))
   message.success(`"${data.name}" 上传成功`);
 };
 

+ 5 - 5
src/views/pms/iotopeationfill/index1.vue

@@ -78,10 +78,10 @@
                       v-if="item.type === 'enum' && item.description !== null"
                       style="width: 200px">
                       <el-option
-                        v-for="dict in getIntDictOptions(item.description)"
+                        v-for="dict in (item.name === '非生产原因' ? getIntDictOptions(item.description) : getStrDictOptions(item.description))"
                         :key="dict.label"
                         :label="dict.label"
-                        :value="dict.value"
+                        :value="item.name === '非生产原因' ? Number(dict.value) : dict.value.toString()"
                       />
                     </el-select>
                     <el-input
@@ -107,10 +107,10 @@
                                 style="width: 200px"
                                 filterable>
                       <el-option
-                        v-for="dict in getIntDictOptions(item.description)"
+                        v-for="dict in (item.name === '非生产原因' ? getIntDictOptions(item.description) : getStrDictOptions(item.description))"
                         :key="dict.label"
                         :label="dict.label"
-                        :value="dict.value"
+                        :value="item.name === '非生产原因' ? Number(dict.value) : dict.value.toString()"
                       />
                     </el-select>
                     <el-input
@@ -147,7 +147,7 @@ import { ElMessage } from 'element-plus'
 import moment from 'moment';
 import { format } from 'date-fns';
 import {cx} from "@fullcalendar/core/internal-common";
-import { DICT_TYPE, getIntDictOptions} from '@/utils/dict'
+import { DICT_TYPE, getIntDictOptions,getStrDictOptions} from '@/utils/dict'
 
 /** 运行记录填报 列表 */
 defineOptions({ name: 'FillOrderInfo' })

+ 1 - 0
src/views/pms/iotopeationfill/statistics.vue

@@ -137,6 +137,7 @@
     </el-col>
   </el-row>
 
+
   <!-- 第三行:消息统计行 -->
   <el-row>
     <el-col :span="24">

+ 10 - 41
src/views/pms/maintain/IotMaintainAddEdit.vue

@@ -165,7 +165,6 @@
             <el-col :span="8" >
               <el-form-item :label="t('iotMaintain.repairCosts')" prop="maintainFee" :rules="formData.type==='out'?feeRules:[]">
                 <el-input-number
-                  :disabled="formData.type==='in'"
                   v-model="formData.maintainFee"
                   :min="0"
                   :precision="2"
@@ -265,7 +264,7 @@
   </ContentWrap>
 
 
-  <ContentWrap>
+  <ContentWrap v-loading="formLoading">
     <ContentWrap>
       <!-- 搜索工作栏 -->
       <el-form class="-mb-15px" ref="queryFormRef" :inline="true" label-width="68px">
@@ -333,7 +332,7 @@
     <ChooseMaintain ref="maintainFormRef" @choose="maintainChoose" />
   </ContentWrap>
 
-  <ContentWrap v-if="materialIfShow">
+  <ContentWrap v-loading="formLoading" v-if="materialIfShow">
     <ContentWrap>
       <!-- 搜索工作栏 -->
       <el-form class="-mb-15px" ref="queryFormRef" :inline="true" label-width="68px">
@@ -356,42 +355,16 @@
     <ContentWrap>
       <el-table :data="filteredMaterials" style="width: 100%">
         <el-table-column prop="bomNodeId" :label="t('bomList.bomNode')" width="180" v-if="false"/>
-        <el-table-column prop="factory" :label="t('workOrderMaterial.factory')" width="180" v-if="!hideExtraColumns">
-          <template #default="scope">
-            <el-input
-              v-model="scope.row.factory"
-              size="small"
-              v-if="scope.row.materialSource === '手动添加'"
-            />
-            <span v-else>{{ scope.row.factory }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column prop="costCenter" :label="t('workOrderMaterial.costCenter')" width="180" v-if="!hideExtraColumns">
-          <template #default="scope">
-            <el-input
-              v-model="scope.row.costCenter"
-              size="small"
-              v-if="scope.row.materialSource === '手动添加'"
-            />
-            <span v-else>{{ scope.row.costCenter }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column prop="projectDepartment" :label="t('workOrderMaterial.storageLocation')"  width="180" v-if="!hideExtraColumns">
-          <template #default="scope">
-            <el-input
-              v-model="scope.row.projectDepartment"
-              size="small"
-              v-if="scope.row.materialSource === '手动添加'"
-            />
-            <span v-else>{{ scope.row.costCenter }}</span>
-          </template>
-        </el-table-column>
+        <el-table-column prop="factory" :label="t('workOrderMaterial.factory')" width="180" v-if="!hideExtraColumns" />
+        <el-table-column prop="costCenter" :label="t('workOrderMaterial.costCenter')" width="180" v-if="!hideExtraColumns"/>
+        <el-table-column prop="projectDepartment" :label="t('workOrderMaterial.storageLocation')"  width="180" v-if="!hideExtraColumns" />
         <el-table-column prop="materialName" :label="t('workOrderMaterial.materialName')" width="180" >
           <template #default="scope">
             <el-input
               v-model="scope.row.materialName"
               size="small"
               v-if="scope.row.materialSource === '手动添加'"
+              :placeholder="t('workOrderMaterial.nameHolder')"
             />
             <span v-else>{{ scope.row.materialName }}</span>
           </template>
@@ -402,6 +375,7 @@
               v-model="scope.row.materialCode"
               size="small"
               v-if="scope.row.materialSource === '手动添加'"
+              :placeholder="t('workOrderMaterial.codeHolder')"
             />
             <span v-else>{{ scope.row.materialCode }}</span>
           </template>
@@ -412,6 +386,7 @@
               v-model="scope.row.unit"
               size="small"
               v-if="scope.row.materialSource === '手动添加'"
+              :placeholder="t('workOrderMaterial.unitHolder')"
             />
             <span v-else>{{ scope.row.unit }}</span>
           </template>
@@ -422,6 +397,7 @@
               v-model="scope.row.unitPrice"
               size="small"
               v-if="scope.row.materialSource === '手动添加'"
+              :placeholder="t('workOrderMaterial.unitPriceHolder')"
             />
             <span v-else>{{ scope.row.unitPrice }}</span>
           </template>
@@ -435,6 +411,7 @@
               @click.stop=""
               @blur="(event) => handleQuantityBlur(event, scope.row)"
               size="small"
+              :placeholder="t('iotMaintain.quantityHolder')"
             />
           </template>
         </el-table-column>
@@ -582,7 +559,6 @@ const handleIfNeedChange = (row) =>{
   } else {
     materialIfShow.value = false
     //关闭的同时清除该维修项的物料
-    debugger
     materialList.value = materialList.value.filter(item => item.bomNodeId !== row.bomNodeId);
     const targetItem = list.value.find(item => item.bomNodeId === row.bomNodeId);
     if (targetItem) {
@@ -660,7 +636,6 @@ const handleRowClick = (row: any) => {
   }
   // 保留原有的点击逻辑(如果有的话)
   console.log('点击了行:', selectedRowId.value)
-  debugger
   if (selectedRow.value === null) {
     filteredMaterials.value = materialList.value;
   } else {
@@ -688,7 +663,6 @@ const typeChange = async () =>{
       applyPeoPle.value = res
     })
     await IotMaintainApi.getProjectUsers("").then((res) => {
-      debugger
       projectManager.value = res
     })
   }
@@ -813,7 +787,6 @@ const materialDelete = (row) =>{
   totalFee.value = 0
   const index = materialList.value.findIndex((item) => item.bomNodeId === selectedRowId.value&&item.materialCode===row.materialCode)
   const filterIndex = filteredMaterials.value.findIndex((item) => item.bomNodeId === selectedRowId.value&&item.materialCode===row.materialCode)
-  debugger
   if (index>-1) {
     materialList.value.splice(index,1)
   }
@@ -837,7 +810,6 @@ const materialList = ref<IotMainWorkOrderBomMaterialVO[]>([]) // 保养工单bom
 const bomNodeId = ref() // 最新的bomNodeId
 
 const selectChoose = (selectedMaterial) => {
-  debugger
   selectedMaterial.bomNodeId = bomNodeId.value
   // 关联 bomNodeId
   const processedMaterials = selectedMaterial.map((material) => ({
@@ -932,7 +904,6 @@ const submitForm = async () => {
       maintain: formData.value,
       maintainMaterials: list.value
     }
-    debugger
     if (formType.value === 'create') {
       await IotMaintainApi.createIotMaintain(data)
       message.success(t('common.createSuccess'))
@@ -990,7 +961,6 @@ onMounted(async () => {
         applyPeoPle.value = res
       })
       await IotMaintainApi.getProjectUsers("").then((res) => {
-        debugger
         projectManager.value = res
       })
     }
@@ -1007,7 +977,6 @@ const handleDelete = async (id: number) => {
       list.value.splice(index, 1)
       materialList.value = materialList.value.filter((item) => item.bomNodeId !== id)
       totalFee.value = 0
-      debugger
       // list.value.forEach(item => {
       //   // item.materials = item.materials.filter(item => item.bomNodeId !== id);
       //   item.materials.forEach((it) => {

+ 30 - 3
src/views/pms/map/Map.vue

@@ -16,6 +16,17 @@
       <button @click="zoomOut">{{t('map.reduce')}}</button>
       <button @click="toggleMapType"
       >{{t('map.SwitchMapType')}}({{ mapType === 'BMAP_NORMAL_MAP' ? '地图' : '卫星' }})</button>
+        <el-tree-select
+          class="my-el-select"
+          v-model="queryParams.deptId"
+          :data="treeList"
+          :props="defaultProps"
+          check-strictly
+          node-key="id"
+          :placeholder="t('deviceForm.deptHolder')"
+          filterable
+          @change="getData"
+        />
     </div>
   </div>
   <DeviceMonitorDrawer :model-value="drawerVisible" @update:model-value="(val) => (drawerVisible = val)" :id="deviceId" :deviceName="deviceName" :lastLineTime="lastLineTime"
@@ -29,6 +40,7 @@ import { DICT_TYPE, getDictLabel } from '@/utils/dict'
 import { IotDeviceApi, IotDeviceVO } from '@/api/pms/device'
 import DeviceMonitorDrawer from '@/views/pms/map/DeviceMonitorDrawer.vue'
 import * as DeptApi from '@/api/system/dept'
+import {defaultProps, handleTree} from "@/utils/tree";
 
 interface Cluster {
   lng: number
@@ -54,7 +66,7 @@ const inlineCount = ref(0)
 const outlineCount = ref(0)
 // 设备数据示例
 const devices = ref<IotDeviceVO[]>()
-
+const treeList = ref<Tree[]>([]) // 树形结构
 // 初始化地图
 const initMap = () => {
   if (!mapContainer.value) return
@@ -322,9 +334,12 @@ const toggleMapType = () => {
   mapType.value = mapType.value === 'BMAP_NORMAL_MAP' ? 'BMAP_SATELLITE_MAP' : 'BMAP_NORMAL_MAP'
   map.value.setMapType((window as any)[mapType.value])
 }
-
+const queryParams = reactive({
+  deptId: undefined
+})
 const getData = async () => {
-  await IotDeviceApi.getMapDevice().then((res) => {
+  debugger
+  await IotDeviceApi.getMapDevice(queryParams).then((res) => {
     devices.value = res.filter((item)=> item.lat!=0&&item.lng!=0)
     outlineCount.value = devices.value.filter((item)=> item.ifInline===4).length
     inlineCount.value = devices.value.filter((item)=> item.ifInline===3).length
@@ -333,6 +348,10 @@ const getData = async () => {
 }
 onMounted(async () => {
   await getData()
+  const res = await DeptApi.getSimpleDeptList()
+  treeList.value = []
+  treeList.value.push(...handleTree(res))
+  debugger
 })
 
 onBeforeUnmount(() => {
@@ -429,4 +448,12 @@ onBeforeUnmount(() => {
   background-repeat: no-repeat;
   background-position: center;
 }
+
+
+:deep(.el-select__selection) {
+  height: 35px; /* 自定义高度 */
+}
+:deep(.el-select__placeholder.is-transparent){
+  color: orangered;
+}
 </style>

+ 2 - 2
src/views/system/tree/PmsTree.vue

@@ -271,6 +271,7 @@ const handleMenuClick = async (action) => {
       dialogTitle.value = '编辑目录'
       formType.value = 'update'
       formData.value = { ...nodeInfo.value }
+      debugger
       break
     case 'delete':
       // 删除的二次确认
@@ -320,10 +321,9 @@ const submitForm = async () => {
   // 表单验证逻辑
   formLoading.value = true
   try {
-    // 假设存在提交接口
     formData.value.deviceId = props.deviceId
     debugger
-    formData.value.parentId = parentId.value
+    // formData.value.parentId = parentId.value
     if (formData.value.parentId===undefined||formData.value.parentId===null) {
       formData.value.parentId = props.currentId
     }

+ 23 - 9
src/views/system/tree/index.vue

@@ -104,12 +104,12 @@
             <el-table-column :label="t('file.operation') " align="center" width="160">
               <template #default="scope">
                 <div class="flex items-center justify-center">
-                  <el-button type="primary" v-if="scope.row.fileType!=='content'" link @click="handleDownload( scope.row.filePath)" v-hasPermi="['rq:iot-info:download']">
+                  <el-button type="primary" v-if="scope.row.fileType!=='content'" link  @click="handleDownload( scope.row.filePath)" v-hasPermi="['rq:iot-info:download']">
                     <Icon icon="ep:download" />{{t('file.dow')}}
                   </el-button>
-<!--                  <el-button type="primary" link @click="handleView( scope.row)">-->
-<!--                    <Icon icon="ep:view" />{{t('file.preview')}}-->
-<!--                  </el-button>-->
+                  <el-button type="danger" v-if="scope.row.fileType!=='content'" link  @click="deleteInfo( scope.row.id)" v-hasPermi="['rq:iot-info:download']">
+                    <Icon icon="ep:delete" />{{t('file.delete')}}
+                  </el-button>
                 </div>
               </template>
             </el-table-column>
@@ -250,11 +250,22 @@ const handleDownload = async (url) => {
     console.error('下载失败:', error)
   }
 }
-const handleFileView = (url: string) => {
-  window.open(
-    'http://1.94.244.160:8012/onlinePreview?url=' + encodeURIComponent(Base64.encode(url))
-  )
+const deleteInfo= async (id) =>{
+  await message.delConfirm()
+  await IotInfoApi.IotInfoApi.deleteIotInfo(id).then(res=>{
+    if (res) {
+      message.success('文件删除成功')
+       getList();
+    } else {
+      message.error('文件删除失败')
+    }
+  })
 }
+// const handleFileView = (url: string) => {
+//   window.open(
+//     'http://1.94.244.160:8012/onlinePreview?url=' + encodeURIComponent(Base64.encode(url))
+//   )
+// }
 const handleDelete = async (id: number) => {
   try {
     // 删除的二次确认
@@ -316,7 +327,7 @@ const updateBreadcrumbs = async (node) => {
 // 表格行点击事件
 const inContent = async (row) => {
   if (row.fileType!='content') {
-    window.open('http://1.94.244.160:8012/onlinePreview?url='+encodeURIComponent(Base64.encode(row.filePath)));
+    window.open('http://doc.deepoil.cc:8012/onlinePreview?url='+encodeURIComponent(Base64.encode(row.filePath)));
     return
   }
   queryParams.filename = ''
@@ -385,6 +396,9 @@ const handleBreadcrumbClick = async (index) => {
     targetId = topNodeId.value
   }
   queryParams.classId = targetId
+  clickNodeId.value = targetId
+  nodeId.value = targetId
+  debugger
   const data = await IotInfoApi.IotInfoApi.getChildContentFile(queryParams)
   list.value = data
   formLoading.value = false