Compare commits
82 Commits
3019295319
...
main
Author | SHA1 | Date | |
---|---|---|---|
71487ac647 | |||
2b06febd8e | |||
42e9bd894c | |||
820d543f4a | |||
50ff873463 | |||
a5c48d796c | |||
058b870b35 | |||
951ff3cba2 | |||
24351e4f7d | |||
33a5f56d83 | |||
81b2319acc | |||
b3b30026c9 | |||
1c3a25f527 | |||
bcbf0be923 | |||
78c589bf3c | |||
4f4530bc2a | |||
cd4b85c587 | |||
326d0f0d13 | |||
73fc5e2a00 | |||
a961f32d93 | |||
1e1cbdf6f1 | |||
1dc72750f6 | |||
18e569cdd0 | |||
3b30b2b834 | |||
03d2e9f459 | |||
2eb2a41b06 | |||
3d439b62e6 | |||
63442217fc | |||
b6e8df30ff | |||
e453742024 | |||
6396f9c13c | |||
3870addd51 | |||
677f2c4a3b | |||
7d809e52d2 | |||
36d23fcbdb | |||
3c1c42a8c5 | |||
6d106674bd | |||
33ceb7a85a | |||
8ea67fd810 | |||
a334d9f61e | |||
08ba25b66a | |||
fdab1188c0 | |||
cf8651fb14 | |||
49ae691b37 | |||
211b947c3c | |||
fdf75c11d2 | |||
b8f943ca79 | |||
83d732d805 | |||
c1abd76205 | |||
2ab7f59898 | |||
a6b918f762 | |||
32de231f1b | |||
057cd0fda6 | |||
1074049a6b | |||
671e33492d | |||
465876a5cc | |||
8b92e91215 | |||
f4bd352162 | |||
fbd2431f63 | |||
72a2e174c1 | |||
874b4a5994 | |||
5ccbc7f3d4 | |||
ce8eee2380 | |||
e447346af5 | |||
92c3c00b98 | |||
20cb6743cd | |||
e1c84d9b27 | |||
cacb2218cd | |||
fcc7c7dc68 | |||
3f4fa2dd0e | |||
26a946daae | |||
b470f5946b | |||
6367754737 | |||
ba54ca1efb | |||
f80a0e5539 | |||
a03780b352 | |||
7407a43c85 | |||
726bae2652 | |||
596760a707 | |||
122208d9cb | |||
e2c18bf8df | |||
b98625f344 |
4
.gitignore
vendored
@ -1,6 +1,8 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
node_modules
|
node_modules
|
||||||
/dist
|
# dist/
|
||||||
|
# build/
|
||||||
|
gsxt/
|
||||||
|
|
||||||
# local env files
|
# local env files
|
||||||
.env.local
|
.env.local
|
||||||
|
268
package-lock.json
generated
@ -1430,6 +1430,41 @@
|
|||||||
"fastq": "^1.6.0"
|
"fastq": "^1.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@paddlejs-mediapipe/opencv": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@paddlejs-mediapipe/opencv/-/opencv-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-ISSZVIeCUQDV4JBHmMXH4t2FQ0p/Qdz3+I1CuMPUg9qyqqYL5SbqL9ji0b6MOQyCOkO7MV37pSFjx9WjZEzP/g=="
|
||||||
|
},
|
||||||
|
"@paddlejs-models/ocr": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@paddlejs-models/ocr/-/ocr-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-uIsyO2bINgEFU2qmSdKWuUhnmyZX03Ktozh93CloiSTbWq66r0qI6KEuxzIQtm+j6pgugLXrvmtoo2tk0SbpVA==",
|
||||||
|
"requires": {
|
||||||
|
"@paddlejs-mediapipe/opencv": "0.0.3",
|
||||||
|
"@paddlejs/paddlejs-backend-webgl": "^1.1.4",
|
||||||
|
"@paddlejs/paddlejs-core": "^2.1.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@paddlejs-models/ocrdet": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@paddlejs-models/ocrdet/-/ocrdet-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-V7sH8cbyhlR7wkpd1/ycfdA+HiD9XuwIQiFlnwOClFIlZ31EyW10LcMrkhaU7x8uG2BYANFeOz4mBrhE9JRElQ==",
|
||||||
|
"requires": {
|
||||||
|
"@paddlejs-mediapipe/opencv": "0.0.3",
|
||||||
|
"@paddlejs/paddlejs-backend-webgl": "^1.1.0",
|
||||||
|
"@paddlejs/paddlejs-core": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@paddlejs/paddlejs-backend-webgl": {
|
||||||
|
"version": "1.2.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@paddlejs/paddlejs-backend-webgl/-/paddlejs-backend-webgl-1.2.9.tgz",
|
||||||
|
"integrity": "sha512-cVDa0/Wbw2EyfsYqdYUPhFeqKsET79keEUWjyhYQmQkJfWg8j1qdR6yp7g6nx9qAGrqFvwuj1s0EqkYA1dok6A=="
|
||||||
|
},
|
||||||
|
"@paddlejs/paddlejs-core": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@paddlejs/paddlejs-core/-/paddlejs-core-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-P3rPkF9fFHtq8uSte5gA7fJQwBNl9Ytsvj6aTcfQSsirnBO/HxMNu0gJyh7+lItvEtF92PR15eI0eOwJYfZDhQ=="
|
||||||
|
},
|
||||||
"@petamoriken/float16": {
|
"@petamoriken/float16": {
|
||||||
"version": "3.6.6",
|
"version": "3.6.6",
|
||||||
"resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.6.6.tgz",
|
"resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.6.6.tgz",
|
||||||
@ -2099,51 +2134,6 @@
|
|||||||
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
|
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"ansi-styles": {
|
|
||||||
"version": "4.3.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
|
||||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"color-convert": "^2.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"chalk": {
|
|
||||||
"version": "4.1.2",
|
|
||||||
"resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
|
|
||||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"ansi-styles": "^4.1.0",
|
|
||||||
"supports-color": "^7.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"color-convert": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"color-name": "~1.1.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"color-name": {
|
|
||||||
"version": "1.1.4",
|
|
||||||
"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
|
|
||||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"has-flag": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"ssri": {
|
"ssri": {
|
||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
|
||||||
@ -2152,28 +2142,6 @@
|
|||||||
"requires": {
|
"requires": {
|
||||||
"minipass": "^3.1.1"
|
"minipass": "^3.1.1"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"supports-color": {
|
|
||||||
"version": "7.2.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
|
|
||||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"has-flag": "^4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"vue-loader-v16": {
|
|
||||||
"version": "npm:vue-loader@16.8.3",
|
|
||||||
"resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz",
|
|
||||||
"integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
|
||||||
"chalk": "^4.1.0",
|
|
||||||
"hash-sum": "^2.0.0",
|
|
||||||
"loader-utils": "^2.0.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -3331,6 +3299,16 @@
|
|||||||
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
|
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"blueimp-canvas-to-blob": {
|
||||||
|
"version": "3.29.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/blueimp-canvas-to-blob/-/blueimp-canvas-to-blob-3.29.0.tgz",
|
||||||
|
"integrity": "sha512-0pcSSGxC0QxT+yVkivxIqW0Y4VlO2XSDPofBAqoJ1qJxgH9eiUDLv50Rixij2cDuEfx4M6DpD9UGZpRhT5Q8qg=="
|
||||||
|
},
|
||||||
|
"bmp-js": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz",
|
||||||
|
"integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw=="
|
||||||
|
},
|
||||||
"bn.js": {
|
"bn.js": {
|
||||||
"version": "5.2.1",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
|
||||||
@ -6922,6 +6900,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"file-saver": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
|
||||||
|
},
|
||||||
"file-uri-to-path": {
|
"file-uri-to-path": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||||
@ -7875,6 +7858,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"idb-keyval": {
|
||||||
|
"version": "6.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.2.tgz",
|
||||||
|
"integrity": "sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg=="
|
||||||
|
},
|
||||||
"ieee754": {
|
"ieee754": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||||
@ -7892,6 +7880,15 @@
|
|||||||
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
|
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"image-compressor.js": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/image-compressor.js/-/image-compressor.js-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-DF1YFSw+m6FqpXsleD4+q9eu/wFFkm8sHuYhgYy5GWFVencXeuB1/UqC12xz+dCZooPetf5LIb8JOGkgEWmlcg==",
|
||||||
|
"requires": {
|
||||||
|
"blueimp-canvas-to-blob": "^3.14.0",
|
||||||
|
"is-blob": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"image-size": {
|
"image-size": {
|
||||||
"version": "0.5.5",
|
"version": "0.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
|
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
|
||||||
@ -8255,6 +8252,11 @@
|
|||||||
"binary-extensions": "^2.0.0"
|
"binary-extensions": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"is-blob": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-blob/-/is-blob-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-QIZDHQZpRfMEZwSTD7egdNZS7H/awVW9FZ3yJv+gg1z8d8GPXEs76QWL67fZs2BoBqp2dGtamTJpEYFJHmD73g=="
|
||||||
|
},
|
||||||
"is-boolean-object": {
|
"is-boolean-object": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
|
||||||
@ -9922,6 +9924,14 @@
|
|||||||
"lower-case": "^1.1.1"
|
"lower-case": "^1.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node-fetch": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||||
|
"requires": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node-forge": {
|
"node-forge": {
|
||||||
"version": "0.10.0",
|
"version": "0.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
|
||||||
@ -10243,6 +10253,11 @@
|
|||||||
"is-wsl": "^1.1.0"
|
"is-wsl": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"opencollective-postinstall": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q=="
|
||||||
|
},
|
||||||
"opener": {
|
"opener": {
|
||||||
"version": "1.5.2",
|
"version": "1.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
|
||||||
@ -14254,6 +14269,27 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"tesseract.js": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tesseract.js/-/tesseract.js-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-/sPvMvrCtgxnNRCjbTYbr7BRu0yfWDsMZQ2a/T5aN/L1t8wUQN6tTWv6p6FwzpoEBA0jrN2UD2SX4QQFRdoDbA==",
|
||||||
|
"requires": {
|
||||||
|
"bmp-js": "^0.1.0",
|
||||||
|
"idb-keyval": "^6.2.0",
|
||||||
|
"is-url": "^1.2.4",
|
||||||
|
"node-fetch": "^2.6.9",
|
||||||
|
"opencollective-postinstall": "^2.0.3",
|
||||||
|
"regenerator-runtime": "^0.13.3",
|
||||||
|
"tesseract.js-core": "^6.0.0",
|
||||||
|
"wasm-feature-detect": "^1.2.11",
|
||||||
|
"zlibjs": "^0.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tesseract.js-core": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tesseract.js-core/-/tesseract.js-core-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-1Qncm/9oKM7xgrQXZXNB+NRh19qiXGhxlrR8EwFbK5SaUbPZnS5OMtP/ghtqfd23hsr1ZvZbZjeuAGcMxd/ooA=="
|
||||||
|
},
|
||||||
"text-table": {
|
"text-table": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||||
@ -14438,6 +14474,11 @@
|
|||||||
"punycode": "^2.1.1"
|
"punycode": "^2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"tr46": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||||
|
},
|
||||||
"traverse": {
|
"traverse": {
|
||||||
"version": "0.6.6",
|
"version": "0.6.6",
|
||||||
"resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz",
|
"resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz",
|
||||||
@ -15013,6 +15054,75 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"vue-loader-v16": {
|
||||||
|
"version": "npm:vue-loader@16.8.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz",
|
||||||
|
"integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"chalk": "^4.1.0",
|
||||||
|
"hash-sum": "^2.0.0",
|
||||||
|
"loader-utils": "^2.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"chalk": {
|
||||||
|
"version": "4.1.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
|
||||||
|
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "^4.1.0",
|
||||||
|
"supports-color": "^7.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"has-flag": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"has-flag": "^4.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"vue-router": {
|
"vue-router": {
|
||||||
"version": "4.1.3",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.1.3.tgz",
|
||||||
@ -15079,6 +15189,11 @@
|
|||||||
"integrity": "sha512-WJrK7i6w+ULuZsGscCezbCH4Aev5U3xY87vnSimzzEgPQhb0Sa0a1rE3c2jtEwrFtSfi61Jefw3jI5/DD/3jbQ==",
|
"integrity": "sha512-WJrK7i6w+ULuZsGscCezbCH4Aev5U3xY87vnSimzzEgPQhb0Sa0a1rE3c2jtEwrFtSfi61Jefw3jI5/DD/3jbQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"wasm-feature-detect": {
|
||||||
|
"version": "1.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.8.0.tgz",
|
||||||
|
"integrity": "sha512-zksaLKM2fVlnB5jQQDqKXXwYHLQUVH9es+5TOOHwGOVJOCeRBCiPjwSg+3tN2AdTCzjgli4jijCH290kXb/zWQ=="
|
||||||
|
},
|
||||||
"watchpack": {
|
"watchpack": {
|
||||||
"version": "1.7.5",
|
"version": "1.7.5",
|
||||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
|
||||||
@ -15233,6 +15348,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz",
|
||||||
"integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA=="
|
"integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA=="
|
||||||
},
|
},
|
||||||
|
"webidl-conversions": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||||
|
},
|
||||||
"webpack": {
|
"webpack": {
|
||||||
"version": "4.46.0",
|
"version": "4.46.0",
|
||||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz",
|
||||||
@ -15754,6 +15874,15 @@
|
|||||||
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
|
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"whatwg-url": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||||
|
"requires": {
|
||||||
|
"tr46": "~0.0.3",
|
||||||
|
"webidl-conversions": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"which": {
|
"which": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||||
@ -16017,6 +16146,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"zlibjs": {
|
||||||
|
"version": "0.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/zlibjs/-/zlibjs-0.3.1.tgz",
|
||||||
|
"integrity": "sha512-+J9RrgTKOmlxFSDHo0pI1xM6BLVUv+o0ZT9ANtCxGkjIVCCUdx9alUF8Gm+dGLKbkkkidWIHFDZHDMpfITt4+w=="
|
||||||
|
},
|
||||||
"zrender": {
|
"zrender": {
|
||||||
"version": "5.3.2",
|
"version": "5.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.3.2.tgz",
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
"@fullcalendar/list": "^5.9.0",
|
"@fullcalendar/list": "^5.9.0",
|
||||||
"@fullcalendar/timegrid": "^5.9.0",
|
"@fullcalendar/timegrid": "^5.9.0",
|
||||||
"@fullcalendar/vue3": "^5.9.0",
|
"@fullcalendar/vue3": "^5.9.0",
|
||||||
|
"@paddlejs-models/ocr": "^1.1.2",
|
||||||
|
"@paddlejs-models/ocrdet": "^0.0.3",
|
||||||
"@types/video.js": "^7.3.42",
|
"@types/video.js": "^7.3.42",
|
||||||
"@wangeditor/editor": "^5.1.23",
|
"@wangeditor/editor": "^5.1.23",
|
||||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||||
@ -24,12 +26,15 @@
|
|||||||
"echarts-gl": "^2.0.9",
|
"echarts-gl": "^2.0.9",
|
||||||
"el-table-infinite-scroll": "^3.0.6",
|
"el-table-infinite-scroll": "^3.0.6",
|
||||||
"element-plus": "2.0.2",
|
"element-plus": "2.0.2",
|
||||||
|
"file-saver": "^2.0.5",
|
||||||
"gifler": "^0.1.0",
|
"gifler": "^0.1.0",
|
||||||
|
"image-compressor.js": "^1.1.4",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mitt": "^3.0.0",
|
"mitt": "^3.0.0",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"ol": "^6.14.1",
|
"ol": "^6.14.1",
|
||||||
"pinia": "^3.0.1",
|
"pinia": "^3.0.1",
|
||||||
|
"tesseract.js": "^6.0.1",
|
||||||
"vue": "^3.2.8",
|
"vue": "^3.2.8",
|
||||||
"vue-router": "^4.0.11",
|
"vue-router": "^4.0.11",
|
||||||
"vuex": "^4.0.2",
|
"vuex": "^4.0.2",
|
||||||
|
@ -31,26 +31,34 @@
|
|||||||
<script src="./static/js/antd.min.js"></script>
|
<script src="./static/js/antd.min.js"></script>
|
||||||
<script src="./static/js/antd-with-locales.min.js"></script>
|
<script src="./static/js/antd-with-locales.min.js"></script>
|
||||||
|
|
||||||
|
<!-- 文本提取 -->
|
||||||
|
<script src="./textPdf/pdf.min.js"></script>
|
||||||
|
<!-- 引入mammoth.js处理Word文件 -->
|
||||||
|
<script src="./textPdf/mammoth.browser.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<noscript>
|
<!-- 语音- 视频 提取 -->
|
||||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
|
<script src="./textVideo/recorder-core.js" charset="UTF-8"></script>
|
||||||
properly without JavaScript enabled. Please enable it to
|
<script src="./textVideo/wav.js" charset="UTF-8"></script>
|
||||||
continue.</strong>
|
<script src="./textVideo/pcm.js" charset="UTF-8"></script>
|
||||||
</noscript>
|
<noscript><strong></strong> </noscript>
|
||||||
|
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<script>
|
<script>
|
||||||
document.documentElement.addEventListener(
|
var imgIsLoad = false
|
||||||
"touchmove",
|
var videoText = ''
|
||||||
|
// 初始化PDF.js
|
||||||
|
pdfjsLib.GlobalWorkerOptions.workerSrc = "./textPdf/pdf.worker.min.js";
|
||||||
|
|
||||||
|
document.documentElement.addEventListener("touchmove",
|
||||||
function (event) {
|
function (event) {
|
||||||
if (event.touches.length > 1) {
|
if (event.touches.length > 1) event.preventDefault();
|
||||||
event.preventDefault();
|
}, false);
|
||||||
}
|
|
||||||
},
|
|
||||||
false
|
|
||||||
);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script src="./textVideo/wsconnecter.js" charset="utf-8"></script>
|
||||||
|
<script src="./textVideo/textVideo.js" charset="utf-8"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
BIN
public/ocr_v2_det_new/chunk_1.dat
Normal file
10846
public/ocr_v2_det_new/model.json
Normal file
BIN
public/ocr_v2_rec_320/chunk_1.dat
Normal file
BIN
public/ocr_v2_rec_320/chunk_2.dat
Normal file
42769
public/ocr_v2_rec_320/model.json
Normal file
18
public/textPdf/mammoth.browser.min.js
vendored
Normal file
22
public/textPdf/pdf.min.js
vendored
Normal file
22
public/textPdf/pdf.worker.min.js
vendored
Normal file
96
public/textVideo/pcm.js
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
pcm编码器+编码引擎
|
||||||
|
https://github.com/xiangyuecn/Recorder
|
||||||
|
|
||||||
|
编码原理:本编码器输出的pcm格式数据其实就是Recorder中的buffers原始数据(经过了重新采样),16位时为LE小端模式(Little Endian),并未经过任何编码处理
|
||||||
|
|
||||||
|
编码的代码和wav.js区别不大,pcm加上一个44字节wav头即成wav文件;所以要播放pcm就很简单了,直接转成wav文件来播放,已提供转换函数 Recorder.pcm2wav
|
||||||
|
*/
|
||||||
|
(function(){
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Recorder.prototype.enc_pcm={
|
||||||
|
stable:true
|
||||||
|
,testmsg:"pcm为未封装的原始音频数据,pcm数据文件无法直接播放;支持位数8位、16位(填在比特率里面),采样率取值无限制"
|
||||||
|
};
|
||||||
|
Recorder.prototype.pcm=function(res,True,False){
|
||||||
|
var This=this,set=This.set
|
||||||
|
,size=res.length
|
||||||
|
,bitRate=set.bitRate==8?8:16;
|
||||||
|
|
||||||
|
var buffer=new ArrayBuffer(size*(bitRate/8));
|
||||||
|
var data=new DataView(buffer);
|
||||||
|
var offset=0;
|
||||||
|
|
||||||
|
// 写入采样数据
|
||||||
|
if(bitRate==8) {
|
||||||
|
for(var i=0;i<size;i++,offset++) {
|
||||||
|
//16转8据说是雷霄骅的 https://blog.csdn.net/sevennight1989/article/details/85376149 细节比blqw的按比例的算法清晰点,虽然都有明显杂音
|
||||||
|
var val=(res[i]>>8)+128;
|
||||||
|
data.setInt8(offset,val,true);
|
||||||
|
};
|
||||||
|
}else{
|
||||||
|
for (var i=0;i<size;i++,offset+=2){
|
||||||
|
data.setInt16(offset,res[i],true);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
True(new Blob([data.buffer],{type:"audio/pcm"}));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**pcm直接转码成wav,可以直接用来播放;需同时引入wav.js
|
||||||
|
data: {
|
||||||
|
sampleRate:16000 pcm的采样率
|
||||||
|
bitRate:16 pcm的位数 取值:8 或 16
|
||||||
|
blob:blob对象
|
||||||
|
}
|
||||||
|
data如果直接提供的blob将默认使用16位16khz的配置,仅用于测试
|
||||||
|
True(wavBlob,duration)
|
||||||
|
False(msg)
|
||||||
|
**/
|
||||||
|
Recorder.pcm2wav=function(data,True,False){
|
||||||
|
if(data.slice && data.type!=null){//Blob 测试用
|
||||||
|
data={blob:data};
|
||||||
|
};
|
||||||
|
var sampleRate=data.sampleRate||16000,bitRate=data.bitRate||16;
|
||||||
|
if(!data.sampleRate || !data.bitRate){
|
||||||
|
console.warn("pcm2wav必须提供sampleRate和bitRate");
|
||||||
|
};
|
||||||
|
if(!Recorder.prototype.wav){
|
||||||
|
False("pcm2wav必须先加载wav编码器wav.js");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
var reader=new FileReader();
|
||||||
|
reader.onloadend=function(){
|
||||||
|
var pcm;
|
||||||
|
if(bitRate==8){
|
||||||
|
//8位转成16位
|
||||||
|
var u8arr=new Uint8Array(reader.result);
|
||||||
|
pcm=new Int16Array(u8arr.length);
|
||||||
|
for(var j=0;j<u8arr.length;j++){
|
||||||
|
pcm[j]=(u8arr[j]-128)<<8;
|
||||||
|
};
|
||||||
|
}else{
|
||||||
|
pcm=new Int16Array(reader.result);
|
||||||
|
};
|
||||||
|
|
||||||
|
Recorder({
|
||||||
|
type:"wav"
|
||||||
|
,sampleRate:sampleRate
|
||||||
|
,bitRate:bitRate
|
||||||
|
}).mock(pcm,sampleRate).stop(function(wavBlob,duration){
|
||||||
|
True(wavBlob,duration);
|
||||||
|
},False);
|
||||||
|
};
|
||||||
|
reader.readAsArrayBuffer(data.blob);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
})();
|
1493
public/textVideo/recorder-core.js
Normal file
275
public/textVideo/textVideo.js
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
/**
|
||||||
|
* Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights
|
||||||
|
* Reserved. MIT License (https://opensource.org/licenses/MIT)
|
||||||
|
*/
|
||||||
|
/* 2022-2023 by zhaoming,mali aihealthx.com */
|
||||||
|
|
||||||
|
|
||||||
|
// 连接; 定义socket连接类对象与语音对象
|
||||||
|
var wsconnecter = new WebSocketConnectMethod({ msgHandle: getJsonMessage, stateHandle: getConnState });
|
||||||
|
var audioBlob;
|
||||||
|
var isfilemode = true; // if it is in file mode
|
||||||
|
// 录音; 定义录音对象,wav格式
|
||||||
|
var rec = Recorder({
|
||||||
|
type: "pcm",
|
||||||
|
bitRate: 16,
|
||||||
|
sampleRate: 16000,
|
||||||
|
onProcess: recProcess
|
||||||
|
});
|
||||||
|
|
||||||
|
var sampleBuf = new Int16Array();
|
||||||
|
|
||||||
|
var rec_text = ""; // for online rec asr result
|
||||||
|
var offline_text = ""; // for offline rec asr result
|
||||||
|
|
||||||
|
|
||||||
|
var file_ext = "";
|
||||||
|
var file_sample_rate = 16000; //for wav file sample rate
|
||||||
|
var file_data_array; // array to save file data
|
||||||
|
var totalsend = 0;
|
||||||
|
|
||||||
|
addresschange();
|
||||||
|
function addresschange() {
|
||||||
|
var Uri = 'ws://192.168.0.232:10095';
|
||||||
|
Uri = Uri.replace(/wss/g, "https");
|
||||||
|
window.open(Uri, '_blank');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var readWavInfo = function (bytes) {
|
||||||
|
//读取wav文件头,统一成44字节的头
|
||||||
|
if (bytes.byteLength < 44) {
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
var wavView = bytes;
|
||||||
|
var eq = function (p, s) {
|
||||||
|
for (var i = 0; i < s.length; i++) {
|
||||||
|
if (wavView[p + i] != s.charCodeAt(i)) {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (eq(0, "RIFF") && eq(8, "WAVEfmt ")) {
|
||||||
|
|
||||||
|
var numCh = wavView[22];
|
||||||
|
if (wavView[20] == 1 && (numCh == 1 || numCh == 2)) {//raw pcm 单或双声道
|
||||||
|
var sampleRate = wavView[24] + (wavView[25] << 8) + (wavView[26] << 16) + (wavView[27] << 24);
|
||||||
|
var bitRate = wavView[34] + (wavView[35] << 8);
|
||||||
|
var heads = [wavView.subarray(0, 12)], headSize = 12;//head只保留必要的块
|
||||||
|
//搜索data块的位置
|
||||||
|
var dataPos = 0; // 44 或有更多块
|
||||||
|
for (var i = 12, iL = wavView.length - 8; i < iL;) {
|
||||||
|
if (wavView[i] == 100 && wavView[i + 1] == 97 && wavView[i + 2] == 116 && wavView[i + 3] == 97) {//eq(i,"data")
|
||||||
|
heads.push(wavView.subarray(i, i + 8));
|
||||||
|
headSize += 8;
|
||||||
|
dataPos = i + 8; break;
|
||||||
|
}
|
||||||
|
var i0 = i;
|
||||||
|
i += 4;
|
||||||
|
i += 4 + wavView[i] + (wavView[i + 1] << 8) + (wavView[i + 2] << 16) + (wavView[i + 3] << 24);
|
||||||
|
if (i0 == 12) {//fmt
|
||||||
|
heads.push(wavView.subarray(i0, i));
|
||||||
|
headSize += i - i0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dataPos) {
|
||||||
|
var wavHead = new Uint8Array(headSize);
|
||||||
|
for (var i = 0, n = 0; i < heads.length; i++) {
|
||||||
|
wavHead.set(heads[i], n); n += heads[i].length;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
sampleRate: sampleRate
|
||||||
|
, bitRate: bitRate
|
||||||
|
, numChannels: numCh
|
||||||
|
, wavHead44: wavHead
|
||||||
|
, dataPos: dataPos
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
function upfileOnchange(files) {
|
||||||
|
this.files = [files];
|
||||||
|
var len = this.files.length;
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
let fileAudio = new FileReader();
|
||||||
|
fileAudio.readAsArrayBuffer(this.files[i]);
|
||||||
|
file_ext = this.files[i].name.split('.').pop().toLowerCase();
|
||||||
|
var audioblob;
|
||||||
|
fileAudio.onload = function () {
|
||||||
|
audioblob = fileAudio.result;
|
||||||
|
file_data_array = audioblob;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileAudio.onerror = function (e) {
|
||||||
|
console.log('error' + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// for wav file, we get the sample rate
|
||||||
|
if (file_ext == "wav") {
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
let fileAudio = new FileReader();
|
||||||
|
fileAudio.readAsArrayBuffer(this.files[i]);
|
||||||
|
fileAudio.onload = function () {
|
||||||
|
audioblob = new Uint8Array(fileAudio.result);
|
||||||
|
|
||||||
|
var info = readWavInfo(audioblob);
|
||||||
|
file_sample_rate = info.sampleRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function play_file() {
|
||||||
|
var audioblob = new Blob([new Uint8Array(file_data_array)], { type: "audio/wav" });
|
||||||
|
var audio_record = document.getElementById('audio_record');
|
||||||
|
audio_record.src = (window.URL || webkitURL).createObjectURL(audioblob);
|
||||||
|
audio_record.controls = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function start_file_send() {
|
||||||
|
sampleBuf = new Uint8Array(file_data_array);
|
||||||
|
var chunk_size = 960; // for asr chunk_size [5, 10, 5]
|
||||||
|
while (sampleBuf.length >= chunk_size) {
|
||||||
|
sendBuf = sampleBuf.slice(0, chunk_size);
|
||||||
|
totalsend = totalsend + sampleBuf.length;
|
||||||
|
sampleBuf = sampleBuf.slice(chunk_size, sampleBuf.length);
|
||||||
|
wsconnecter.wsSend(sendBuf);
|
||||||
|
}
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
function stop() {
|
||||||
|
var chunk_size = new Array(5, 10, 5);
|
||||||
|
var request = {
|
||||||
|
"chunk_size": chunk_size,
|
||||||
|
"wav_name": "h5",
|
||||||
|
"is_speaking": false,
|
||||||
|
"chunk_interval": 10,
|
||||||
|
"mode": getAsrMode(),
|
||||||
|
};
|
||||||
|
if (sampleBuf.length > 0) {
|
||||||
|
wsconnecter.wsSend(sampleBuf);
|
||||||
|
sampleBuf = new Int16Array();
|
||||||
|
}
|
||||||
|
wsconnecter.wsSend(JSON.stringify(request));
|
||||||
|
// 控件状态更新
|
||||||
|
isRec = false;
|
||||||
|
if (isfilemode == false) {
|
||||||
|
//wait 3s for asr result
|
||||||
|
setTimeout(function () {
|
||||||
|
wsconnecter.wsStop();
|
||||||
|
}, 3000);
|
||||||
|
rec.stop(function (blob, duration) {
|
||||||
|
var audioBlob = Recorder.pcm2wav(data = { sampleRate: 16000, bitRate: 16, blob: blob },
|
||||||
|
function (theblob, duration) {
|
||||||
|
console.log(theblob);
|
||||||
|
var audio_record = document.getElementById('audio_record');
|
||||||
|
audio_record.src = (window.URL || webkitURL).createObjectURL(theblob);
|
||||||
|
audio_record.controls = true;
|
||||||
|
}, function (msg) {
|
||||||
|
console.log(msg);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}, function (errMsg) {
|
||||||
|
console.log("errMsg: " + errMsg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 停止连接
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAsrMode() {
|
||||||
|
return 'offline';
|
||||||
|
}
|
||||||
|
function getHotwords() {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function handleWithTimestamp(tmptext, tmptime) {
|
||||||
|
|
||||||
|
if (tmptime == null || tmptime == "undefined" || tmptext.length <= 0) {
|
||||||
|
return tmptext;
|
||||||
|
}
|
||||||
|
tmptext = tmptext.replace(/。|?|,|、|\?|\.|\ /g, ","); // in case there are a lot of "。"
|
||||||
|
var words = tmptext.split(","); // split to chinese sentence or english words
|
||||||
|
var jsontime = JSON.parse(tmptime); //JSON.parse(tmptime.replace(/\]\]\[\[/g, "],[")); // in case there are a lot segments by VAD
|
||||||
|
var char_index = 0; // index for timestamp
|
||||||
|
var text_withtime = "";
|
||||||
|
for (var i = 0; i < words.length; i++) {
|
||||||
|
if (words[i] == "undefined" || words[i].length <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (/^[a-zA-Z]+$/.test(words[i])) { // if it is english
|
||||||
|
text_withtime = text_withtime + jsontime[char_index][0] / 1000 + ":" + words[i] + "\n";
|
||||||
|
char_index = char_index + 1; //for english, timestamp unit is about a word
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
text_withtime = text_withtime + jsontime[char_index][0] / 1000 + ":" + words[i] + "\n";
|
||||||
|
char_index = char_index + words[i].length; //for chinese, timestamp unit is about a char
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return text_withtime;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
// 语音识别结果; 对jsonMsg数据解析,将识别结果附加到编辑框中
|
||||||
|
function getJsonMessage(jsonMsg) {
|
||||||
|
var rectxt = "" + JSON.parse(jsonMsg.data)['text'];
|
||||||
|
var asrmodel = JSON.parse(jsonMsg.data)['mode'];
|
||||||
|
var is_final = JSON.parse(jsonMsg.data)['is_final'];
|
||||||
|
var timestamp = JSON.parse(jsonMsg.data)['timestamp'];
|
||||||
|
if (asrmodel == "2pass-offline" || asrmodel == "offline") {
|
||||||
|
offline_text = offline_text + handleWithTimestamp(rectxt, timestamp); //rectxt; //.replace(/ +/g,"");
|
||||||
|
rec_text = offline_text;
|
||||||
|
} else {
|
||||||
|
rec_text = rec_text + rectxt;
|
||||||
|
}
|
||||||
|
videoText = rec_text;
|
||||||
|
if (is_final == true) {
|
||||||
|
play_file();
|
||||||
|
wsconnecter.wsStop();
|
||||||
|
btnConnect.disabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 连接状态响应
|
||||||
|
function getConnState(connState) {
|
||||||
|
if (connState === 0) start_file_send();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 识别启动、停止、清空操作
|
||||||
|
function start() {
|
||||||
|
var ret = wsconnecter.wsStart();//启动连接
|
||||||
|
return ret == 1 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function recProcess(buffer, powerLevel, bufferDuration, bufferSampleRate, newBufferIdx, asyncEnd) {
|
||||||
|
if (isRec === true) {
|
||||||
|
var data_48k = buffer[buffer.length - 1];
|
||||||
|
var array_48k = new Array(data_48k);
|
||||||
|
var data_16k = Recorder.SampleData(array_48k, bufferSampleRate, 16000).data;
|
||||||
|
sampleBuf = Int16Array.from([...sampleBuf, ...data_16k]);
|
||||||
|
var chunk_size = 960; // for asr chunk_size [5, 10, 5]
|
||||||
|
while (sampleBuf.length >= chunk_size) {
|
||||||
|
sendBuf = sampleBuf.slice(0, chunk_size);
|
||||||
|
sampleBuf = sampleBuf.slice(chunk_size, sampleBuf.length);
|
||||||
|
wsconnecter.wsSend(sendBuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUseITN() {
|
||||||
|
return false;
|
||||||
|
}
|
86
public/textVideo/wav.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
wav编码器+编码引擎
|
||||||
|
https://github.com/xiangyuecn/Recorder
|
||||||
|
|
||||||
|
当然最佳推荐使用mp3、wav格式,代码也是优先照顾这两种格式
|
||||||
|
浏览器支持情况
|
||||||
|
https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats
|
||||||
|
|
||||||
|
编码原理:给pcm数据加上一个44直接的wav头即成wav文件;pcm数据就是Recorder中的buffers原始数据(重新采样),16位时为LE小端模式(Little Endian),实质上是未经过任何编码处理
|
||||||
|
*/
|
||||||
|
(function(){
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
Recorder.prototype.enc_wav={
|
||||||
|
stable:true
|
||||||
|
,testmsg:"支持位数8位、16位(填在比特率里面),采样率取值无限制"
|
||||||
|
};
|
||||||
|
Recorder.prototype.wav=function(res,True,False){
|
||||||
|
var This=this,set=This.set
|
||||||
|
,size=res.length
|
||||||
|
,sampleRate=set.sampleRate
|
||||||
|
,bitRate=set.bitRate==8?8:16;
|
||||||
|
|
||||||
|
//编码数据 https://github.com/mattdiamond/Recorderjs https://www.cnblogs.com/blqw/p/3782420.html https://www.cnblogs.com/xiaoqi/p/6993912.html
|
||||||
|
var dataLength=size*(bitRate/8);
|
||||||
|
var buffer=new ArrayBuffer(44+dataLength);
|
||||||
|
var data=new DataView(buffer);
|
||||||
|
|
||||||
|
var offset=0;
|
||||||
|
var writeString=function(str){
|
||||||
|
for (var i=0;i<str.length;i++,offset++) {
|
||||||
|
data.setUint8(offset,str.charCodeAt(i));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
var write16=function(v){
|
||||||
|
data.setUint16(offset,v,true);
|
||||||
|
offset+=2;
|
||||||
|
};
|
||||||
|
var write32=function(v){
|
||||||
|
data.setUint32(offset,v,true);
|
||||||
|
offset+=4;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* RIFF identifier */
|
||||||
|
writeString('RIFF');
|
||||||
|
/* RIFF chunk length */
|
||||||
|
write32(36+dataLength);
|
||||||
|
/* RIFF type */
|
||||||
|
writeString('WAVE');
|
||||||
|
/* format chunk identifier */
|
||||||
|
writeString('fmt ');
|
||||||
|
/* format chunk length */
|
||||||
|
write32(16);
|
||||||
|
/* sample format (raw) */
|
||||||
|
write16(1);
|
||||||
|
/* channel count */
|
||||||
|
write16(1);
|
||||||
|
/* sample rate */
|
||||||
|
write32(sampleRate);
|
||||||
|
/* byte rate (sample rate * block align) */
|
||||||
|
write32(sampleRate*(bitRate/8));// *1 声道
|
||||||
|
/* block align (channel count * bytes per sample) */
|
||||||
|
write16(bitRate/8);// *1 声道
|
||||||
|
/* bits per sample */
|
||||||
|
write16(bitRate);
|
||||||
|
/* data chunk identifier */
|
||||||
|
writeString('data');
|
||||||
|
/* data chunk length */
|
||||||
|
write32(dataLength);
|
||||||
|
// 写入采样数据
|
||||||
|
if(bitRate==8) {
|
||||||
|
for(var i=0;i<size;i++,offset++) {
|
||||||
|
//16转8据说是雷霄骅的 https://blog.csdn.net/sevennight1989/article/details/85376149 细节比blqw的按比例的算法清晰点,虽然都有明显杂音
|
||||||
|
var val=(res[i]>>8)+128;
|
||||||
|
data.setInt8(offset,val,true);
|
||||||
|
};
|
||||||
|
}else{
|
||||||
|
for (var i=0;i<size;i++,offset+=2){
|
||||||
|
data.setInt16(offset,res[i],true);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
True(new Blob([data.buffer],{type:"audio/wav"}));
|
||||||
|
}
|
||||||
|
})();
|
119
public/textVideo/wsconnecter.js
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/**
|
||||||
|
* Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights
|
||||||
|
* Reserved. MIT License (https://opensource.org/licenses/MIT)
|
||||||
|
*/
|
||||||
|
/* 2021-2023 by zhaoming,mali aihealthx.com */
|
||||||
|
|
||||||
|
function WebSocketConnectMethod( config ) { //定义socket连接方法类
|
||||||
|
|
||||||
|
|
||||||
|
var speechSokt;
|
||||||
|
var connKeeperID;
|
||||||
|
|
||||||
|
var msgHandle = config.msgHandle;
|
||||||
|
var stateHandle = config.stateHandle;
|
||||||
|
|
||||||
|
this.wsStart = function () {
|
||||||
|
var Uri = 'ws://192.168.0.232:10095'; //"wss://111.205.137.58:5821/wss/" //设置wss asr online接口地址 如 wss://X.X.X.X:port/wss/
|
||||||
|
if(Uri.match(/wss:\S*|ws:\S*/))
|
||||||
|
{
|
||||||
|
console.log("Uri"+Uri);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
alert("请检查wss地址正确性");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( 'WebSocket' in window ) {
|
||||||
|
speechSokt = new WebSocket( Uri ); // 定义socket连接对象
|
||||||
|
speechSokt.onopen = function(e){onOpen(e);}; // 定义响应函数
|
||||||
|
speechSokt.onclose = function(e){
|
||||||
|
console.log("onclose ws!");
|
||||||
|
//speechSokt.close();
|
||||||
|
onClose(e);
|
||||||
|
};
|
||||||
|
speechSokt.onmessage = function(e){onMessage(e);};
|
||||||
|
speechSokt.onerror = function(e){onError(e);};
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
alert('当前浏览器不支持 WebSocket');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 定义停止与发送函数
|
||||||
|
this.wsStop = function () {
|
||||||
|
if(speechSokt != undefined) {
|
||||||
|
console.log("stop ws!");
|
||||||
|
speechSokt.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.wsSend = function ( oneData ) {
|
||||||
|
|
||||||
|
if(speechSokt == undefined) return;
|
||||||
|
if ( speechSokt.readyState === 1 ) { // 0:CONNECTING, 1:OPEN, 2:CLOSING, 3:CLOSED
|
||||||
|
|
||||||
|
speechSokt.send( oneData );
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// SOCEKT连接中的消息与状态响应
|
||||||
|
function onOpen( e ) {
|
||||||
|
// 发送json
|
||||||
|
var chunk_size = new Array( 5, 10, 5 );
|
||||||
|
var request = {
|
||||||
|
"chunk_size": chunk_size,
|
||||||
|
"wav_name": "h5",
|
||||||
|
"is_speaking": true,
|
||||||
|
"chunk_interval":10,
|
||||||
|
"itn":getUseITN(),
|
||||||
|
"mode":getAsrMode(),
|
||||||
|
|
||||||
|
};
|
||||||
|
if(isfilemode)
|
||||||
|
{
|
||||||
|
request.wav_format=file_ext;
|
||||||
|
if(file_ext=="wav")
|
||||||
|
{
|
||||||
|
request.wav_format="PCM";
|
||||||
|
request.audio_fs=file_sample_rate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var hotwords=getHotwords();
|
||||||
|
|
||||||
|
if(hotwords!=null )
|
||||||
|
{
|
||||||
|
request.hotwords=hotwords;
|
||||||
|
}
|
||||||
|
console.log(JSON.stringify(request));
|
||||||
|
speechSokt.send(JSON.stringify(request));
|
||||||
|
console.log("连接成功");
|
||||||
|
stateHandle(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClose( e ) {
|
||||||
|
stateHandle(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMessage( e ) {
|
||||||
|
|
||||||
|
msgHandle( e );
|
||||||
|
}
|
||||||
|
|
||||||
|
function onError( e ) {
|
||||||
|
|
||||||
|
info_div.innerHTML="连接"+e;
|
||||||
|
console.log(e);
|
||||||
|
stateHandle(2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
24
src/App.vue
@ -6,10 +6,12 @@
|
|||||||
</router-view>
|
</router-view>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, nextTick, provide, onMounted } from "vue";
|
import * as ocr from "@paddlejs-models/ocr";
|
||||||
|
import { ref, nextTick, provide, onMounted,getCurrentInstance } from "vue";
|
||||||
import { useStore } from "vuex";
|
import { useStore } from "vuex";
|
||||||
import { getItem } from "@/utils/storage";
|
import { getItem, setItem} from "@/utils/storage";
|
||||||
import { generateNewStyle, writeNewStyle } from "@/utils/theme";
|
import { generateNewStyle, writeNewStyle } from "@/utils/theme";
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
generateNewStyle(store.getters.mainColor).then((newStyle) => {
|
generateNewStyle(store.getters.mainColor).then((newStyle) => {
|
||||||
writeNewStyle(newStyle);
|
writeNewStyle(newStyle);
|
||||||
@ -23,9 +25,25 @@ const reload = () => {
|
|||||||
};
|
};
|
||||||
provide("reload", reload);
|
provide("reload", reload);
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
let dept = getItem("deptId");
|
|
||||||
document.title = "林芝";
|
document.title = "林芝";
|
||||||
|
// initPage()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@Descripttion:图片页面初始化
|
||||||
|
*@Author: PengShuai
|
||||||
|
*/
|
||||||
|
const initPage = async () => {
|
||||||
|
try {
|
||||||
|
await ocr.init();// 模型初始化
|
||||||
|
imgIsLoad = true;
|
||||||
|
proxy.$message({ type: "success", message: "加载成功" });
|
||||||
|
} catch (err) {
|
||||||
|
proxy.$message({ type: "error", message: "加载失败,请刷新页面" });
|
||||||
|
imgIsLoad = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "./styles/index.scss";
|
@import "./styles/index.scss";
|
||||||
|
@ -1,22 +1,17 @@
|
|||||||
import request from "@/utils/request";
|
import request from "@/utils/request";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
const api = "/mosty-api";
|
const api = "/mosty-api";
|
||||||
const egisSpace = "/egis-space";
|
|
||||||
|
|
||||||
// 选择站口名称
|
// 解析数据
|
||||||
export function egisSpaceGet(fun,coords){
|
export function ParsingText(data,fun){
|
||||||
let params = {
|
axios({
|
||||||
pageNum: 1,
|
method: 'post',
|
||||||
pageSize: 1000,
|
url: '/chat/completions',
|
||||||
keyword: "",
|
data:data,
|
||||||
geometry: `{"type":"Polygon","coordinates":${JSON.stringify(coords)}}`,
|
headers: { 'Authorization': 'Bearer sk-064b5c53131c4046883b718f2b31c050' }
|
||||||
};
|
}).then( (res) => {
|
||||||
params.geometry = encodeURIComponent(params.geometry)
|
fun(res)
|
||||||
|
})
|
||||||
let url = egisSpace + '/space/search/custom/ms-dy-intersections'
|
|
||||||
axios.get(url,{params}).then((res) => {
|
|
||||||
fun(res.data)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -599,7 +599,7 @@ export const selectUserDeptPage = (data = {}) => {
|
|||||||
///unifiedLogin
|
///unifiedLogin
|
||||||
export const unifiedLogin = (data) => {
|
export const unifiedLogin = (data) => {
|
||||||
return request({
|
return request({
|
||||||
url: api + `/unifiedLogin`,
|
url: api + `/ssoLogin`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
-webkit-text-fill-color: transparent;
|
-webkit-text-fill-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.homeBox {
|
.homeBox {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
|
||||||
.home-aside {
|
.home-aside {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 442px;
|
width: 442px;
|
||||||
@ -14,6 +16,7 @@
|
|||||||
height: calc(100vh - 72px);
|
height: calc(100vh - 72px);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
|
||||||
.asideTitle {
|
.asideTitle {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -23,6 +26,7 @@
|
|||||||
background: linear-gradient(90deg, #124CB3 0%, rgba(18, 76, 179, 0.23) 77%, rgba(18, 76, 179, 0) 100%);
|
background: linear-gradient(90deg, #124CB3 0%, rgba(18, 76, 179, 0.23) 77%, rgba(18, 76, 179, 0) 100%);
|
||||||
border-radius: 0px 0px 0px 0px;
|
border-radius: 0px 0px 0px 0px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
@ -30,15 +34,18 @@
|
|||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.asideCnt {
|
.asideCnt {
|
||||||
height: calc(100% - 40px);
|
height: calc(100% - 40px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.aside-middle {
|
.aside-middle {
|
||||||
height: calc(100%/2);
|
height: calc(100%/2);
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.homeBtn {
|
.homeBtn {
|
||||||
height: 302px;
|
height: 302px;
|
||||||
width: calc(100% - 894px);
|
width: calc(100% - 894px);
|
||||||
@ -47,6 +54,7 @@
|
|||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 头部
|
// 头部
|
||||||
.headBox {
|
.headBox {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -55,6 +63,7 @@
|
|||||||
height: 70px;
|
height: 70px;
|
||||||
background: rgba(0, 0, 0, 0.8);
|
background: rgba(0, 0, 0, 0.8);
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
||||||
.headBoxBg {
|
.headBoxBg {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -62,6 +71,7 @@
|
|||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
height: 151px;
|
height: 151px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-center {
|
.top-center {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
@ -76,10 +86,12 @@
|
|||||||
-webkit-text-fill-color: transparent;
|
-webkit-text-fill-color: transparent;
|
||||||
text-shadow: 4px 4px 4px rgba(54, 255, 243, 0.15);
|
text-shadow: 4px 4px 4px rgba(54, 255, 243, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
.topBtn {
|
.topBtn {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 22px;
|
top: 22px;
|
||||||
|
|
||||||
.topBtn-item {
|
.topBtn-item {
|
||||||
width: 190px;
|
width: 190px;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
@ -90,6 +102,7 @@
|
|||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
font-family: "YSBTH";
|
font-family: "YSBTH";
|
||||||
margin-top: -4px;
|
margin-top: -4px;
|
||||||
@ -98,21 +111,26 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.topBtn-left {
|
.topBtn-left {
|
||||||
left: 30px;
|
left: 30px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
font-family: "YSBTH";
|
font-family: "YSBTH";
|
||||||
color: #0bb7ff;
|
color: #0bb7ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tests {
|
.tests {
|
||||||
color: #0a99ff;
|
color: #0a99ff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.leftBtn-yjbtn {
|
.leftBtn-yjbtn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 360px;
|
left: 360px;
|
||||||
top: 20px;
|
top: 20px;
|
||||||
|
|
||||||
.leftBtn-item {
|
.leftBtn-item {
|
||||||
width: 155px;
|
width: 155px;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
@ -123,61 +141,73 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-family: "YSBTH";
|
font-family: "YSBTH";
|
||||||
}
|
}
|
||||||
|
|
||||||
.btms {
|
.btms {
|
||||||
@include textColor(#a1d6ff, #ffffff);
|
@include textColor(#a1d6ff, #ffffff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.yjbtnActive {
|
.yjbtnActive {
|
||||||
background: url("~@/assets/images/home_btns_active.png") no-repeat center center;
|
background: url("~@/assets/images/home_btns_active.png") no-repeat center center;
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
|
|
||||||
.btms {
|
.btms {
|
||||||
@include textColor(#00ffff, #faff00);
|
@include textColor(#00ffff, #faff00);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.topBtn-right {
|
.topBtn-right {
|
||||||
right: 270px;
|
right: 270px;
|
||||||
top: 22px;
|
top: 22px;
|
||||||
|
|
||||||
.topBtn-item {
|
.topBtn-item {
|
||||||
background: url("~@/assets/images/home_btns_right.png") no-repeat center
|
background: url("~@/assets/images/home_btns_right.png") no-repeat center center;
|
||||||
center;
|
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.active-topBtn {
|
.active-topBtn {
|
||||||
background: url("~@/assets/images/home_btns_right_active.png") no-repeat
|
background: url("~@/assets/images/home_btns_right_active.png") no-repeat center center;
|
||||||
center center;
|
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
@include textColor(#00ffff, #faff00);
|
@include textColor(#00ffff, #faff00);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.rightIcon {
|
.rightIcon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
top: 22px;
|
top: 22px;
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
color: #0bb7ff;
|
color: #0bb7ff;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 左边
|
// 左边
|
||||||
.asideL {
|
.asideL {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
|
|
||||||
.asideL-top {
|
.asideL-top {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 141px;
|
height: 141px;
|
||||||
background: #052249;
|
background: #052249;
|
||||||
}
|
}
|
||||||
|
|
||||||
.asideL-Bottom {
|
.asideL-Bottom {
|
||||||
height: calc(100% - 141px);
|
height: calc(100% - 141px);
|
||||||
|
|
||||||
.commom-aside {
|
.commom-aside {
|
||||||
height: calc((100%/3) - 6px);
|
height: calc((100%/3) - 6px);
|
||||||
margin-top: 7px;
|
margin-top: 7px;
|
||||||
@ -185,15 +215,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 右边
|
// 右边
|
||||||
.asideR {
|
.asideR {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
|
|
||||||
.commom-aside-small {
|
.commom-aside-small {
|
||||||
height: calc(((100% - 146px) /3) - 6px);
|
height: calc(((100% - 146px) /3) - 6px);
|
||||||
background: #052249;
|
background: #052249;
|
||||||
margin-top: 9px;
|
margin-top: 9px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commom-aside-big {
|
.commom-aside-big {
|
||||||
height: calc(((100% - (100% - 146px) /3)/2) - 6px);
|
height: calc(((100% - (100% - 146px) /3)/2) - 6px);
|
||||||
margin-bottom: 9px;
|
margin-bottom: 9px;
|
||||||
@ -207,9 +240,17 @@
|
|||||||
top: 70px;
|
top: 70px;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
width: calc(100% - 890px);
|
width: calc(100% - 890px);
|
||||||
height: 80px;
|
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
background: #052249;
|
background: #052249;
|
||||||
|
height: calc(100% - (100% - 141px) / 3 - 45px);
|
||||||
|
|
||||||
|
.middle-top {
|
||||||
|
height: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.middle-bottom {
|
||||||
|
height: calc(100% - 90px);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.home-foot-t {
|
.home-foot-t {
|
||||||
@ -224,9 +265,11 @@
|
|||||||
z-index: 9;
|
z-index: 9;
|
||||||
background: url("~@/assets/images/right-1.png") no-repeat center center;
|
background: url("~@/assets/images/right-1.png") no-repeat center center;
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
|
|
||||||
.comom-title {
|
.comom-title {
|
||||||
background: url("~@/assets/images/bg18.png") no-repeat center center;
|
background: url("~@/assets/images/bg18.png") no-repeat center center;
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
font-family: 'YSBTH';
|
font-family: 'YSBTH';
|
||||||
@ -246,12 +289,14 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
font-family: 'YSBTH';
|
font-family: 'YSBTH';
|
||||||
padding-left: 35px;
|
padding-left: 35px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.comom-cnt {
|
.comom-cnt {
|
||||||
height: calc(100% - 35px);
|
height: calc(100% - 35px);
|
||||||
padding: 4px 10px;
|
padding: 4px 10px;
|
||||||
|
Before Width: | Height: | Size: 540 KiB |
Before Width: | Height: | Size: 212 KiB |
Before Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 948 B |
Before Width: | Height: | Size: 209 B |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 3.3 KiB |
BIN
src/assets/images/ddtb.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 4.0 KiB |
@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M16 2C10.477 2 6 6.477 6 12C6 19.5 16 30 16 30C16 30 26 19.5 26 12C26 6.477 21.523 2 16 2ZM16 16C13.791 16 12 14.209 12 12C12 9.791 13.791 8 16 8C18.209 8 20 9.791 20 12C20 14.209 18.209 16 16 16Z" fill="#00f0ff" stroke="#ffffff" stroke-width="1"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 401 B |
BIN
src/assets/images/mxbg.jpg
Normal file
After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 6.8 KiB |
BIN
src/assets/images/xxxxxx.png
Normal file
After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 571 B |
Before Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 792 B |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.7 KiB |
104
src/components/ChooseList/ChooseCl/addPeo.vue
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="showDialog" :destroy-on-close="true" title="新增车辆" @close="close" :close-on-click-modal="false">
|
||||||
|
<FormMessage v-model="listQuery" :formList="formData" labelWidth="120px" ref="elform" :rules="rules">
|
||||||
|
<template #bqList>
|
||||||
|
<div class="marks pointer" @click="chooseMarksVisible = true">
|
||||||
|
<span style="color: rgb(175 178 184);padding-left: 10px;"
|
||||||
|
v-if="!listQuery.bqList || listQuery.bqList.length == 0">请选择标签</span>
|
||||||
|
<span v-else>
|
||||||
|
<el-tag @close.stop="closeTag(idx)" type="success" closable v-for="(it, idx) in listQuery.bqList"
|
||||||
|
:key="idx">{{ it.bqMc }}</el-tag>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</FormMessage>
|
||||||
|
<template #footer>
|
||||||
|
<div class="flex just-center">
|
||||||
|
<el-button @click="close">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submitForm">确认</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
<ChooseMarks v-model="chooseMarksVisible" @choosed="choosed" :roleIds="roleIds" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import ChooseMarks from "@/components/ChooseList/ChooseMarks/index.vue";
|
||||||
|
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||||
|
import { reactive, ref, getCurrentInstance } from 'vue';
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
const { D_BZ_XB } = proxy.$dict("D_BZ_XB"); // 获取字典数据
|
||||||
|
const elform = ref()
|
||||||
|
const roleIds = ref([])
|
||||||
|
const showDialog = ref(false)
|
||||||
|
const chooseMarksVisible = ref(false)
|
||||||
|
const emit = defineEmits(['change'])
|
||||||
|
const listQuery = ref({})
|
||||||
|
const formData = ref([
|
||||||
|
{ label: "车牌号", prop: "hphm", type: "input" },
|
||||||
|
{ label: "车架号", prop: "clCjh", type: "input" },
|
||||||
|
{
|
||||||
|
label: "车辆颜色",
|
||||||
|
prop: "clYs",
|
||||||
|
type: "input",
|
||||||
|
},
|
||||||
|
{ label: "车辆所有人", prop: "clSyr", type: "input" },
|
||||||
|
{ label: "人员身份证", prop: "clSyrsfzh", type: "input" },
|
||||||
|
{ label: "责任单位", prop: "zrSsbmdm", depMc: 'zrSsbmmc', type: "department" },
|
||||||
|
{ label: "管辖单位", prop: "gxSsbmdm", depMc: 'gxSsbmmc', type: "department" },
|
||||||
|
{ label: "管控民警姓名", prop: "gkMjXm", type: "input" },
|
||||||
|
{ label: "管控民警警号", prop: "gkMjJh", type: "input" },
|
||||||
|
{ label: "管控原因", prop: "clLkyy", type: "textarea", width: "100%" },
|
||||||
|
{ label: "车辆照片", prop: "fjdz", type: "upload", width: "100%" },
|
||||||
|
])
|
||||||
|
const rules = reactive({
|
||||||
|
hphm: [{ required: true, message: "请输入车牌号", trigger: "blur" }],
|
||||||
|
clCjh: [{ required: true, message: "请输入车架号", trigger: "blur" }],
|
||||||
|
clYs: [{ required: true, message: "请输入车辆颜色", trigger: "blur" }],
|
||||||
|
clSyr: [{ required: true, message: "请输入车辆所有人", trigger: "blur" }],
|
||||||
|
clSyrsfzh: [{ required: true, message: "请输入人员身份证", trigger: "blur" }],
|
||||||
|
})
|
||||||
|
const init = () => {
|
||||||
|
showDialog.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择标签
|
||||||
|
const choosed = (val) => {
|
||||||
|
listQuery.value.bqList = val.map(v => {
|
||||||
|
return { bqZl: v.bqLb, bqId: v.id, bqLx: v.bqLx, bqLb: v.bqLb, bqMc: v.bqMc, bqDm: v.bqDm }
|
||||||
|
});
|
||||||
|
roleIds.value = val.map(v => v.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除数据
|
||||||
|
const closeTag = (idx) => {
|
||||||
|
listQuery.value.bqList.splice(idx, 1)
|
||||||
|
roleIds.value.splice(idx, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const submitForm = () => {
|
||||||
|
elform.value.submit((val) => {
|
||||||
|
val.id = new Date().getTime()
|
||||||
|
emit('change', val)
|
||||||
|
showDialog.value = false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
elform.value.reset();
|
||||||
|
listQuery.value.bqList = []
|
||||||
|
roleIds.value = []
|
||||||
|
showDialog.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ init })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.marks {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 32px;
|
||||||
|
border: 1px solid #e9e9e9;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
204
src/components/ChooseList/ChooseCl/index.vue
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog width="1400px" :model-value="modelValue" append-to-body @close="closed">
|
||||||
|
<template #title>
|
||||||
|
<span class="mr10 f16">选择布控车辆</span>
|
||||||
|
<el-button type="primary" size="small" @click="zdyaddPerson">添加其他车辆</el-button>
|
||||||
|
</template>
|
||||||
|
<el-form :model="listQuery" :inline="true">
|
||||||
|
<el-form-item label="车牌号">
|
||||||
|
<el-input placeholder="请输入车牌号" v-model="listQuery.hphm" clearable ></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="车架号">
|
||||||
|
<el-input placeholder="请输入车架号" v-model="listQuery.clCjh" clearable ></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="车辆所有人">
|
||||||
|
<el-input placeholder="请输入车辆所有人" v-model="listQuery.clSyr" clearable ></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="success" @click="handleFilter">查询</el-button>
|
||||||
|
<el-button type="info" @click="reset()"> 重置 </el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div class="tabBox" :class="props.Single ? 'tabBoxRadio' : ''" style="margin-top: 0px">
|
||||||
|
<el-table ref="multipleUserRef" :key="keyTabel" v-loading="loading" @selection-change="handleSelectionChange" :data="tableData" border :row-key="keyid" style="width: 100%" height="450">
|
||||||
|
<el-table-column type="selection" width="55" :reserve-selection="true"/>
|
||||||
|
<el-table-column prop="hphm" align="center" label="车牌号"/>
|
||||||
|
<el-table-column prop="clCjh" align="center" label="车架号"/>
|
||||||
|
<el-table-column prop="clYs" align="center" label="车辆颜色"/>
|
||||||
|
<el-table-column prop="clSyr" align="center" label="车辆所有人"/>
|
||||||
|
<el-table-column prop="gxSsbmmc" align="center" label="管辖单位"/>
|
||||||
|
<el-table-column prop="gkMjXm" align="center" label="管控民警"/>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div class="fenye flex just-end " :style="{ top: tableHeight + 'px' }">
|
||||||
|
<el-pagination
|
||||||
|
class="pagination"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
:current-page="listQuery.pageCurrent"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
:page-size="listQuery.pageSize"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total"
|
||||||
|
></el-pagination>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="flex just-center">
|
||||||
|
<el-button @click="closed">取消</el-button>
|
||||||
|
<el-button type="primary" @click="onComfirm">确认</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 自定义选添加人 -->
|
||||||
|
<AddPeo ref="addPerson" @change="changeZdy"></AddPeo>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import AddPeo from './addPeo.vue'
|
||||||
|
import { qcckGet} from "@/api/qcckApi.js";
|
||||||
|
import { defineProps, ref ,getCurrentInstance, watch} from "vue";
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
const { D_BZ_XB,D_BZ_MZ } = proxy.$dict("D_BZ_XB","D_BZ_MZ"); //获取字典数据
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Boolean,
|
||||||
|
default:false
|
||||||
|
},
|
||||||
|
LeaderType: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
//是否单选
|
||||||
|
Single: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
roleIds: {
|
||||||
|
type: Array,
|
||||||
|
default: []
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const loading = ref(false)
|
||||||
|
const total = ref(0);
|
||||||
|
const listQuery = ref({
|
||||||
|
pageCurrent: 1,
|
||||||
|
pageSize: 20
|
||||||
|
});
|
||||||
|
const addPerson = ref()
|
||||||
|
const multipleUserRef = ref(null);
|
||||||
|
const multipleSelectionUser = ref([]);
|
||||||
|
const tableData = ref([]);
|
||||||
|
const emits = defineEmits(["update:modelValue", "choosed","choosedAdd"]);
|
||||||
|
const keyTabel = ref(0)
|
||||||
|
const keyid = (row) => {
|
||||||
|
return row.id;
|
||||||
|
};
|
||||||
|
|
||||||
|
const closed = () => {
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
const reset = () => {
|
||||||
|
listQuery.value = { pageCurrent: 1, pageSize: 20, };
|
||||||
|
getListData();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 为用户分配角色
|
||||||
|
const onComfirm = () => {
|
||||||
|
const userList = multipleSelectionUser.value;
|
||||||
|
let list = [];
|
||||||
|
let listId = [];
|
||||||
|
userList.forEach((val) => {
|
||||||
|
if (listId.indexOf(val.id) == -1) {
|
||||||
|
list.push(val);
|
||||||
|
listId.push(val.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
emits("choosed", list);
|
||||||
|
closed();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 自定义加人
|
||||||
|
const changeZdy = (val) => {
|
||||||
|
emits("choosedAdd", val);
|
||||||
|
closed();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* pageSize 改变触发
|
||||||
|
*/
|
||||||
|
const handleSizeChange = (currentSize) => {
|
||||||
|
listQuery.value.pageSize = currentSize;
|
||||||
|
getListData();
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 页码改变触发
|
||||||
|
*/
|
||||||
|
const handleCurrentChange = (currentPage) => {
|
||||||
|
listQuery.value.pageCurrent = currentPage;
|
||||||
|
getListData();
|
||||||
|
};
|
||||||
|
const getListData = () => {
|
||||||
|
keyTabel.value++
|
||||||
|
const params = {...listQuery.value}
|
||||||
|
loading.value = true;
|
||||||
|
qcckGet(params,'/mosty-gsxt/tbGsxtZdcl/selectPage').then(res=>{
|
||||||
|
loading.value = false;
|
||||||
|
tableData.value = res.records || [];
|
||||||
|
total.value = res.total;
|
||||||
|
multipleUser();
|
||||||
|
}).catch(()=>{
|
||||||
|
loading.value = false;
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
//列表回显
|
||||||
|
function multipleUser() {
|
||||||
|
tableData.value.forEach((item) => {
|
||||||
|
multipleUserRef.value.toggleRowSelection(item, false);
|
||||||
|
if (props.roleIds.some((id) => id == item.id)) {
|
||||||
|
multipleUserRef.value.toggleRowSelection(item, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFilter = () => {
|
||||||
|
listQuery.value.pageCurrent = 1;
|
||||||
|
getListData();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSelectionChange = (val) => {
|
||||||
|
if (props.Single) {
|
||||||
|
if (val.length > 1) {
|
||||||
|
let del_row = val.shift();
|
||||||
|
multipleUserRef.value.toggleRowSelection(del_row, false);
|
||||||
|
}
|
||||||
|
multipleSelectionUser.value = val;
|
||||||
|
} else {
|
||||||
|
multipleSelectionUser.value = val;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const zdyaddPerson = () => {
|
||||||
|
addPerson.value.init();
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(()=>props.modelValue,val=>{
|
||||||
|
if(val) handleFilter();
|
||||||
|
},{immediate:true})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "@/assets/css/layout.scss";
|
||||||
|
@import "@/assets/css/element-plus.scss";
|
||||||
|
</style>
|
||||||
|
<style>
|
||||||
|
.tabBoxRadio .el-checkbox__inner {
|
||||||
|
border-radius: 50% !important;
|
||||||
|
}
|
||||||
|
.tabBoxRadio .el-table__header-wrapper .el-checkbox {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
@ -1,18 +1,46 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog :title="titleValue" width="1400px" :model-value="modelValue" append-to-body @close="closed">
|
<el-dialog
|
||||||
|
:title="titleValue"
|
||||||
|
width="1400px"
|
||||||
|
:model-value="modelValue"
|
||||||
|
append-to-body
|
||||||
|
@close="closed"
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<el-form :model="listQuery" class="mosty-from-wrap" :inline="true">
|
<el-form :model="listQuery" class="mosty-from-wrap" :inline="true">
|
||||||
<el-form-item label="标签名称">
|
<el-form-item label="标签名称">
|
||||||
<el-input placeholder="请输入标签名称" v-model="listQuery.bqMc" clearable ></el-input>
|
<el-input
|
||||||
|
placeholder="请输入标签名称"
|
||||||
|
v-model="listQuery.bqMc"
|
||||||
|
clearable
|
||||||
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="success" @click="handleFilter">查询</el-button>
|
<el-button type="success" @click="handleFilter">查询</el-button>
|
||||||
<el-button type="info" @click="reset"> 重置 </el-button>
|
<el-button type="info" @click="reset"> 重置 </el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="tabBox" :class="props.Single ? 'tabBoxRadio' : ''" :key="keyVal" style="margin-top: 0px">
|
<div
|
||||||
<el-table ref="multipleUserRef" @selection-change="handleSelectionChange" :data="tableData" v-loading="loading" border :row-key="keyid" style="width: 100%" height="450">
|
class="tabBox"
|
||||||
<el-table-column type="selection" width="55" :reserve-selection="true"/>
|
:class="props.Single ? 'tabBoxRadio' : ''"
|
||||||
|
:key="keyVal"
|
||||||
|
style="margin-top: 0px"
|
||||||
|
>
|
||||||
|
<el-table
|
||||||
|
ref="multipleUserRef"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
:data="tableData"
|
||||||
|
v-loading="loading"
|
||||||
|
border
|
||||||
|
:row-key="keyid"
|
||||||
|
style="width: 100%"
|
||||||
|
height="450"
|
||||||
|
>
|
||||||
|
<el-table-column
|
||||||
|
type="selection"
|
||||||
|
width="55"
|
||||||
|
:reserve-selection="true"
|
||||||
|
/>
|
||||||
<el-table-column prop="bqMc" align="center" label="标签名称" />
|
<el-table-column prop="bqMc" align="center" label="标签名称" />
|
||||||
<el-table-column prop="bqDm" align="center" label="标签代码" />
|
<el-table-column prop="bqDm" align="center" label="标签代码" />
|
||||||
<el-table-column prop="bqDj" align="center" label="标签等级">
|
<el-table-column prop="bqDj" align="center" label="标签等级">
|
||||||
@ -30,11 +58,11 @@
|
|||||||
<div class="fenye" :style="{ top: tableHeight + 'px' }">
|
<div class="fenye" :style="{ top: tableHeight + 'px' }">
|
||||||
<el-pagination
|
<el-pagination
|
||||||
class="pagination"
|
class="pagination"
|
||||||
@size-change="handleSizeChange"
|
@pageSize-change="handleSizeChange"
|
||||||
@current-change="handleCurrentChange"
|
@current-change="handleCurrentChange"
|
||||||
:current-page="listQuery.pages"
|
:current-page="listQuery.pageCurrent"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
:page-size="listQuery.size"
|
:page-pageSize="listQuery.pageSize"
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
:total="total"
|
:total="total"
|
||||||
></el-pagination>
|
></el-pagination>
|
||||||
@ -77,14 +105,14 @@ const props = defineProps({
|
|||||||
default: []
|
default: []
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const loading = ref(false)
|
const loading = ref(false);
|
||||||
const total = ref(0);
|
const total = ref(0);
|
||||||
const listQuery = ref({
|
const listQuery = ref({
|
||||||
pages: 1,
|
pageCurrent: 1,
|
||||||
size: 20
|
pageSize: 20
|
||||||
});
|
});
|
||||||
|
|
||||||
const keyVal = ref()
|
const keyVal = ref();
|
||||||
const multipleUserRef = ref(null);
|
const multipleUserRef = ref(null);
|
||||||
const multipleSelectionUser = ref([]);
|
const multipleSelectionUser = ref([]);
|
||||||
const tableData = ref([]);
|
const tableData = ref([]);
|
||||||
@ -97,11 +125,10 @@ const closed = () => {
|
|||||||
emits("update:modelValue", false);
|
emits("update:modelValue", false);
|
||||||
};
|
};
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
listQuery.value = { pages: 1, size: 20, };
|
listQuery.value = { pageCurrent: 1, pageSize: 20 };
|
||||||
getListData();
|
getListData();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 为用户分配角色
|
// 为用户分配角色
|
||||||
const onComfirm = () => {
|
const onComfirm = () => {
|
||||||
const userList = multipleSelectionUser.value;
|
const userList = multipleSelectionUser.value;
|
||||||
@ -117,31 +144,33 @@ const onComfirm = () => {
|
|||||||
closed();
|
closed();
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* size 改变触发
|
* pageSize 改变触发
|
||||||
*/
|
*/
|
||||||
const handleSizeChange = (currentSize) => {
|
const handleSizeChange = (currentSize) => {
|
||||||
listQuery.value.size = currentSize;
|
listQuery.value.pageSize = currentSize;
|
||||||
getListData();
|
getListData();
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 页码改变触发
|
* 页码改变触发
|
||||||
*/
|
*/
|
||||||
const handleCurrentChange = (currentPage) => {
|
const handleCurrentChange = (currentPage) => {
|
||||||
listQuery.value.pages = currentPage;
|
listQuery.value.pageCurrent = currentPage;
|
||||||
getListData();
|
getListData();
|
||||||
};
|
};
|
||||||
const getListData = () => {
|
const getListData = () => {
|
||||||
keyVal.value++;
|
keyVal.value++;
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const params = { ...listQuery.value, bqLb:'02',}
|
const params = { ...listQuery.value, bqLb: "02" };
|
||||||
qcckGet(params,'/mosty-gsxt/tbGsxtBqgl/selectPage').then(res=>{
|
qcckGet(params, "/mosty-gsxt/tbGsxtBqgl/selectPage")
|
||||||
|
.then((res) => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
tableData.value = res.records || [];
|
tableData.value = res.records || [];
|
||||||
total.value = res.total;
|
total.value = res.total;
|
||||||
multipleUser();
|
multipleUser();
|
||||||
}).catch(()=>{
|
|
||||||
loading.value = false;
|
|
||||||
})
|
})
|
||||||
|
.catch(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
//列表回显
|
//列表回显
|
||||||
@ -155,7 +184,7 @@ function multipleUser() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleFilter = () => {
|
const handleFilter = () => {
|
||||||
listQuery.value.pages = 1;
|
listQuery.value.pageCurrent = 1;
|
||||||
getListData();
|
getListData();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -171,10 +200,13 @@ const handleSelectionChange = (val) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(()=>props.modelValue,val=>{
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(val) => {
|
||||||
if (val) handleFilter();
|
if (val) handleFilter();
|
||||||
},{immediate:true})
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -188,5 +220,4 @@ watch(()=>props.modelValue,val=>{
|
|||||||
.tabBoxRadio .el-table__header-wrapper .el-checkbox {
|
.tabBoxRadio .el-table__header-wrapper .el-checkbox {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
<el-dialog :title="titleValue" width="1400px" :model-value="modelValue" append-to-body @close="closed">
|
<el-dialog :title="titleValue" width="1400px" :model-value="modelValue" append-to-body @close="closed">
|
||||||
<div>
|
<div>
|
||||||
<el-form :model="listQuery" class="mosty-from-wrap" :inline="true">
|
<el-form :model="listQuery" class="mosty-from-wrap" :inline="true">
|
||||||
<el-form-item label="标签名称">
|
<el-form-item label="线索名称">
|
||||||
<el-input placeholder="请输入标签名称" v-model="listQuery.bqMc" clearable ></el-input>
|
<el-input placeholder="请输入线索名称" v-model="listQuery.xsMc" clearable ></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="success" @click="handleFilter">查询</el-button>
|
<el-button type="success" @click="handleFilter">查询</el-button>
|
||||||
|
@ -38,7 +38,7 @@ const formData = ref([
|
|||||||
{ label: "身份证号", prop: "rySfzh", type: "input" ,width:'45%'},
|
{ label: "身份证号", prop: "rySfzh", type: "input" ,width:'45%'},
|
||||||
{ label: "手机号码", prop: "ryLxdh", type: "input",width:'45%' },
|
{ label: "手机号码", prop: "ryLxdh", type: "input",width:'45%' },
|
||||||
{ label: "户籍地址", prop: "hjdXz", type: "input",width:'100%'},
|
{ label: "户籍地址", prop: "hjdXz", type: "input",width:'100%'},
|
||||||
{ label: "现居住地址", prop: "xzdXz", type: "input",width:'100%'},
|
{ label: "户籍地派出所", prop: "hjdpcsdm",depMc:'hjdpcs', type: "department" ,width:'48%'},
|
||||||
{ label: "特征描述", prop: "qtTzms", type: "input" ,width:'100%'},
|
{ label: "特征描述", prop: "qtTzms", type: "input" ,width:'100%'},
|
||||||
{ label: "人员标签", prop: "bqList", type: "slot" ,width:'100%'},
|
{ label: "人员标签", prop: "bqList", type: "slot" ,width:'100%'},
|
||||||
{ label: "车牌号", prop: "clCph", type: "input" ,width:'45%'},
|
{ label: "车牌号", prop: "clCph", type: "input" ,width:'45%'},
|
||||||
|
399
src/components/ExtractionText/index.vue
Normal file
@ -0,0 +1,399 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-dialog v-model="modelValue" title="文件解析" width="1000px" :show-close="true" :center="true" :close-on-click-modal="false" :before-close="handleClose" >
|
||||||
|
<div class="flex align-center">
|
||||||
|
<h3>提取文件类型:</h3>
|
||||||
|
<el-radio-group v-model="active" @change="changeRadio">
|
||||||
|
<el-radio :label="'文件解析'">文件解析</el-radio>
|
||||||
|
<el-radio :label="'图片解析'">图片解析</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</div>
|
||||||
|
<!-- 文件解析 -->
|
||||||
|
<div v-show="active == '文件解析'">
|
||||||
|
<h1>文件文本提取工具</h1>
|
||||||
|
<p>上传文件提取文本内容(支持 .txt, .pdf, .docx, mp4 , mp3, wav)</p>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<input type="file" id="file-input" accept=".txt,.pdf,.docx,'.mp4','.mp3','.wav'"/>
|
||||||
|
<button @click="chooseFile">选择文件</button>
|
||||||
|
<p id="file-info">{{ fileText }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button id="extract-btn" disabled>提取文本</button>
|
||||||
|
|
||||||
|
<h3>提取结果:</h3>
|
||||||
|
<div id="result">{{ content }}</div>
|
||||||
|
</div>
|
||||||
|
<!-- 图片解析 -->
|
||||||
|
<div v-show="active == '图片解析'" v-loading="loading" element-loading-text="模型加载中......">
|
||||||
|
<div class="flex align-center just-between">
|
||||||
|
<h1>文件文本提取工具</h1>
|
||||||
|
<span title="刷新" class="pointer" >
|
||||||
|
<el-icon color="#0072ff" size="30px" @click="frashJs"><RefreshRight /></el-icon>
|
||||||
|
<el-icon color="#23c044" size="14px" v-if="hasLoad"><CircleCheckFilled /></el-icon>
|
||||||
|
<el-icon color="#e60e0e" size="14px" v-if="!hasLoad"><CircleCloseFilled /></el-icon>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p>上传文件提取文本内容(支持 .png, .jpg )</p>
|
||||||
|
<div class="container flex" style="height: 248px;">
|
||||||
|
<div class="mr10">
|
||||||
|
<el-upload :headers="headers" accept=".png,.jpg,jpeg" action="/mosty-api/mosty-base/minio/image/upload/id" :show-file-list="false" :on-success="handlerSuccess" :on-change="onHandleChange" >
|
||||||
|
<el-button size="medium" type="primary">上传图片</el-button>
|
||||||
|
</el-upload>
|
||||||
|
<p id="file-info">{{ files.name || '未选择文件' }} </p>
|
||||||
|
</div>
|
||||||
|
<div class="box">
|
||||||
|
<div class="imd">
|
||||||
|
<img :src="image" v-if="image" style="width: 340px; max-height: 200px"/>
|
||||||
|
<img :src="image" ref="imageRef" v-show="false" />
|
||||||
|
</div>
|
||||||
|
<div class="imd" v-show="false">
|
||||||
|
<canvas ref="canvasRef"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h3>提取结果:</h3>
|
||||||
|
<div class="textModel noScollLine" v-loading="linadingImg" element-loading-text="图片解析中......">
|
||||||
|
<p v-if="texts.length == 0">{{ alertText }}</p>
|
||||||
|
<template v-else>
|
||||||
|
<p v-for="(text, index) in texts" :key="index">{{ text }}</p>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="handleClose">取消</el-button>
|
||||||
|
<el-button type="primary" @click="onComfirm">确认</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import axios from "axios";
|
||||||
|
import * as ocr from "@paddlejs-models/ocr";
|
||||||
|
import { drawBox } from "@/utils/ocrUtils";
|
||||||
|
import { nextTick,reactive, ref,getCurrentInstance, watch } from "vue";
|
||||||
|
import { useStore } from "vuex";
|
||||||
|
const store = useStore();
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const content = ref('请先上传文件...')
|
||||||
|
const fileText = ref('未选择文件')
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
const emits = defineEmits(["update:modelValue", "change"]);
|
||||||
|
const active = ref('文件解析')
|
||||||
|
const hasLoad = ref(false)
|
||||||
|
const files = ref({})
|
||||||
|
const loading = ref(true)
|
||||||
|
const linadingImg = ref(false)
|
||||||
|
const image = ref('')
|
||||||
|
const alertText = ref('请先上传文件...')
|
||||||
|
const texts = ref([])
|
||||||
|
const imageRef = ref()
|
||||||
|
const canvasRef = ref()
|
||||||
|
const textStyle = reactive({
|
||||||
|
width: "",
|
||||||
|
height: ""
|
||||||
|
})
|
||||||
|
const headers = ref({
|
||||||
|
Authorization: store.getters.token
|
||||||
|
});
|
||||||
|
const fjdz = ref('') //附件地址
|
||||||
|
const fjmc = ref('') //附件地址
|
||||||
|
|
||||||
|
const initDemo = () =>{
|
||||||
|
loading.value = imgIsLoad ? false : true;
|
||||||
|
hasLoad.value = imgIsLoad ? true : false;
|
||||||
|
nextTick(() => {
|
||||||
|
const fileInput = document.getElementById("file-input");
|
||||||
|
const extractBtn = document.getElementById("extract-btn");
|
||||||
|
let selectedFile = null;
|
||||||
|
// 监听文件选择
|
||||||
|
fileInput.addEventListener("change", function (e) {
|
||||||
|
if (e.target.files.length > 0) {
|
||||||
|
selectedFile = e.target.files[0];
|
||||||
|
fileText.value = `已选择: ${selectedFile.name} (${( selectedFile.size / 1024 ).toFixed(2)} KB)`;
|
||||||
|
extractBtn.disabled = false;
|
||||||
|
fjmc.value = selectedFile.name;
|
||||||
|
uploadFile(selectedFile); //上传附件
|
||||||
|
} else {
|
||||||
|
selectedFile = null;
|
||||||
|
fileText.value = "未选择文件";
|
||||||
|
extractBtn.disabled = true;
|
||||||
|
}
|
||||||
|
if (selectedFile.type == "video/mp4") {
|
||||||
|
upfileOnchange(selectedFile);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 提取文本按钮点击事件
|
||||||
|
extractBtn.addEventListener("click", async function () {
|
||||||
|
if (!selectedFile) return (content.value = "请先选择文件");
|
||||||
|
content.value = "正在处理文件...";
|
||||||
|
try {
|
||||||
|
let text = "";
|
||||||
|
const fileType = selectedFile.name.split(".").pop().toLowerCase();
|
||||||
|
if (fileType === "txt") {
|
||||||
|
// 处理文本文件
|
||||||
|
text = await readTextFile(selectedFile);
|
||||||
|
} else if (fileType === "pdf") {
|
||||||
|
// 处理PDF文件
|
||||||
|
text = await extractTextFromPDF(selectedFile);
|
||||||
|
} else if (fileType === "docx") {
|
||||||
|
// 处理Word文件
|
||||||
|
text = await extractTextFromDocx(selectedFile);
|
||||||
|
} else if (["mp4", "mp3", "wav"].includes(fileType)) {
|
||||||
|
// 处理mp4,mp3,wav文件
|
||||||
|
await start();
|
||||||
|
text = "数据加载有点慢,请稍等。。。。";
|
||||||
|
setTimeout(() => {
|
||||||
|
content.value = videoText;
|
||||||
|
}, 2000);
|
||||||
|
}else {
|
||||||
|
throw new Error("不支持的文件类型");
|
||||||
|
}
|
||||||
|
content.value = text || "未提取到文本内容";
|
||||||
|
} catch (error) {
|
||||||
|
content.value = `处理失败: ${error.message}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(()=>props.modelValue,val=>{
|
||||||
|
if(val) initDemo();
|
||||||
|
},{immediate:true,deep:true})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 读取文本文件
|
||||||
|
function readTextFile(file) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => resolve(e.target.result);
|
||||||
|
reader.onerror = (e) => reject(new Error("文件读取失败"));
|
||||||
|
reader.readAsText(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取PDF文本
|
||||||
|
async function extractTextFromPDF(file) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const fileReader = new FileReader();
|
||||||
|
|
||||||
|
fileReader.onload = async function () {
|
||||||
|
try {
|
||||||
|
const typedArray = new Uint8Array(this.result);
|
||||||
|
const pdf = await pdfjsLib.getDocument(typedArray).promise;
|
||||||
|
let fullText = "";
|
||||||
|
|
||||||
|
for (let i = 1; i <= pdf.numPages; i++) {
|
||||||
|
const page = await pdf.getPage(i);
|
||||||
|
const textContent = await page.getTextContent();
|
||||||
|
const text = textContent.items.map((item) => item.str).join(" ");
|
||||||
|
fullText += text + "\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(fullText);
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fileReader.onerror = reject;
|
||||||
|
fileReader.readAsArrayBuffer(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取Word文档文本
|
||||||
|
async function extractTextFromDocx(file) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
|
||||||
|
reader.onload = function (event) {
|
||||||
|
const arrayBuffer = event.target.result;
|
||||||
|
mammoth.extractRawText({ arrayBuffer: arrayBuffer }).then(function (result) {
|
||||||
|
resolve(result.value);
|
||||||
|
}).catch(function (error) {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
reader.onerror = reject;
|
||||||
|
reader.readAsArrayBuffer(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlerSuccess = (file) =>{
|
||||||
|
fjdz.value = file.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**@Descripttion:图片上传事件*/
|
||||||
|
const onHandleChange = (file) => {
|
||||||
|
fjmc.value = file.name;
|
||||||
|
files.value = file;
|
||||||
|
image.value = URL.createObjectURL(file.raw);
|
||||||
|
linadingImg.value = true;
|
||||||
|
alertText.value = '图片文件解析中。。。'
|
||||||
|
setTimeout(() => {
|
||||||
|
getRecognize();
|
||||||
|
}, 600);
|
||||||
|
|
||||||
|
}
|
||||||
|
// 图片解析
|
||||||
|
const getRecognize = async () => {
|
||||||
|
const image = imageRef.value;
|
||||||
|
const canvas = canvasRef.value;
|
||||||
|
const res = await ocr.recognize(image);
|
||||||
|
const { text, points } = res;
|
||||||
|
drawBox(points, image, canvas);
|
||||||
|
textStyle.width = image.width - 40 + "px";
|
||||||
|
texts.value = text;
|
||||||
|
linadingImg.value = false;
|
||||||
|
alertText.value = '解析失败,请选择清晰一点的图片重试!'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换标签
|
||||||
|
const changeRadio = (val) =>{
|
||||||
|
content.value = "请先上传文件...";
|
||||||
|
fileText.value = "选择文件";
|
||||||
|
files.value = {};
|
||||||
|
alertText.value = '请先上传文件...';
|
||||||
|
texts.value = [];
|
||||||
|
image.value = '';
|
||||||
|
fjmc.value = '';
|
||||||
|
if(val == '图片解析'){
|
||||||
|
if(!imgIsLoad) proxy.$message({ type: "error", message: "加载失败,请刷新页面" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交
|
||||||
|
const onComfirm = () => {
|
||||||
|
if(active.value == '文件解析'){
|
||||||
|
if(content.value == '请先上传文件...') return proxy.$message({ type: "warning", message: "请解析文件" });
|
||||||
|
emits("change", { text: content.value,fjdz:fjdz.value,fjmc:fjmc.value });
|
||||||
|
}else{
|
||||||
|
if(texts.value.length == 0) return proxy.$message({ type: "warning", message: "请解析文件" });
|
||||||
|
emits("change", {text:texts.value.join(',\n'),fjdz:fjdz.value,fjmc:fjmc.value});
|
||||||
|
}
|
||||||
|
handleClose()
|
||||||
|
};
|
||||||
|
|
||||||
|
// 关闭
|
||||||
|
const handleClose = () => {
|
||||||
|
content.value = "请先上传文件";
|
||||||
|
fileText.value = "未选择文件";
|
||||||
|
files.value = {}
|
||||||
|
alertText.value = '请先上传文件...';
|
||||||
|
texts.value = []
|
||||||
|
image.value = ''
|
||||||
|
active.value = '文件解析'
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 上传附件
|
||||||
|
const uploadFile = (file) =>{
|
||||||
|
let formData = new FormData();
|
||||||
|
formData.append("file", file);
|
||||||
|
let token = localStorage.getItem('token');
|
||||||
|
axios({
|
||||||
|
method: 'post',
|
||||||
|
url: '/mosty-api/mosty-base/minio/image/upload/id',
|
||||||
|
data:formData,
|
||||||
|
headers: { "Content-type": "multipart/form-data",'Authorization': token }
|
||||||
|
}).then( (res) => {
|
||||||
|
fjdz.value = res.data ? res.data.data : null;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 刷新js
|
||||||
|
const frashJs = async () =>{
|
||||||
|
if(!imgIsLoad){
|
||||||
|
try {
|
||||||
|
await ocr.init();// 模型初始化
|
||||||
|
imgIsLoad = true;
|
||||||
|
proxy.$message({ type: "success", message: "加载成功" });
|
||||||
|
} catch (err) {
|
||||||
|
proxy.$message({ type: "error", message: "加载失败,请刷新页面" });
|
||||||
|
imgIsLoad = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const chooseFile = () => {
|
||||||
|
document.getElementById("file-input").click();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.container {
|
||||||
|
border: 2px dashed #ccc;
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#file-input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background: #0072ff;
|
||||||
|
color: white;
|
||||||
|
padding: 10px 15px;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background: #0072ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#result {
|
||||||
|
margin-top: 20px;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
background: #f9f9f9;
|
||||||
|
padding: 15px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 270px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#file-info {
|
||||||
|
margin: 10px 0;
|
||||||
|
font-style: italic;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-dialog {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.box{
|
||||||
|
display: flex;
|
||||||
|
.imd{
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.textModel{
|
||||||
|
margin-top: 20px;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
background: #f9f9f9;
|
||||||
|
padding: 15px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 195px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
</style>
|
@ -46,11 +46,15 @@ const mMap = ref(null); //地图对象
|
|||||||
const mapUtil = ref(null); //地图工具对象
|
const mapUtil = ref(null); //地图工具对象
|
||||||
const zoomTarget = ref(6);
|
const zoomTarget = ref(6);
|
||||||
|
|
||||||
|
// 定义组件发出的事件
|
||||||
|
const emit = defineEmits(['mapLoaded'])
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
mapid: {
|
mapid: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "mapDiv"
|
default: "mapDiv"
|
||||||
},
|
},
|
||||||
|
|
||||||
//是否显示可以切换地图底图
|
//是否显示可以切换地图底图
|
||||||
isShow: {
|
isShow: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -79,6 +83,8 @@ let map;
|
|||||||
let mapLayer;
|
let mapLayer;
|
||||||
let mapLayer1;
|
let mapLayer1;
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
console.log("xxxxxxx");
|
||||||
|
|
||||||
emitter.on("followUp", (res) => {
|
emitter.on("followUp", (res) => {
|
||||||
let box = document.getElementsByClassName("changeMap_box");
|
let box = document.getElementsByClassName("changeMap_box");
|
||||||
if (!box) return;
|
if (!box) return;
|
||||||
@ -110,6 +116,8 @@ onMounted(() => {
|
|||||||
url: 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
|
url: 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
|
||||||
})
|
})
|
||||||
zoomTarget.value = map.mapboxGLMap.getZoom();
|
zoomTarget.value = map.mapboxGLMap.getZoom();
|
||||||
|
// 地图加载完成后发出事件
|
||||||
|
emit('mapLoaded')
|
||||||
});
|
});
|
||||||
mapUtil.value = new MapUtil(map);
|
mapUtil.value = new MapUtil(map);
|
||||||
|
|
||||||
|
359
src/components/GdMap/indexnw.vue
Normal file
@ -0,0 +1,359 @@
|
|||||||
|
<template>
|
||||||
|
<div :id="mapid" class="map"></div>
|
||||||
|
<div class="changeMap_box" v-if="props.isShow">
|
||||||
|
<el-switch v-model="conditionRoute" @change="handleSwitch" active-text="打开路况" inactive-text="关闭路况"
|
||||||
|
style="--el-switch-color: #13ce66; --el-switch-off-color: #ff4949" />
|
||||||
|
<!-- <el-carousel type="card" height="75px" :autoplay="false" indicator-position="none" :initial-index="3" @change="onMapImageChange">
|
||||||
|
<el-carousel-item>
|
||||||
|
<div class="mapImageItem">
|
||||||
|
<img :src="require('@/assets/images/slt.jpg')" alt="" />
|
||||||
|
<div>栅格浅色</div>
|
||||||
|
</div>
|
||||||
|
</el-carousel-item>
|
||||||
|
<el-carousel-item>
|
||||||
|
<div class="mapImageItem">
|
||||||
|
<img :src="require('@/assets/images/yxt.jpg')" alt="" />
|
||||||
|
<div>影像图</div>
|
||||||
|
</div>
|
||||||
|
</el-carousel-item>
|
||||||
|
<el-carousel-item>
|
||||||
|
<div class="mapImageItem">
|
||||||
|
<img :src="require('@/assets/images/yst.jpg')" alt="" />
|
||||||
|
<div>栅格深色</div>
|
||||||
|
</div>
|
||||||
|
</el-carousel-item>
|
||||||
|
<el-carousel-item>
|
||||||
|
<div class="mapImageItem">
|
||||||
|
<img :src="require('@/assets/images/shy.png')" alt="" />
|
||||||
|
<div>三合一</div>
|
||||||
|
</div>
|
||||||
|
</el-carousel-item>
|
||||||
|
</el-carousel> -->
|
||||||
|
<!-- 地图缩放 -->
|
||||||
|
<div class="zoomTargetBox">
|
||||||
|
<el-input-number :min="7" :max="18" v-model="zoomTarget" :step="1" step-strictly @change="handleZoom"></el-input-number>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, onUnmounted, defineProps, nextTick } from "vue";
|
||||||
|
import { MapUtil } from "./mapUtil";
|
||||||
|
import emitter from "@/utils/eventBus.js";
|
||||||
|
import { getItem } from "@/utils/storage";
|
||||||
|
const conditionRoute = ref(true); //路况
|
||||||
|
const mMap = ref(null); //地图对象
|
||||||
|
const mapUtil = ref(null); //地图工具对象
|
||||||
|
const zoomTarget = ref(6);
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
mapid: {
|
||||||
|
type: String,
|
||||||
|
default: "mapDiv"
|
||||||
|
},
|
||||||
|
//是否显示可以切换地图底图
|
||||||
|
isShow: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
//是否显示实时路况
|
||||||
|
isShowMvt: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
//是否显示地图层级
|
||||||
|
isShowZoom: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
//是否显示绘制控件
|
||||||
|
isShowDraw: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
const userInfo = getItem("deptId")[0].deptCode;
|
||||||
|
} catch (error) { }
|
||||||
|
let map;
|
||||||
|
let mapLayer;
|
||||||
|
let mapLayer1;
|
||||||
|
onMounted(() => {
|
||||||
|
emitter.on("followUp", (res) => {
|
||||||
|
let box = document.getElementsByClassName("changeMap_box");
|
||||||
|
if (!box) return;
|
||||||
|
box[0].style.right = !res ? "4px" : "398px";
|
||||||
|
box[0].style.transition = "0.5s";
|
||||||
|
});
|
||||||
|
|
||||||
|
map = new EliMap({
|
||||||
|
id: props.mapid,
|
||||||
|
crs: "EPSG:4490",
|
||||||
|
style: {
|
||||||
|
glyphs: "./fonts/{fontstack}/{range}.pbf",
|
||||||
|
center: [94.36057012, 29.64276831],
|
||||||
|
zoom: 15
|
||||||
|
},
|
||||||
|
minZoom: 7,
|
||||||
|
maxZoom: 18,
|
||||||
|
});
|
||||||
|
window.map = map;
|
||||||
|
map.mapboxGLMap.on("load", () => {
|
||||||
|
map.addWMTSLayer(
|
||||||
|
"/PGIS_S_TileMapServer/Maps/XZDJ_SL/EzMap"
|
||||||
|
,
|
||||||
|
{
|
||||||
|
Service: "getImage",
|
||||||
|
Type: "RGB",
|
||||||
|
ZoomOffset: "0",
|
||||||
|
V: "0.3",
|
||||||
|
Zoom: "{z}",
|
||||||
|
Row: "{y}",
|
||||||
|
Col: "{x}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tileSize: 300
|
||||||
|
}
|
||||||
|
);
|
||||||
|
zoomTarget.value = map.mapboxGLMap.getZoom();
|
||||||
|
});
|
||||||
|
mapUtil.value = new MapUtil(map);
|
||||||
|
|
||||||
|
mapUtil.value.Drawplot(); //初始化加载绘制工具
|
||||||
|
|
||||||
|
// 设置地图中心点及图层
|
||||||
|
emitter.on("setMapCenter", (res) => {
|
||||||
|
mapUtil.value.setMapCenter(res.location, res.zoomLevel);
|
||||||
|
});
|
||||||
|
|
||||||
|
emitter.on("removePlot", (flag) => {
|
||||||
|
mapUtil.value.removePlot(flag);
|
||||||
|
});
|
||||||
|
emitter.on("removeAll", (flag) => {
|
||||||
|
mapUtil.value.removeAll(flag);
|
||||||
|
});
|
||||||
|
// 撒点
|
||||||
|
emitter.on("addPointArea", (obj) => {
|
||||||
|
mapUtil.value.makerSki(obj);
|
||||||
|
});
|
||||||
|
// 鼠标滑过提示文字的点位
|
||||||
|
emitter.on("showPoint", (obj) => {
|
||||||
|
mapUtil.value.showPoint(obj);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 清除覆盖物
|
||||||
|
emitter.on("deletePointArea", (res) => {
|
||||||
|
mapUtil.value.removeElement(res);
|
||||||
|
});
|
||||||
|
// 清除某个覆盖物的单个
|
||||||
|
emitter.on("deletePointAreaOne", (obj) => {
|
||||||
|
mapUtil.value.removeElementOne(obj.flag, obj.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 清除某个覆盖物的单个
|
||||||
|
emitter.on("showSquire", (obj) => {
|
||||||
|
mapUtil.value.zdySquire(obj);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 绘制图形 - 回显区域
|
||||||
|
emitter.on("drawShape", (res) => {
|
||||||
|
mapUtil.value.plot(res, resFun);
|
||||||
|
});
|
||||||
|
emitter.on("removeEara", (flag) => {
|
||||||
|
mapUtil.value.removeEara(flag);
|
||||||
|
});
|
||||||
|
// 回显图形
|
||||||
|
emitter.on("echoPlane", (res) => {
|
||||||
|
mapUtil.value.echoPlane(res);
|
||||||
|
});
|
||||||
|
//移除绘制区域
|
||||||
|
emitter.on("removeEara", (flag) => {
|
||||||
|
mapUtil.value.removeEara(flag);
|
||||||
|
});
|
||||||
|
// 回显线
|
||||||
|
emitter.on("echoLine", (res) => {
|
||||||
|
mapUtil.value.createLine(res, res.flag);
|
||||||
|
});
|
||||||
|
//创建边界面(geojson)
|
||||||
|
emitter.on("setBoundarys", (res) => {
|
||||||
|
mapUtil.value.createBoundarys(res);
|
||||||
|
});
|
||||||
|
// 移除边界
|
||||||
|
emitter.on("removeBj", (res) => {
|
||||||
|
mapUtil.value.removeBj(res);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 轨迹回放
|
||||||
|
emitter.on("drawLineAnimation", (res) => {
|
||||||
|
mapUtil.value.displayLineAnimation(res);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 聚合撒点
|
||||||
|
emitter.on("addPoint", (obj) => {
|
||||||
|
mapUtil.value.aggregateScatteringPoint(obj);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 热力图显示
|
||||||
|
emitter.on("thermodynamicChart", (res) => {
|
||||||
|
mapUtil.value.showHeatDrawing(res);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 扩散圆
|
||||||
|
emitter.on("diffusionCircle", (res) => {
|
||||||
|
mapUtil.value.diffusionCircle(res);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 展示盘曲
|
||||||
|
emitter.on("showGapText", (obj) => {
|
||||||
|
mapUtil.value.gapText(obj);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取当前地图中心点
|
||||||
|
emitter.on("getCurrentCenter", (res) => {
|
||||||
|
let centerPoint = map.mapboxGLMap.getCenter();
|
||||||
|
let coords = [centerPoint.lng, centerPoint.lat];
|
||||||
|
emitter.emit("getcentercoord", coords);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//切换地图底图
|
||||||
|
const onMapImageChange = (val) => {
|
||||||
|
//清除已经存在胡地图图层
|
||||||
|
if (map.mapboxGLMap.getLayer("SGQS_ID"))
|
||||||
|
map.mapboxGLMap.removeLayer("SGQS_ID");
|
||||||
|
if (map.mapboxGLMap.getLayer("YX_ID")) map.mapboxGLMap.removeLayer("YX_ID");
|
||||||
|
if (map.mapboxGLMap.getLayer("SGSG_ID"))
|
||||||
|
map.mapboxGLMap.removeLayer("SGSG_ID");
|
||||||
|
if (map.mapboxGLMap.getLayer("TDT_TITLE_ID"))
|
||||||
|
map.mapboxGLMap.removeLayer("TDT_TITLE_ID");
|
||||||
|
if (map.mapboxGLMap.getLayer("TDT_ROAD_ID"))
|
||||||
|
map.mapboxGLMap.removeLayer("TDT_ROAD_ID");
|
||||||
|
if (map.mapboxGLMap.getLayer("TDT_POI_ID"))
|
||||||
|
map.mapboxGLMap.removeLayer("TDT_POI_ID");
|
||||||
|
//设置图层
|
||||||
|
switch (val) {
|
||||||
|
case 0:
|
||||||
|
mapSetLayer("SGQS_ID", "SGQS");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
mapSetLayer("YX_ID", "YX");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
mapSetLayer("SGSG_ID", "SGSG");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mapSetLayer("TDT_TITLE_ID", "TDT_TITLE_SOURCES");
|
||||||
|
mapSetLayer("TDT_ROAD_ID", "TDT_ROAD_SOURCES");
|
||||||
|
mapSetLayer("TDT_POI_ID", "TDT_POI_SOURCES");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (map.mapboxGLMap.getLayer("realTimeTrafficlevelOne"))
|
||||||
|
map.mapboxGLMap.moveLayer("realTimeTrafficlevelOne");
|
||||||
|
if (map.mapboxGLMap.getLayer("map_id")) map.mapboxGLMap.moveLayer("map_id");
|
||||||
|
if (map.mapboxGLMap.getLayer("map_ids")) map.mapboxGLMap.moveLayer("map_ids");
|
||||||
|
};
|
||||||
|
|
||||||
|
//设置图层函数
|
||||||
|
const mapSetLayer = (id, source) => {
|
||||||
|
map.mapboxGLMap.addLayer({ id, type: "raster", source });
|
||||||
|
};
|
||||||
|
|
||||||
|
//获取地图绘制的数据
|
||||||
|
const resFun = (coord, type, flag, data) => {
|
||||||
|
emitter.emit("coordString", {
|
||||||
|
coord: coord,
|
||||||
|
type: type,
|
||||||
|
flag: flag,
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 地图层级
|
||||||
|
const handleZoom = (val) => {
|
||||||
|
map.mapboxGLMap.setZoom(val);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 是否打开或者关闭路况
|
||||||
|
const handleSwitch = (val) => {
|
||||||
|
if (val) {
|
||||||
|
// 打开
|
||||||
|
} else {
|
||||||
|
// 关闭
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
emitter.off("removePlot");
|
||||||
|
emitter.off("setMapCenter");
|
||||||
|
emitter.off("addPointArea");
|
||||||
|
emitter.off("showPoint");
|
||||||
|
emitter.off("deletePointArea");
|
||||||
|
emitter.off("deletePointAreaOne");
|
||||||
|
emitter.off("drawShape");
|
||||||
|
emitter.off("echoPlane");
|
||||||
|
emitter.off("removeEara");
|
||||||
|
emitter.off("echoLine");
|
||||||
|
emitter.off("addPoint");
|
||||||
|
emitter.off("thermodynamicChart");
|
||||||
|
emitter.off("drawLineAnimation");
|
||||||
|
emitter.off("aggregateScatteringPoint");
|
||||||
|
emitter.off("hotmap");
|
||||||
|
emitter.off("setBoundarys");
|
||||||
|
emitter.off("diffusionCircle");
|
||||||
|
emitter.off("SsCircle");
|
||||||
|
emitter.off("ClearssCircle");
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.map {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: aliceblue;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin: auto;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.changeMap_box {
|
||||||
|
position: absolute;
|
||||||
|
right: 398px;
|
||||||
|
bottom: 4px;
|
||||||
|
z-index: 9;
|
||||||
|
|
||||||
|
.mapImageItem {
|
||||||
|
border: 1px solid #08aae8;
|
||||||
|
background: rgb(9, 26, 70);
|
||||||
|
|
||||||
|
&>img {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&>div {
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
top: -3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.zoomTargetBox {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-left: 23px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-input-number__decrease,
|
||||||
|
::v-deep .el-input-number__increase {
|
||||||
|
background: #133362;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-input__inner {
|
||||||
|
background: #0c1641;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
125
src/components/MarkdownEdit/index.vue
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
<template>
|
||||||
|
<div style="border: 1px solid #ccc">
|
||||||
|
<!-- 工具栏 -->
|
||||||
|
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
|
||||||
|
<!-- 编辑器 -->
|
||||||
|
<Editor :style="`height: ${props.heightNumber}px; overflow-y: hidden`" v-model="editorVal" :defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" @onChange="handChange" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { compressImage } from "@/utils/tools.js";
|
||||||
|
import "@wangeditor/editor/dist/css/style.css";
|
||||||
|
import { qcckPost } from "@/api/qcckApi.js";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
|
||||||
|
import {
|
||||||
|
ref,
|
||||||
|
onMounted,
|
||||||
|
shallowRef,
|
||||||
|
onBeforeUnmount,
|
||||||
|
defineEmits,
|
||||||
|
defineProps,
|
||||||
|
watch
|
||||||
|
} from "vue";
|
||||||
|
const props = defineProps({
|
||||||
|
// 编辑器内容
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
markitVal: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: "请输入内容。。。。"
|
||||||
|
},
|
||||||
|
heightNumber: {
|
||||||
|
type: Number,
|
||||||
|
default: 500
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const editorVal = ref("");
|
||||||
|
const editorRef = shallowRef();
|
||||||
|
const mode = "default";
|
||||||
|
const valueHtml = ref(""); //内容
|
||||||
|
//工具配置
|
||||||
|
const toolbarConfig = {
|
||||||
|
excludeKeys: ["blockquote", "codeBlock"] //清除不必要的工具,引用和代码块
|
||||||
|
};
|
||||||
|
const emits = defineEmits(["update:modelValue", "changeFn"]);
|
||||||
|
//编辑器配置
|
||||||
|
const editorConfig = {
|
||||||
|
withCredentials: true, //允许跨域
|
||||||
|
placeholder: props.placeholder, //提示语
|
||||||
|
MENU_CONF: {
|
||||||
|
uploadImage: {
|
||||||
|
// 自定义上传图片
|
||||||
|
async customUpload(file, insertFn) {
|
||||||
|
let fileBlob = await compressImage(file);
|
||||||
|
let fileData = new File([fileBlob], fileBlob.name, {
|
||||||
|
type: fileBlob.type
|
||||||
|
});
|
||||||
|
if (fileData.size > 2 * 1024 * 1024) {
|
||||||
|
ElMessage({
|
||||||
|
message: "图片超过2MB",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await uploadFn(fileData, insertFn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// server: "/mosty-api/mosty-base/minio/image/upload",
|
||||||
|
// base64LimitSize: 10000 * 1024,
|
||||||
|
},
|
||||||
|
uploadVideo: {
|
||||||
|
// 自定义上传视频
|
||||||
|
async customUpload(file, insertFn) {
|
||||||
|
await uploadFn(file, insertFn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
watch(
|
||||||
|
[() => props.markitVal, () => editorRef.value],
|
||||||
|
(val) => {
|
||||||
|
// if (val) editorRef.value = val;
|
||||||
|
if ((val[0] && val[1]) || val[0] == "") {
|
||||||
|
editorVal.value = val[0];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
const uploadFn = (file, insertFn) => {
|
||||||
|
let param = new FormData();
|
||||||
|
param.append("file", file);
|
||||||
|
qcckPost(param, "/mosty-base/minio/image/upload").then((res) => {
|
||||||
|
insertFn(res);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//编辑器创建成功
|
||||||
|
const handleCreated = (editor) => {
|
||||||
|
editorRef.value = editor;
|
||||||
|
};
|
||||||
|
//内容发生变化
|
||||||
|
const handChange = (editor) => {
|
||||||
|
// console.log(editor.getHtml(),'editor.getText()');
|
||||||
|
// 判断是否是一个空段落,是空就传空文本
|
||||||
|
if (editor.isEmpty()) {
|
||||||
|
emits("changeFn", editor.getText());
|
||||||
|
} else {
|
||||||
|
emits("changeFn", editor.getHtml());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
const editor = editorRef.value;
|
||||||
|
if (editor) editor.destroy();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
@ -1,8 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<!--选择图标-->
|
<!--选择图标-->
|
||||||
<div class="form-item-box choose-icon-zj" :style="{ width: width }">
|
<div class="form-item-box choose-icon-zj" :style="{ width: width }">
|
||||||
<el-autocomplete v-bind="$attrs" v-model="modelValue" :fetch-suggestions="querySearch"
|
<el-autocomplete
|
||||||
popper-class="choose-icon-zj-autocomplete" :placeholder="placeholder" @change="onInput" @select="handleSelect">
|
v-bind="$attrs"
|
||||||
|
v-model="modelValue"
|
||||||
|
:fetch-suggestions="querySearch"
|
||||||
|
popper-class="choose-icon-zj-autocomplete"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
@change="onInput"
|
||||||
|
@select="handleSelect"
|
||||||
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<SvgIcon :icon="modelValue"></SvgIcon>
|
<SvgIcon :icon="modelValue"></SvgIcon>
|
||||||
</template>
|
</template>
|
||||||
@ -57,8 +64,7 @@ const handleSelect = (item) => {
|
|||||||
emits("update:modelValue", item.value);
|
emits("update:modelValue", item.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleIconClick = (ev) => {
|
const handleIconClick = (ev) => {};
|
||||||
};
|
|
||||||
|
|
||||||
const loadAll = () => {
|
const loadAll = () => {
|
||||||
const svgRequire = require.context("@/icons/svg", false, /\.svg$/);
|
const svgRequire = require.context("@/icons/svg", false, /\.svg$/);
|
||||||
|
@ -1,12 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="form-item-box" :style="{ width: width }">
|
<div class="form-item-box" :style="{ width: width }">
|
||||||
<el-date-picker style="width:100%" v-model="modelValue" type="date" v-bind="$attrs" @change="onInput" :placeholder="placeholder" :value-format="props.format"/>
|
<el-date-picker
|
||||||
|
style="width:100%"
|
||||||
|
v-model="localModelValue"
|
||||||
|
:type="props.type"
|
||||||
|
v-bind="$attrs"
|
||||||
|
@change="onInput"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:value-format="props.format"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { COMPONENT_WIDTH } from "@/constant";
|
import { COMPONENT_WIDTH } from "@/constant";
|
||||||
import { ref, defineProps, defineEmits, defineExpose } from "vue";
|
import { ref, defineProps, defineEmits, defineExpose, computed } from "vue";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
//获取组件传值
|
//获取组件传值
|
||||||
placeholder: {
|
placeholder: {
|
||||||
@ -25,12 +34,21 @@ const props = defineProps({
|
|||||||
default: COMPONENT_WIDTH,
|
default: COMPONENT_WIDTH,
|
||||||
type: String
|
type: String
|
||||||
},
|
},
|
||||||
|
type: {
|
||||||
|
default: "date",
|
||||||
|
type: String
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const emits = defineEmits(["update:modelValue"]);
|
const emits = defineEmits(["update:modelValue"]);
|
||||||
|
|
||||||
|
// 使用计算属性处理双向绑定
|
||||||
|
const localModelValue = computed({
|
||||||
|
get: () => props.modelValue,
|
||||||
|
set: (value) => emits("update:modelValue", value)
|
||||||
|
});
|
||||||
|
|
||||||
const onInput = (e) => {
|
const onInput = (e) => {
|
||||||
emits("update:modelValue", e);
|
emits("update:modelValue", e);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import { COMPONENT_WIDTH } from "@/constant";
|
|||||||
import { qcckPost, qcckGet, qcckFlvGet } from "@/api/qcckApi.js";
|
import { qcckPost, qcckGet, qcckFlvGet } from "@/api/qcckApi.js";
|
||||||
import { ref, defineProps, defineEmits, defineExpose, computed, onMounted, watch } from "vue";
|
import { ref, defineProps, defineEmits, defineExpose, computed, onMounted, watch } from "vue";
|
||||||
import { selectDeptPage } from "@/api/user-manage";
|
import { selectDeptPage } from "@/api/user-manage";
|
||||||
|
import { tr } from "element-plus/es/locale.mjs";
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
//获取组件传值
|
//获取组件传值
|
||||||
placeholder: {
|
placeholder: {
|
||||||
@ -41,9 +42,13 @@ const props = defineProps({
|
|||||||
width: {
|
width: {
|
||||||
default: COMPONENT_WIDTH,
|
default: COMPONENT_WIDTH,
|
||||||
type: String
|
type: String
|
||||||
|
},
|
||||||
|
isAll:{
|
||||||
|
default: false,
|
||||||
|
type: Boolean
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const modelShow = ref(false);
|
const firstLoad = ref(true)
|
||||||
const oldmodelValue = ref([]);
|
const oldmodelValue = ref([]);
|
||||||
const listQuery = ref({
|
const listQuery = ref({
|
||||||
deptname: "",
|
deptname: "",
|
||||||
@ -61,7 +66,12 @@ const endProps = {
|
|||||||
lazy: true,
|
lazy: true,
|
||||||
lazyLoad(node, resolve) {
|
lazyLoad(node, resolve) {
|
||||||
listQuery.value.parentid = node.data.id;
|
listQuery.value.parentid = node.data.id;
|
||||||
selectDeptPage(listQuery.value).then((res) => {
|
let params = { ...listQuery.value };
|
||||||
|
if(props.isAll && firstLoad.value) {
|
||||||
|
params.parentid = 1;
|
||||||
|
firstLoad.value = false;
|
||||||
|
}
|
||||||
|
selectDeptPage(params).then((res) => {
|
||||||
depList.value = depList.value.concat(res)
|
depList.value = depList.value.concat(res)
|
||||||
//处理部门是否包含下级
|
//处理部门是否包含下级
|
||||||
for (let i = 0; i < res.length; i++) {
|
for (let i = 0; i < res.length; i++) {
|
||||||
@ -73,7 +83,9 @@ const endProps = {
|
|||||||
};
|
};
|
||||||
const tableData = ref([]);
|
const tableData = ref([]);
|
||||||
const getSysMenuTree = async () => {
|
const getSysMenuTree = async () => {
|
||||||
const res = await selectDeptPage(listQuery.value);
|
let params = { ...listQuery.value }
|
||||||
|
if(props.isAll) params.parentid = 1;
|
||||||
|
const res = await selectDeptPage(params);
|
||||||
tableData.value = res;
|
tableData.value = res;
|
||||||
depList.value = res
|
depList.value = res
|
||||||
};
|
};
|
||||||
|
@ -1,75 +1,35 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div class="form-item-box" :class="props.showBtn ? 'showBtn-upload' : ''" :style="{ width: width }">
|
||||||
class="form-item-box"
|
<el-upload v-bind="$attrs" :headers="headers" :multiple="false" class="avatar-uploader" :limit="props.limit"
|
||||||
:class="props.showBtn ? 'showBtn-upload' : ''"
|
:action="actionUrl" :list-type="props.showBtn ? '' : 'picture-card'" :file-list="fileList" show-file-list
|
||||||
:style="{ width: width }"
|
:on-exceed="handleExceed" :on-success="handlerSuccess" :before-upload="beforeImgUpload">
|
||||||
>
|
|
||||||
<el-upload
|
|
||||||
v-bind="$attrs"
|
|
||||||
:headers="headers"
|
|
||||||
:multiple="false"
|
|
||||||
class="avatar-uploader"
|
|
||||||
:limit="props.limit"
|
|
||||||
:action="actionUrl"
|
|
||||||
:list-type="props.showBtn ? '' : 'picture-card'"
|
|
||||||
:file-list="fileList"
|
|
||||||
show-file-list
|
|
||||||
:on-exceed="handleExceed"
|
|
||||||
:on-success="handlerSuccess"
|
|
||||||
:before-upload="beforeImgUpload"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
<el-button v-if="props.showBtn" size="small" type="primary"
|
<el-button v-if="props.showBtn" size="small" type="primary">上传文件</el-button>
|
||||||
>上传文件</el-button
|
|
||||||
>
|
|
||||||
<el-icon v-else><Plus /></el-icon>
|
<el-icon v-else><Plus /></el-icon>
|
||||||
</template>
|
</template>
|
||||||
<template #file="{ file }" v-if="!props.showBtn">
|
<template #file="{ file }" v-if="!props.showBtn">
|
||||||
<div v-if="props.isImg">
|
<div v-if="props.isImg">
|
||||||
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
|
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
|
||||||
<span class="el-upload-list__item-actions">
|
<span class="el-upload-list__item-actions">
|
||||||
<span
|
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
|
||||||
class="el-upload-list__item-preview"
|
|
||||||
@click="handlePictureCardPreview(file)"
|
|
||||||
>
|
|
||||||
<el-icon> <zoom-in /></el-icon>
|
<el-icon> <zoom-in /></el-icon>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file, fileList)">
|
||||||
v-if="!disabled"
|
<el-icon><Delete /></el-icon>
|
||||||
class="el-upload-list__item-delete"
|
|
||||||
@click="handleRemove(file, fileList)"
|
|
||||||
>
|
|
||||||
<el-icon>
|
|
||||||
<Delete />
|
|
||||||
</el-icon>
|
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div class="file-wrap">
|
<div class="file-wrap">
|
||||||
<span>
|
<span><svg-icon :icon="getSuffix(file.name)" /></span>
|
||||||
<svg-icon :icon="getSuffix(file.name)" />
|
|
||||||
</span>
|
|
||||||
<span class="file-name">{{ file.name }}</span>
|
<span class="file-name">{{ file.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="el-upload-list__item-actions">
|
<span class="el-upload-list__item-actions">
|
||||||
<span
|
<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleDownload(file)">
|
||||||
v-if="!disabled"
|
<el-icon><Download /></el-icon>
|
||||||
class="el-upload-list__item-delete"
|
|
||||||
@click="handleDownload(file)"
|
|
||||||
>
|
|
||||||
<el-icon>
|
|
||||||
<Download />
|
|
||||||
</el-icon>
|
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file, fileList)">
|
||||||
v-if="!disabled"
|
<el-icon><Delete /></el-icon>
|
||||||
class="el-upload-list__item-delete"
|
|
||||||
@click="handleRemove(file, fileList)"
|
|
||||||
>
|
|
||||||
<el-icon>
|
|
||||||
<Delete />
|
|
||||||
</el-icon>
|
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -107,14 +67,22 @@ const props = defineProps({
|
|||||||
showBtn: {
|
showBtn: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
isAll: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const actionUrl = computed(() =>
|
const actionUrl = computed(() => {
|
||||||
props.isImg
|
if (props.isAll) {
|
||||||
|
return "/mosty-api/mosty-base/minio/image/upload/id";
|
||||||
|
} else {
|
||||||
|
return props.isImg
|
||||||
? "/mosty-api/mosty-base/minio/image/upload/id"
|
? "/mosty-api/mosty-base/minio/image/upload/id"
|
||||||
: "/mosty-api/mosty-base/minio/file/upload"
|
: "/mosty-api/mosty-base/minio/file/upload";
|
||||||
);
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const emits = defineEmits(["update:modelValue", "handleChange"]);
|
const emits = defineEmits(["update:modelValue", "handleChange"]);
|
||||||
|
|
||||||
@ -149,7 +117,17 @@ const getSuffix = (fileName) => {
|
|||||||
if (suffix === "pdf") return "PDF";
|
if (suffix === "pdf") return "PDF";
|
||||||
|
|
||||||
//视频 音频
|
//视频 音频
|
||||||
var videolist = [ "mp4", "m2v", "mkv", "rmvb", "wmv", "avi", "flv", "mov", "m4v" ];
|
var videolist = [
|
||||||
|
"mp4",
|
||||||
|
"m2v",
|
||||||
|
"mkv",
|
||||||
|
"rmvb",
|
||||||
|
"wmv",
|
||||||
|
"avi",
|
||||||
|
"flv",
|
||||||
|
"mov",
|
||||||
|
"m4v"
|
||||||
|
];
|
||||||
if (videolist.includes(suffix)) return "VIDEO";
|
if (videolist.includes(suffix)) return "VIDEO";
|
||||||
|
|
||||||
var musiclist = ["mp3", "wav", "wmv"];
|
var musiclist = ["mp3", "wav", "wmv"];
|
||||||
@ -174,7 +152,6 @@ const headers = ref({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const fileList = ref([]);
|
const fileList = ref([]);
|
||||||
;
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
(val) => {
|
(val) => {
|
||||||
@ -182,11 +159,22 @@ watch(
|
|||||||
if (arr && arr.length > 0) {
|
if (arr && arr.length > 0) {
|
||||||
if (!props.sfUrl) {
|
if (!props.sfUrl) {
|
||||||
fileList.value = arr.map((el) => {
|
fileList.value = arr.map((el) => {
|
||||||
|
if (Object.prototype.toString.call(el) === "[object Object]") {
|
||||||
|
return {
|
||||||
|
url: `/mosty-api/mosty-base/minio/image/download/` + el,
|
||||||
|
name: el.name
|
||||||
|
};
|
||||||
|
} else {
|
||||||
return { url: `/mosty-api/mosty-base/minio/image/download/` + el };
|
return { url: `/mosty-api/mosty-base/minio/image/download/` + el };
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
fileList.value = arr.map((el) => {
|
fileList.value = arr.map((el) => {
|
||||||
|
if (Object.prototype.toString.call(el) === "[object Object]") {
|
||||||
|
return { url: el, name: el.name };
|
||||||
|
} else {
|
||||||
return { url: el };
|
return { url: el };
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,7 +182,6 @@ watch(
|
|||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
const handlerSuccess = (res, file) => {
|
const handlerSuccess = (res, file) => {
|
||||||
file.url = `/mosty-api/mosty-base/minio/image/download/` + res.data;
|
file.url = `/mosty-api/mosty-base/minio/image/download/` + res.data;
|
||||||
fileList.value.push(file);
|
fileList.value.push(file);
|
||||||
@ -244,7 +231,6 @@ const handleRemove = (file) => {
|
|||||||
emits("update:modelValue", props.modelValue);
|
emits("update:modelValue", props.modelValue);
|
||||||
};
|
};
|
||||||
const propsModelValue = ref();
|
const propsModelValue = ref();
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -29,10 +29,7 @@
|
|||||||
:header-cell-class-name="() => 'myTableHeadBgColorDark'"
|
:header-cell-class-name="() => 'myTableHeadBgColorDark'"
|
||||||
:highlight-current-row="getConfiger.showSelectType === 'radio'"
|
:highlight-current-row="getConfiger.showSelectType === 'radio'"
|
||||||
:row-style="{
|
:row-style="{
|
||||||
height:
|
height: getConfiger.rowHeight === 'auto' ? getConfiger.rowHeight : getConfiger.rowHeight + 'px'
|
||||||
getConfiger.rowHeight === 'auto'
|
|
||||||
? getConfiger.rowHeight
|
|
||||||
: getConfiger.rowHeight + 'px'
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
@ -1,167 +1,57 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-form
|
<el-form ref="elform" :model="listQuery" :label-width="props.labelWidth" :rules="props.rules" :inline="props.inline"
|
||||||
ref="elform"
|
label-position="right" :disabled="props.disabled">
|
||||||
:model="listQuery"
|
<el-form-item v-for="(item, idx) in props.formList" :style="item.width && { width: item.width }" :prop="item.prop"
|
||||||
:label-width="props.labelWidth"
|
:label="item.label" :label-width="item.labelWidth" :key="idx">
|
||||||
:rules="props.rules"
|
|
||||||
:inline="props.inline"
|
|
||||||
label-position="right"
|
|
||||||
:disabled="props.disabled"
|
|
||||||
>
|
|
||||||
<el-form-item
|
|
||||||
v-for="(item,idx) in props.formList"
|
|
||||||
:style="item.width && { width: item.width }"
|
|
||||||
:prop="item.prop"
|
|
||||||
:label="item.label"
|
|
||||||
:label-width="item.labelWidth"
|
|
||||||
:key="idx"
|
|
||||||
>
|
|
||||||
<!-- input表单 input-->
|
<!-- input表单 input-->
|
||||||
<MOSTY.Other
|
<MOSTY.Other v-if="item.type == 'input'" width="100%" clearable v-model="listQuery[item.prop]"
|
||||||
v-if="item.type == 'input'"
|
:placeholder="`请输入${item.label}`" :disabled="item.disabled" />
|
||||||
width="100%"
|
<el-input v-model="listQuery[item.prop]" v-else-if="item.type == 'textarea'" type="textarea" :rows="3"
|
||||||
clearable
|
:placeholder="`请输入${item.label}`" :disabled="item.disabled" />
|
||||||
v-model="listQuery[item.prop]"
|
|
||||||
:placeholder="`请输入${item.label}`"
|
|
||||||
:disabled="item.disabled"
|
|
||||||
/>
|
|
||||||
<el-input
|
|
||||||
v-model="listQuery[item.prop]"
|
|
||||||
v-else-if="item.type == 'textarea'"
|
|
||||||
type="textarea"
|
|
||||||
:rows="3"
|
|
||||||
:placeholder="`请输入${item.label}`"
|
|
||||||
:disabled="item.disabled"
|
|
||||||
/>
|
|
||||||
<!-- 数值 inputNumber-->
|
<!-- 数值 inputNumber-->
|
||||||
<el-input
|
<el-input type="number" v-model="listQuery[item.prop]" v-else-if="item.type == 'inputNumber'"
|
||||||
type="number"
|
:placeholder="`请输入${item.label}`" :disabled="item.disabled" />
|
||||||
v-model="listQuery[item.prop]"
|
|
||||||
v-else-if="item.type == 'inputNumber'"
|
|
||||||
:placeholder="`请输入${item.label}`"
|
|
||||||
:disabled="item.disabled"
|
|
||||||
/>
|
|
||||||
<!-- 数值 number-->
|
<!-- 数值 number-->
|
||||||
<el-input-number
|
<el-input-number v-model="listQuery[item.prop]" v-else-if="item.type == 'number'" style="width: 100%"
|
||||||
v-model="listQuery[item.prop]"
|
:min="item.min || 0" :max="item.max || 1000" :disabled="item.disabled" />
|
||||||
v-else-if="item.type == 'number'"
|
|
||||||
style="width: 100%"
|
|
||||||
:min="item.min || 0"
|
|
||||||
:max="item.max || 1000"
|
|
||||||
:disabled="item.disabled"
|
|
||||||
/>
|
|
||||||
<!--选择 select-->
|
<!--选择 select-->
|
||||||
<MOSTY.Select
|
<MOSTY.Select v-else-if="item.type == 'select'" filterable :multiple="item.multiple"
|
||||||
v-else-if="item.type == 'select'"
|
v-model="listQuery[item.prop]" :dictEnum="item.options" width="100%" clearable :placeholder="`请选择${item.label}`"
|
||||||
filterable
|
:disabled="item.disabled" />
|
||||||
:multiple="item.multiple"
|
|
||||||
v-model="listQuery[item.prop]"
|
|
||||||
:dictEnum="item.options"
|
|
||||||
width="100%"
|
|
||||||
clearable
|
|
||||||
:placeholder="`请选择${item.label}`"
|
|
||||||
:disabled="item.disabled"
|
|
||||||
/>
|
|
||||||
<!-- 部门department -->
|
<!-- 部门department -->
|
||||||
<template v-else-if="item.type === 'department'">
|
<template v-else-if="item.type === 'department'">
|
||||||
<MOSTY.Department
|
<MOSTY.Department style="width: 100%;" clearable :isAll="item.isAll" @getDepValue="getdep($event, item.depMc)"
|
||||||
style="width: 100%;"
|
v-model="listQuery[item.prop]" :placeholder="listQuery[item.depMc] ? listQuery[item.depMc] : '请选择'" />
|
||||||
clearable
|
|
||||||
v-model="listQuery[item.prop]"
|
|
||||||
:placeholder="listQuery[item.prop] ? listQuery[item.prop+'mc']:''"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 上传 upload -->
|
<!-- 上传 upload -->
|
||||||
<MOSTY.Upload
|
<MOSTY.Upload v-else-if="item.type == 'upload'" width="100%" v-model="listQuery[item.prop]" :isImg="item.isImg"
|
||||||
v-else-if="item.type == 'upload'"
|
:disabled="item.disabled" />
|
||||||
width="100%"
|
|
||||||
v-model="listQuery[item.prop]"
|
|
||||||
:isImg="item.isImg"
|
|
||||||
:disabled="item.disabled"
|
|
||||||
/>
|
|
||||||
<!--选择checkbox -->
|
<!--选择checkbox -->
|
||||||
<MOSTY.CheckBox
|
<MOSTY.CheckBox v-else-if="item.type == 'checkbox'" width="100%" clearable v-model="listQuery[item.prop]"
|
||||||
v-else-if="item.type == 'checkbox'"
|
:checkList="item.options" :placeholder="`请选择${item.label}`" :disabled="item.disabled" />
|
||||||
width="100%"
|
|
||||||
clearable
|
|
||||||
v-model="listQuery[item.prop]"
|
|
||||||
:checkList="item.options"
|
|
||||||
:placeholder="`请选择${item.label}`"
|
|
||||||
:disabled="item.disabled"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 单选radio -->
|
<!-- 单选radio -->
|
||||||
<el-radio-group
|
<el-radio-group v-model="listQuery[item.prop]" v-else-if="item.type == 'radio'" :disabled="item.disabled">
|
||||||
v-model="listQuery[item.prop]"
|
<el-radio v-for="obj in item.options" :key="obj.value" :label="obj.value">{{ obj.label }}</el-radio>
|
||||||
v-else-if="item.type == 'radio'"
|
|
||||||
:disabled="item.disabled"
|
|
||||||
>
|
|
||||||
<el-radio
|
|
||||||
v-for="obj in item.options"
|
|
||||||
:key="obj.value"
|
|
||||||
:label="obj.value"
|
|
||||||
>{{ obj.label }}</el-radio
|
|
||||||
>
|
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
|
|
||||||
<!-- 时间选择 -->
|
<!-- 时间选择 -->
|
||||||
<el-time-picker
|
<el-time-picker v-else-if="item.type == 'time'" v-model="listQuery[item.prop]" placeholder="选择时间"
|
||||||
v-else-if="item.type == 'time'"
|
style="width: 100%" :disabled="item.disabled" />
|
||||||
v-model="listQuery[item.prop]"
|
<el-date-picker v-else-if="item.type == 'date'" v-model="listQuery[item.prop]" type="date"
|
||||||
placeholder="选择时间"
|
value-format="YYYY-MM-DD" placeholder="请选择日期" style="width: 100%" :disabled="item.disabled" />
|
||||||
style="width: 100%"
|
<el-date-picker v-else-if="item.type == 'datetime'" v-model="listQuery[item.prop]" type="datetime"
|
||||||
:disabled="item.disabled"
|
value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择时间" style="width: 100%" :disabled="item.disabled" />
|
||||||
/>
|
<el-date-picker v-else-if="item.type == 'datetimerange'" v-model="listQuery[item.prop]" type="datetimerange"
|
||||||
<el-date-picker
|
:shortcuts="shortcuts" range-separator="To" value-format="YYYY-MM-DD HH:mm:ss" start-placeholder="选择开始时间"
|
||||||
v-else-if="item.type == 'date'"
|
end-placeholder="选择结束时间" style="width: 100%" :disabled="item.disabled" />
|
||||||
v-model="listQuery[item.prop]"
|
<el-date-picker v-else-if="item.type == 'daterange'" v-model="listQuery[item.prop]" type="daterange"
|
||||||
type="date"
|
range-separator="To" value-format="YYYY-MM-DD" start-placeholder="选择开始日期" end-placeholder="选择开始日期"
|
||||||
value-format="YYYY-MM-DD"
|
style="width: 100%" :disabled="item.disabled" />
|
||||||
placeholder="请选择日期"
|
|
||||||
style="width: 100%"
|
|
||||||
:disabled="item.disabled"
|
|
||||||
/>
|
|
||||||
<el-date-picker
|
|
||||||
v-else-if="item.type == 'datetime'"
|
|
||||||
v-model="listQuery[item.prop]"
|
|
||||||
type="datetime"
|
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
placeholder="请选择时间"
|
|
||||||
style="width: 100%"
|
|
||||||
:disabled="item.disabled"
|
|
||||||
/>
|
|
||||||
<el-date-picker
|
|
||||||
v-else-if="item.type == 'datetimerange'"
|
|
||||||
v-model="listQuery[item.prop]"
|
|
||||||
type="datetimerange"
|
|
||||||
:shortcuts="shortcuts"
|
|
||||||
range-separator="To"
|
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
start-placeholder="选择开始时间"
|
|
||||||
end-placeholder="选择结束时间"
|
|
||||||
style="width: 100%"
|
|
||||||
:disabled="item.disabled"
|
|
||||||
/>
|
|
||||||
<el-date-picker
|
|
||||||
v-else-if="item.type == 'daterange'"
|
|
||||||
v-model="listQuery[item.prop]"
|
|
||||||
type="daterange"
|
|
||||||
range-separator="To"
|
|
||||||
value-format="YYYY-MM-DD"
|
|
||||||
start-placeholder="选择开始日期"
|
|
||||||
end-placeholder="选择开始日期"
|
|
||||||
style="width: 100%"
|
|
||||||
:disabled="item.disabled"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<el-switch
|
<el-switch v-else-if="item.type == 'switch'" v-model="listQuery[item.prop]" class="ml-2" :disabled="item.disabled"
|
||||||
v-else-if="item.type == 'switch'"
|
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" />
|
||||||
v-model="listQuery[item.prop]"
|
|
||||||
class="ml-2"
|
|
||||||
:disabled="item.disabled"
|
|
||||||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<template v-else-if="item.type === 'slot'">
|
<template v-else-if="item.type === 'slot'">
|
||||||
<slot :name="item.prop"></slot>
|
<slot :name="item.prop"></slot>
|
||||||
@ -193,6 +83,10 @@ const props = defineProps({
|
|||||||
inline: {
|
inline: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const elform = ref();
|
const elform = ref();
|
||||||
@ -206,22 +100,32 @@ const submit = (resfun) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getdep = (e, val) => {
|
||||||
|
if (val) listQuery.value[val] = e ? e.orgName : '';
|
||||||
|
}
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
elform.value.resetFields()
|
elform.value.resetFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 修改这里的watch逻辑,避免无限循环
|
||||||
|
let isUpdatingFromProps = false;
|
||||||
|
|
||||||
watch(() => listQuery.value, (newVal) => {
|
watch(() => listQuery.value, (newVal) => {
|
||||||
if(newVal) emits("update:modelValue", newVal);
|
if (newVal && !isUpdatingFromProps) {
|
||||||
},{ immediate: true, deep: true });
|
emits("update:modelValue", newVal);
|
||||||
|
}
|
||||||
|
}, { deep: true });
|
||||||
|
|
||||||
watch(() => props.modelValue, (newVal) => {
|
watch(() => props.modelValue, (newVal) => {
|
||||||
// 只有在新值确实变化时才更新(避免空值覆盖)
|
// 只有在新值确实变化时才更新(避免空值覆盖)
|
||||||
if (newVal && Object.keys(newVal).length > 0) {
|
if (newVal && Object.keys(newVal).length > 0) {
|
||||||
|
isUpdatingFromProps = true;
|
||||||
listQuery.value = { ...newVal };
|
listQuery.value = { ...newVal };
|
||||||
|
setTimeout(() => {
|
||||||
|
isUpdatingFromProps = false;
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
}, { immediate: true, deep: true });
|
}, { immediate: true, deep: true });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
defineExpose({ submit, reset });
|
defineExpose({ submit, reset });
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="width: 100%">
|
<div style="width: 100%" :class="getConfiger.showSelectType === 'radio' ? 'tabBoxRadio' : ''">
|
||||||
<!-- hasChildren要在tableData中定义表示当前行有没有下一级 children要在tableData中定义表示下一级的数据-->
|
<!-- hasChildren要在tableData中定义表示当前行有没有下一级 children要在tableData中定义表示下一级的数据-->
|
||||||
<el-table
|
<el-table
|
||||||
ref="multipleTableRef"
|
ref="multipleTableRef"
|
||||||
:data="tableData"
|
:data="tableData"
|
||||||
@selection-change="handleSelectionChange"
|
@selection-change="handleSelectionChange"
|
||||||
@current-change="handleCurrentChange"
|
|
||||||
@row-click="singleElection"
|
|
||||||
:row-key="getConfiger.rowKey"
|
:row-key="getConfiger.rowKey"
|
||||||
:border="getConfiger.border"
|
:border="getConfiger.border"
|
||||||
:default-expand-all="getConfiger.defaultExpandAll"
|
:default-expand-all="getConfiger.defaultExpandAll"
|
||||||
@ -21,23 +19,7 @@
|
|||||||
:highlight-current-row="getConfiger.showSelectType === 'radio'"
|
:highlight-current-row="getConfiger.showSelectType === 'radio'"
|
||||||
:row-style="{ height: getConfiger.rowHeight === 'auto' ? getConfiger.rowHeight : getConfiger.rowHeight + 'px'}"
|
:row-style="{ height: getConfiger.rowHeight === 'auto' ? getConfiger.rowHeight : getConfiger.rowHeight + 'px'}"
|
||||||
>
|
>
|
||||||
<el-table-column
|
<el-table-column type="selection" width="55" />
|
||||||
type="selection"
|
|
||||||
width="55"
|
|
||||||
v-if="getConfiger.showSelectType === 'checkBox'"
|
|
||||||
/>
|
|
||||||
<el-table-column
|
|
||||||
width="55"
|
|
||||||
v-else-if="getConfiger.showSelectType === 'radio'"
|
|
||||||
#default="{ row }"
|
|
||||||
>
|
|
||||||
<el-radio
|
|
||||||
class="radio"
|
|
||||||
v-model="getConfiger.radioChoose"
|
|
||||||
:label="row[getConfiger.rowKey]"
|
|
||||||
> </el-radio
|
|
||||||
>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
type="index"
|
type="index"
|
||||||
label="序号"
|
label="序号"
|
||||||
@ -148,19 +130,16 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
// 可选的时候选择的数据
|
// 可选的时候选择的数据
|
||||||
const handleSelectionChange = (val) => {
|
const handleSelectionChange = (val) => {
|
||||||
emit("chooseData", val);
|
if(getConfiger.showSelectType === 'radio' && val.length > 1){
|
||||||
};
|
let del_row = val.shift();
|
||||||
// 单选的时候选择的数据
|
multipleTableRef.value.toggleRowSelection(del_row, false);
|
||||||
const handleCurrentChange = (val) => {
|
|
||||||
currentRow.value = val;
|
currentRow.value = val;
|
||||||
emit("chooseData", val);
|
emit("chooseData", val);
|
||||||
};
|
}else{
|
||||||
const singleElection = (val) => {
|
|
||||||
if (getConfiger.showSelectType === "radio") {
|
|
||||||
getConfiger.radioChoose = val[getConfiger.rowKey];
|
|
||||||
emit("chooseData", val);
|
emit("chooseData", val);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 懒加载数据的方法
|
// 懒加载数据的方法
|
||||||
const load = (date, treeNode, resolve) => {
|
const load = (date, treeNode, resolve) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -184,25 +163,14 @@ const load = (date, treeNode, resolve) => {
|
|||||||
function setDefaultChoose() {
|
function setDefaultChoose() {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
// 多选的默认选中
|
// 多选的默认选中
|
||||||
if (
|
if ( props.tableConfiger.defaultSelectKeys?.length > 0 && props.tableConfiger.showSelectType === "checkBox" ) {
|
||||||
props.tableConfiger.defaultSelectKeys?.length > 0 &&
|
|
||||||
props.tableConfiger.showSelectType === "checkBox"
|
|
||||||
) {
|
|
||||||
props.tableData.forEach((item) => {
|
props.tableData.forEach((item) => {
|
||||||
if (
|
if ( props.tableConfiger.defaultSelectKeys.findIndex( (v) => v === item[props.tableConfiger.rowKey] ) > -1) {
|
||||||
props.tableConfiger.defaultSelectKeys.findIndex(
|
|
||||||
(v) => v === item[props.tableConfiger.rowKey]
|
|
||||||
) > -1
|
|
||||||
) {
|
|
||||||
multipleTableRef.value.toggleRowSelection(item, true);
|
multipleTableRef.value.toggleRowSelection(item, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// 单选的默认选中
|
// 单选的默认选中
|
||||||
} else if (
|
} else if ( props.tableConfiger.defaultSelectKeys && props.tableConfiger.defaultSelectKeys?.length > 0 && props.tableConfiger.showSelectType === "radio" ) {
|
||||||
props.tableConfiger.defaultSelectKeys &&
|
|
||||||
props.tableConfiger.defaultSelectKeys?.length > 0 &&
|
|
||||||
props.tableConfiger.showSelectType === "radio"
|
|
||||||
) {
|
|
||||||
getConfiger.radioChoose = props.tableConfiger.defaultSelectKeys[0];
|
getConfiger.radioChoose = props.tableConfiger.defaultSelectKeys[0];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -212,3 +180,12 @@ function setDefaultChoose() {
|
|||||||
<style lang = "scss">
|
<style lang = "scss">
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
<style>
|
||||||
|
.tabBoxRadio .el-checkbox__inner {
|
||||||
|
border-radius: 50% !important;
|
||||||
|
}
|
||||||
|
.tabBoxRadio .el-table__header-wrapper .el-checkbox {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
@ -63,10 +63,18 @@
|
|||||||
value-format="YYYY-MM-DD"
|
value-format="YYYY-MM-DD"
|
||||||
>
|
>
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
|
<el-date-picker
|
||||||
|
v-else-if="item.showType === 'datetime'"
|
||||||
|
v-model="searchObj[item.prop]"
|
||||||
|
type="datetime"
|
||||||
|
:placeholder="item.placeholder"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
>
|
||||||
|
</el-date-picker>
|
||||||
|
|
||||||
<!-- checkbox -->
|
<!-- checkbox -->
|
||||||
<template v-else-if="item.showType === 'department'">
|
<template v-else-if="item.showType === 'department'">
|
||||||
<MOSTY.Department clearable v-model="item.ssbmdm" />
|
<MOSTY.Department clearable v-model="searchObj[item.prop]" />
|
||||||
</template>
|
</template>
|
||||||
<!-- checkbox -->
|
<!-- checkbox -->
|
||||||
<template v-else-if="item.showType === 'checkbox'">
|
<template v-else-if="item.showType === 'checkbox'">
|
||||||
@ -117,7 +125,6 @@
|
|||||||
<!-- 级联选择 -->
|
<!-- 级联选择 -->
|
||||||
<el-cascader
|
<el-cascader
|
||||||
v-else-if="item.showType === 'cascader'"
|
v-else-if="item.showType === 'cascader'"
|
||||||
@change="changeca"
|
|
||||||
v-model="searchObj[item.prop]"
|
v-model="searchObj[item.prop]"
|
||||||
:props="item.props"
|
:props="item.props"
|
||||||
:show-all-levels="item.showAllLevels"
|
:show-all-levels="item.showAllLevels"
|
||||||
@ -143,11 +150,8 @@
|
|||||||
import {
|
import {
|
||||||
ref,
|
ref,
|
||||||
reactive,
|
reactive,
|
||||||
watch,
|
|
||||||
watchEffect,
|
watchEffect,
|
||||||
nextTick,
|
|
||||||
getCurrentInstance,
|
getCurrentInstance,
|
||||||
toRefs
|
|
||||||
} from "vue";
|
} from "vue";
|
||||||
import * as MOSTY from "@/components/MyComponents/index";
|
import * as MOSTY from "@/components/MyComponents/index";
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
@ -175,6 +179,12 @@ const props = defineProps({
|
|||||||
defaultVal: "",
|
defaultVal: "",
|
||||||
label: "输入"
|
label: "输入"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
showType: "department",
|
||||||
|
prop: "deptKey",
|
||||||
|
defaultVal: "",
|
||||||
|
label: "输入"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
showType: "daterange",
|
showType: "daterange",
|
||||||
prop: "daterangeKey",
|
prop: "daterangeKey",
|
||||||
@ -207,9 +217,6 @@ const props = defineProps({
|
|||||||
{
|
{
|
||||||
showType: "radio",
|
showType: "radio",
|
||||||
defaultVal: ""
|
defaultVal: ""
|
||||||
// prop: "cascaderKey",
|
|
||||||
// label: "级联选择",
|
|
||||||
// checkStrictly: false //点击任意选中
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
showType: "defaultTime",
|
showType: "defaultTime",
|
||||||
@ -229,16 +236,9 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
let loadingPage = ref(false);
|
let loadingPage = ref(false);
|
||||||
const isShowDate = ref(false);
|
|
||||||
const emit = defineEmits(["submit", "reset"]);
|
const emit = defineEmits(["submit", "reset"]);
|
||||||
let searchObj = reactive({});
|
let searchObj = reactive({});
|
||||||
const timeConfig = reactive({
|
|
||||||
//时间字典筛选和自定义日期组件相关数据
|
|
||||||
typeValue: "01", //时间字典类型默认
|
|
||||||
timeArry: [] //时间筛选自定义默认值
|
|
||||||
});
|
|
||||||
//全所或自定义选择按钮
|
|
||||||
const slectType = ref("qs");
|
|
||||||
// select 的一些默认配置
|
// select 的一些默认配置
|
||||||
const selectDefault = {
|
const selectDefault = {
|
||||||
clearable: true, // 是否可以清空
|
clearable: true, // 是否可以清空
|
||||||
@ -354,53 +354,6 @@ const dateShortcuts = [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
//自定义时间选择 item 配置项 value 选中的值
|
|
||||||
const screenSelect = (item, value) => {
|
|
||||||
if (value == "08") {
|
|
||||||
searchObj[item.prop] = value;
|
|
||||||
isShowDate.value = true;
|
|
||||||
} else {
|
|
||||||
timeConfig.typeValue = value;
|
|
||||||
searchObj[item.prop] = value;
|
|
||||||
submit();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//自定义时间确定时间
|
|
||||||
const chooseDateOk = (item) => {
|
|
||||||
timeConfig.typeValue = "08";
|
|
||||||
if (timeConfig.timeArry && timeConfig.timeArry.length) {
|
|
||||||
//选择了时间
|
|
||||||
searchObj[item.propStart] = timeConfig.timeArry[0];
|
|
||||||
searchObj[item.propEnd] = timeConfig.timeArry[1];
|
|
||||||
} else {
|
|
||||||
//清空了时间
|
|
||||||
searchObj[item.prop] = "01";
|
|
||||||
timeConfig.typeValue = "01";
|
|
||||||
}
|
|
||||||
isShowDate.value = false;
|
|
||||||
submit();
|
|
||||||
};
|
|
||||||
//全所-部门选择回调
|
|
||||||
const organizatioHland = (val) => {
|
|
||||||
let item = getArr.find((item) => item.showType == "qsOrZdy");
|
|
||||||
searchObj[item.propBm] = val?.data?.orgCode || "";
|
|
||||||
if (!val || val == "") {
|
|
||||||
//清空了部门选择后清空责任区ID
|
|
||||||
slectType.value = "qs";
|
|
||||||
delete searchObj[item.propZrq];
|
|
||||||
}
|
|
||||||
submit();
|
|
||||||
};
|
|
||||||
//全所-责任区回调
|
|
||||||
const zrqHland = (val) => {
|
|
||||||
let item = getArr.find((item) => item.showType == "qsOrZdy");
|
|
||||||
searchObj[item.propZrq] = val || ""; //责任区选择
|
|
||||||
submit();
|
|
||||||
};
|
|
||||||
//自定义时间取消事件
|
|
||||||
const popoverCancel = (item) => {
|
|
||||||
isShowDate.value = false;
|
|
||||||
};
|
|
||||||
// 设置不可选的日期
|
// 设置不可选的日期
|
||||||
const disabledDate = (time) => {
|
const disabledDate = (time) => {
|
||||||
return time.getTime() > Date.now();
|
return time.getTime() > Date.now();
|
||||||
@ -505,10 +458,6 @@ const cascaderLazyProps = reactive({
|
|||||||
resolve(options);
|
resolve(options);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// 级联框选择
|
|
||||||
function changeca(v) {
|
|
||||||
console.log("vvvv", v);
|
|
||||||
}
|
|
||||||
// 获取到传过来的参数
|
// 获取到传过来的参数
|
||||||
let getArr = reactive([]);
|
let getArr = reactive([]);
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
@ -521,11 +470,10 @@ const reset = () => {
|
|||||||
emit("submit", searchObj);
|
emit("submit", searchObj);
|
||||||
emit("reset", false);
|
emit("reset", false);
|
||||||
};
|
};
|
||||||
let dataOptions = reactive([]); //时间字典筛选
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
loadingPage.value = true;
|
loadingPage.value = true;
|
||||||
getArr = JSON.parse(JSON.stringify(props.searchArr));
|
let arr = JSON.parse(JSON.stringify(props.searchArr));
|
||||||
getArr = getArr.map((item) => {
|
getArr = arr.map((item) => {
|
||||||
switch (item.showType) {
|
switch (item.showType) {
|
||||||
case "select":
|
case "select":
|
||||||
item = { ...selectDefault, ...item };
|
item = { ...selectDefault, ...item };
|
||||||
@ -537,9 +485,7 @@ watchEffect(() => {
|
|||||||
break;
|
break;
|
||||||
case "daterange":
|
case "daterange":
|
||||||
item = { ...daterangeDefault, ...item };
|
item = { ...daterangeDefault, ...item };
|
||||||
if (item.defaultShortcuts) {
|
if (item.defaultShortcuts) item.shortcuts = shortcuts;
|
||||||
item.shortcuts = shortcuts;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case "date":
|
case "date":
|
||||||
item = { ...defaultDate, ...item };
|
item = { ...defaultDate, ...item };
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="showDialog" :destroy-on-close="true" :title="title+'人员'" @close="close" :close-on-click-modal="false">
|
<el-dialog v-model="modelValue" :destroy-on-close="true" :title="title+'人员'" @close="close" :close-on-click-modal="false">
|
||||||
<FormMessage v-model="listQuery" :formList="formData" labelWidth="120px" ref="elform" :rules="rules">
|
<FormMessage v-model="listQuery" :formList="formData" labelWidth="120px" ref="elform" :rules="rules">
|
||||||
<template #bqList>
|
<template #bqList>
|
||||||
<div class="marks pointer" @click="chooseMarksVisible = true">
|
<div class="marks pointer" @click="chooseMarksVisible = true">
|
||||||
@ -29,11 +29,14 @@ const props = defineProps({
|
|||||||
type:Object,
|
type:Object,
|
||||||
default:{}
|
default:{}
|
||||||
},
|
},
|
||||||
|
modelValue:{
|
||||||
|
type:Boolean,
|
||||||
|
default:false
|
||||||
|
}
|
||||||
})
|
})
|
||||||
const chooseMarksVisible = ref(false)
|
const chooseMarksVisible = ref(false)
|
||||||
const roleIds = ref([])
|
const roleIds = ref([])
|
||||||
const elform = ref()
|
const elform = ref()
|
||||||
const showDialog = ref(false)
|
|
||||||
const emit = defineEmits(['change'])
|
const emit = defineEmits(['change'])
|
||||||
const listQuery = ref({})
|
const listQuery = ref({})
|
||||||
const formData = ref([
|
const formData = ref([
|
||||||
@ -41,7 +44,7 @@ const formData = ref([
|
|||||||
{ label: "性别", prop: "xb", type: "select",options:props.dic.D_BZ_XB ,width:'48%'},
|
{ label: "性别", prop: "xb", type: "select",options:props.dic.D_BZ_XB ,width:'48%'},
|
||||||
{ label: "身份证号", prop: "sfzh", type: "input" ,width:'48%'},
|
{ label: "身份证号", prop: "sfzh", type: "input" ,width:'48%'},
|
||||||
{ label: "户籍地", prop: "hjdz", type: "input",width:'48%' },
|
{ label: "户籍地", prop: "hjdz", type: "input",width:'48%' },
|
||||||
{ label: "户籍地派出所", prop: "hjdpcsdm", type: "department" ,width:'48%'},
|
{ label: "户籍地派出所", prop: "hjdpcsdm",depMc:'hjdpcs', type: "department" ,width:'48%'},
|
||||||
{ label: "标签", prop: "bqList", type: "slot",width:'100%' },
|
{ label: "标签", prop: "bqList", type: "slot",width:'100%' },
|
||||||
{ label: "是否挑头人", prop: "sfttr", type: "select",options:props.dic.D_BZ_SF ,width:'48%'},
|
{ label: "是否挑头人", prop: "sfttr", type: "select",options:props.dic.D_BZ_SF ,width:'48%'},
|
||||||
{ label: "是否响应人", prop: "sfxyr", type: "select" ,options:props.dic.D_BZ_SF,width:'48%' },
|
{ label: "是否响应人", prop: "sfxyr", type: "select" ,options:props.dic.D_BZ_SF,width:'48%' },
|
||||||
@ -60,7 +63,6 @@ const order = ref(null)
|
|||||||
const init = (type,row,index) =>{
|
const init = (type,row,index) =>{
|
||||||
title.value = type == 'add' ? '新增' :'编辑';
|
title.value = type == 'add' ? '新增' :'编辑';
|
||||||
order.value = index;
|
order.value = index;
|
||||||
showDialog.value = true;
|
|
||||||
if(row) listQuery.value = {...row};
|
if(row) listQuery.value = {...row};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,13 +84,13 @@ const submitForm = () =>{
|
|||||||
elform.value.submit((val)=>{
|
elform.value.submit((val)=>{
|
||||||
let obj = { data:val,type:title.value ,index:order.value}
|
let obj = { data:val,type:title.value ,index:order.value}
|
||||||
emit('change',obj)
|
emit('change',obj)
|
||||||
showDialog.value = false;
|
emit('update:modelValue',false)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const close = () =>{
|
const close = () =>{
|
||||||
elform.value.reset();
|
elform.value.reset();
|
||||||
showDialog.value = false;
|
emit('update:modelValue',false)
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({init})
|
defineExpose({init})
|
@ -1,24 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="exportBox">
|
<div class="exportBox">
|
||||||
<el-dialog
|
<el-dialog v-model="show" title="导入文件" width="400px" :show-close="true" :center="true" :before-close="handleClose">
|
||||||
v-model="show"
|
|
||||||
title="导入文件"
|
|
||||||
width="400px"
|
|
||||||
:show-close="true"
|
|
||||||
:center="true"
|
|
||||||
:before-close="handleClose"
|
|
||||||
>
|
|
||||||
<div class="uplodBox">
|
<div class="uplodBox">
|
||||||
<el-upload
|
<el-upload action="#" drag :on-success="handleSuccess" :on-change="handleChange" :show-file-list="true" :file-list="fileDate" accept=".xls,.xlsx" :auto-upload="false">
|
||||||
action="#"
|
|
||||||
drag
|
|
||||||
:on-success="handleSuccess"
|
|
||||||
:on-change="handleChange"
|
|
||||||
:show-file-list="true"
|
|
||||||
:file-list="fileDate"
|
|
||||||
accept=".xls,.xlsx"
|
|
||||||
:auto-upload="false"
|
|
||||||
>
|
|
||||||
<el-icon class="el-icon-upload" size="100"><upload-filled /></el-icon>
|
<el-icon class="el-icon-upload" size="100"><upload-filled /></el-icon>
|
||||||
<div class="el-upload-text">
|
<div class="el-upload-text">
|
||||||
拖动或者点击上传或者<span @click.stop="downloadModel" class="model">下载模板</span>
|
拖动或者点击上传或者<span @click.stop="downloadModel" class="model">下载模板</span>
|
||||||
@ -27,9 +11,7 @@
|
|||||||
</el-upload>
|
</el-upload>
|
||||||
</div>
|
</div>
|
||||||
<div class="check">
|
<div class="check">
|
||||||
<el-checkbox true-label="true" false-label="false" v-model="isSelect"
|
<el-checkbox true-label="true" false-label="false" v-model="isSelect">是否替换已存在的数据</el-checkbox>
|
||||||
>是否替换已存在的数据</el-checkbox
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="foot">
|
<div class="foot">
|
||||||
<el-button @click="handleClose">取消</el-button>
|
<el-button @click="handleClose">取消</el-button>
|
||||||
@ -42,7 +24,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { qcckPost, qcckGet } from "@/api/qcckApi.js";
|
|
||||||
import { useStore } from "vuex";
|
import { useStore } from "vuex";
|
||||||
import { ref, defineProps, defineEmits, watch } from "vue";
|
import { ref, defineProps, defineEmits, watch } from "vue";
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
114
src/components/ypModel/index.vue
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="modelValue" center width="1000px" :destroy-on-close="true" title="报告模板" @close="close" :close-on-click-modal="false">
|
||||||
|
<div class="cntBox">
|
||||||
|
<!-- 工具栏 -->
|
||||||
|
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
|
||||||
|
<!-- 编辑器 -->
|
||||||
|
<Editor :style="`height: ${props.heightNumber}px; overflow-y: hidden`" v-model="textContent" :defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" @onChange="handChange" />
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<el-button type="primary">暂存</el-button>
|
||||||
|
<el-button type="primary">下载</el-button>
|
||||||
|
<el-button type="primary" @click="close">取消</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { compressImage } from "@/utils/tools.js";
|
||||||
|
import "@wangeditor/editor/dist/css/style.css";
|
||||||
|
import { qcckPost } from "@/api/qcckApi.js";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
|
||||||
|
import { ref, shallowRef, onBeforeUnmount, defineEmits, defineProps, watch } from "vue";
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue:{
|
||||||
|
type:Boolean,
|
||||||
|
default:false
|
||||||
|
},
|
||||||
|
// 编辑器内容
|
||||||
|
textContent: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: "请输入内容。。。。"
|
||||||
|
},
|
||||||
|
heightNumber: {
|
||||||
|
type: Number,
|
||||||
|
default: 448
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const editorRef = shallowRef();
|
||||||
|
const mode = "default";
|
||||||
|
//工具配置
|
||||||
|
const toolbarConfig = {
|
||||||
|
excludeKeys: ["blockquote", "codeBlock"] //清除不必要的工具,引用和代码块
|
||||||
|
};
|
||||||
|
const emits = defineEmits(["update:textContent", "changeFn"]);
|
||||||
|
//编辑器配置
|
||||||
|
const editorConfig = {
|
||||||
|
withCredentials: true, //允许跨域
|
||||||
|
placeholder: props.placeholder, //提示语
|
||||||
|
MENU_CONF: {
|
||||||
|
uploadImage: {
|
||||||
|
// 自定义上传图片
|
||||||
|
async customUpload(file, insertFn) {
|
||||||
|
let fileBlob = await compressImage(file);
|
||||||
|
let fileData = new File([fileBlob], fileBlob.name, { type: fileBlob.type });
|
||||||
|
if (fileData.size > 2 * 1024 * 1024) {
|
||||||
|
ElMessage({ message: "图片超过2MB", type: "success" });
|
||||||
|
} else {
|
||||||
|
await uploadFn(fileData, insertFn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
uploadVideo: {
|
||||||
|
// 自定义上传视频
|
||||||
|
async customUpload(file, insertFn) {
|
||||||
|
await uploadFn(file, insertFn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploadFn = (file, insertFn) => {
|
||||||
|
let param = new FormData();
|
||||||
|
param.append("file", file);
|
||||||
|
qcckPost(param, "/mosty-base/minio/image/upload").then((res) => {
|
||||||
|
insertFn(res);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//编辑器创建成功
|
||||||
|
const handleCreated = (editor) => {
|
||||||
|
editorRef.value = editor;
|
||||||
|
};
|
||||||
|
//内容发生变化
|
||||||
|
const handChange = (editor) => {
|
||||||
|
console.log(editor.getHtml(),'====editor.getHtml()');
|
||||||
|
// 判断是否是一个空段落,是空就传空文本
|
||||||
|
if (editor.isEmpty()) {
|
||||||
|
emits("changeFn", editor.getText());
|
||||||
|
} else {
|
||||||
|
emits("changeFn", editor.getHtml());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
const editor = editorRef.value;
|
||||||
|
if (editor) editor.destroy();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.cntBox{
|
||||||
|
height: 60vh;
|
||||||
|
padding: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
border: 1px dashed #e9e9e9;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
@ -56,7 +56,9 @@ onMounted(() => {
|
|||||||
active.value = "LZ";
|
active.value = "LZ";
|
||||||
});
|
});
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
store.dispatch("user/logout");
|
window.opener = null;
|
||||||
|
window.open('', '_self');
|
||||||
|
window.close();
|
||||||
store.commit("app/clearTag", null, { immediate: true });
|
store.commit("app/clearTag", null, { immediate: true });
|
||||||
store.commit("permission/deleteRouter", { immediate: true });
|
store.commit("permission/deleteRouter", { immediate: true });
|
||||||
store.commit("user/deleteKeepLiiveRoute", "home");
|
store.commit("user/deleteKeepLiiveRoute", "home");
|
||||||
|
@ -28,13 +28,12 @@ const updatePwd = () => {
|
|||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
store.dispatch("user/logout");
|
window.opener = null;
|
||||||
store.commit("app/clearTag", null, {
|
window.open('', '_self');
|
||||||
immediate: true
|
window.close();
|
||||||
});
|
store.commit("app/clearTag", null, { immediate: true });
|
||||||
store.commit("permission/deleteRouter", {
|
store.commit("permission/deleteRouter", { immediate: true });
|
||||||
immediate: true
|
store.commit("user/deleteKeepLiiveRoute", "home");
|
||||||
});
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -191,14 +191,7 @@ export const publicRoutes = [
|
|||||||
title: "标签组合管理",
|
title: "标签组合管理",
|
||||||
icon: "article"
|
icon: "article"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "/IntelligentControl",
|
|
||||||
name: "IntelligentControl",
|
|
||||||
meta: { title: "智能布控", icon: "article" },
|
|
||||||
children: [
|
|
||||||
{
|
{
|
||||||
path: "/warningControl",
|
path: "/warningControl",
|
||||||
name: "warningControl",
|
name: "warningControl",
|
||||||
@ -208,6 +201,25 @@ export const publicRoutes = [
|
|||||||
icon: "article"
|
icon: "article"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/WarningModel",
|
||||||
|
name: "WarningModel",
|
||||||
|
component: () =>
|
||||||
|
import(
|
||||||
|
"@/views/backOfficeSystem/ExcavationResearch/WarningModel/index"
|
||||||
|
),
|
||||||
|
meta: {
|
||||||
|
title: "重点人员预警模型",
|
||||||
|
icon: "article"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/IntelligentControl",
|
||||||
|
name: "IntelligentControl",
|
||||||
|
meta: { title: "智能布控", icon: "article" },
|
||||||
|
children: [
|
||||||
{
|
{
|
||||||
path: "/DeploymentArea",
|
path: "/DeploymentArea",
|
||||||
name: "DeploymentArea",
|
name: "DeploymentArea",
|
||||||
@ -256,7 +268,7 @@ export const publicRoutes = [
|
|||||||
name: "DatAcquisition",
|
name: "DatAcquisition",
|
||||||
component: () => import("@/views/backOfficeSystem/ResearchJudgment/DatAcquisition/index"),
|
component: () => import("@/views/backOfficeSystem/ResearchJudgment/DatAcquisition/index"),
|
||||||
meta: {
|
meta: {
|
||||||
title: "情报数据采集",
|
title: "线索数据采集",
|
||||||
icon: "article"
|
icon: "article"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -274,7 +286,7 @@ export const publicRoutes = [
|
|||||||
name: "IntelligenceManagement",
|
name: "IntelligenceManagement",
|
||||||
component: () => import("@/views/backOfficeSystem/ResearchJudgment/IntelligenceManagement/index"),
|
component: () => import("@/views/backOfficeSystem/ResearchJudgment/IntelligenceManagement/index"),
|
||||||
meta: {
|
meta: {
|
||||||
title: "情报管理",
|
title: "线索管理",
|
||||||
icon: "article"
|
icon: "article"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -328,7 +340,7 @@ export const publicRoutes = [
|
|||||||
"@/views/backOfficeSystem/HumanIntelligence/CollectCrculate/index"
|
"@/views/backOfficeSystem/HumanIntelligence/CollectCrculate/index"
|
||||||
),
|
),
|
||||||
meta: {
|
meta: {
|
||||||
title: "人力情报信息采集流转",
|
title: "人力情报管理",
|
||||||
icon: "article"
|
icon: "article"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -378,6 +390,15 @@ export const publicRoutes = [
|
|||||||
icon: "article"
|
icon: "article"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// path: "/MakeAcomment",
|
||||||
|
// name: "MakeAcomment",
|
||||||
|
// component: () => import("@/views/backOfficeSystem/MakeAcomment/index"),
|
||||||
|
// meta: {
|
||||||
|
// title: "情报评一评",
|
||||||
|
// icon: "article"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -421,19 +442,6 @@ export const publicRoutes = [
|
|||||||
icon: "article"
|
icon: "article"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "/WarningModel",
|
|
||||||
name: "WarningModel",
|
|
||||||
component: () =>
|
|
||||||
import(
|
|
||||||
"@/views/backOfficeSystem/ExcavationResearch/WarningModel/index"
|
|
||||||
),
|
|
||||||
meta: {
|
|
||||||
title: "重点人员预警模型",
|
|
||||||
icon: "article"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -450,7 +458,16 @@ export const publicRoutes = [
|
|||||||
name: "ResearchHome",
|
name: "ResearchHome",
|
||||||
component: () => import("@/views/backOfficeSystem/JudgmentHome/ResearchHome/index"),
|
component: () => import("@/views/backOfficeSystem/JudgmentHome/ResearchHome/index"),
|
||||||
meta: {
|
meta: {
|
||||||
title: "研判首页",
|
title: "专题研判",
|
||||||
|
icon: "article"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/tsypHome",
|
||||||
|
name: "tsypHome",
|
||||||
|
component: () => import("@/views/backOfficeSystem/JudgmentHome/tsypHome/index"),
|
||||||
|
meta: {
|
||||||
|
title: "态势研判",
|
||||||
icon: "article"
|
icon: "article"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -510,7 +527,15 @@ export const publicRoutes = [
|
|||||||
icon: "article"
|
icon: "article"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/mpvCar",
|
||||||
|
name: "mpvCar",
|
||||||
|
component: () => import("@/views/backOfficeSystem/DeploymentDisposal/mpvCar/index"),
|
||||||
|
meta: {
|
||||||
|
title: "重点车辆管理",
|
||||||
|
icon: "article"
|
||||||
|
}
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -521,15 +546,27 @@ export const publicRoutes = [
|
|||||||
icon: "article"
|
icon: "article"
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
// {
|
||||||
|
// path: "/surveillanceControl",
|
||||||
|
// name: "surveillanceControl",
|
||||||
|
// component: () =>
|
||||||
|
// import(
|
||||||
|
// "@/views/backOfficeSystem/BasicManagement/surveillanceControl/index"
|
||||||
|
// ),
|
||||||
|
// meta: {
|
||||||
|
// title: "布控监视",
|
||||||
|
// icon: "article"
|
||||||
|
// }
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
path: "/surveillanceControl",
|
path: "/experienceShare",
|
||||||
name: "surveillanceControl",
|
name: "experienceShare",
|
||||||
component: () =>
|
component: () =>
|
||||||
import(
|
import(
|
||||||
"@/views/backOfficeSystem/BasicManagement/surveillanceControl/index"
|
"@/views/backOfficeSystem/BasicManagement/experienceShare/index"
|
||||||
),
|
),
|
||||||
meta: {
|
meta: {
|
||||||
title: "布控监视",
|
title: "经验分享",
|
||||||
icon: "article"
|
icon: "article"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ export default {
|
|||||||
removeAllItem();
|
removeAllItem();
|
||||||
// 待补充 清理权限相关的配置
|
// 待补充 清理权限相关的配置
|
||||||
if (isOatuh) {
|
if (isOatuh) {
|
||||||
window.location.href = `http://80.149.27.78:8001/login`;
|
window.location.href = `http://155.240.22.102:40992`;
|
||||||
} else {
|
} else {
|
||||||
router.push("/login");
|
router.push("/login");
|
||||||
}
|
}
|
||||||
|
52
src/utils/ocrUtils.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// utils文件夹下创建 ocrUtils.js
|
||||||
|
export function drawBox(points, imgElement, canvasOutput) {
|
||||||
|
canvasOutput.width = imgElement.width
|
||||||
|
canvasOutput.height = imgElement.height
|
||||||
|
const ratio = imgElement.naturalHeight / imgElement.height
|
||||||
|
|
||||||
|
const ctx = canvasOutput.getContext('2d')
|
||||||
|
ctx.drawImage(imgElement, 0, 0, canvasOutput.width, canvasOutput.height)
|
||||||
|
points.forEach((point) => {
|
||||||
|
// 开始一个新的绘制路径
|
||||||
|
ctx.beginPath()
|
||||||
|
// 设置线条颜色为红色
|
||||||
|
ctx.strokeStyle = 'red'
|
||||||
|
// 设置路径起点坐标
|
||||||
|
ctx.moveTo(point[0][0] / ratio, point[0][1] / ratio)
|
||||||
|
ctx.lineTo(point[1][0] / ratio, point[1][1] / ratio)
|
||||||
|
ctx.lineTo(point[2][0] / ratio, point[2][1] / ratio)
|
||||||
|
ctx.lineTo(point[3][0] / ratio, point[3][1] / ratio)
|
||||||
|
ctx.closePath()
|
||||||
|
ctx.stroke()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function drawText(text, points, imgElement, canvasOutput) {
|
||||||
|
canvasOutput.width = imgElement.width
|
||||||
|
canvasOutput.height = imgElement.height
|
||||||
|
const ratio = imgElement.naturalHeight / imgElement.height
|
||||||
|
|
||||||
|
const ctx = canvasOutput.getContext('2d')
|
||||||
|
points.forEach((point, index) => {
|
||||||
|
// 开始一个新的绘制路径
|
||||||
|
ctx.beginPath()
|
||||||
|
// 设置线条颜色为红色
|
||||||
|
ctx.strokeStyle = 'red'
|
||||||
|
// 设置路径起点坐标
|
||||||
|
ctx.moveTo(point[0][0] / ratio, point[0][1] / ratio)
|
||||||
|
ctx.lineTo(point[1][0] / ratio, point[1][1] / ratio)
|
||||||
|
ctx.lineTo(point[2][0] / ratio, point[2][1] / ratio)
|
||||||
|
ctx.lineTo(point[3][0] / ratio, point[3][1] / ratio)
|
||||||
|
ctx.closePath()
|
||||||
|
ctx.stroke()
|
||||||
|
|
||||||
|
ctx.font = '30px 黑体'
|
||||||
|
ctx.fillText(
|
||||||
|
text[index],
|
||||||
|
point[3][0] / ratio,
|
||||||
|
point[3][1] / ratio,
|
||||||
|
point[1][0] / ratio - point[0][0] / ratio
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -73,17 +73,24 @@ service.interceptors.response.use(
|
|||||||
|
|
||||||
// 通用下载方法
|
// 通用下载方法
|
||||||
export function download(url, params, filename, config) {
|
export function download(url, params, filename, config) {
|
||||||
let token = localStorage.getItem('token')
|
return service.post(url, params, {
|
||||||
return axios.post(url, params, {"Content-type": "multipart/form-data",headers:{"Authorization": `${token}`}}).then( async (data) => {
|
transformRequest: [(params) => { return tansParams(params) }],
|
||||||
const isBlob = blobValidate(data.data);
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||||
console.log(isBlob,'====data');
|
responseType: 'blob',
|
||||||
|
...config
|
||||||
|
}).then(async (data) => {
|
||||||
|
const isBlob = blobValidate(data);
|
||||||
if (isBlob) {
|
if (isBlob) {
|
||||||
const blob = new Blob([data.data])
|
const blob = new Blob([data])
|
||||||
saveAs(blob, filename)
|
saveAs(blob, filename)
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error('网络异常');
|
const resText = await data.text();
|
||||||
|
const rspObj = JSON.parse(resText);
|
||||||
|
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
|
||||||
|
ElMessage.error(errMsg);
|
||||||
}
|
}
|
||||||
// downloadLoadingInstance.close();
|
}).catch((r) => {
|
||||||
|
ElMessage.error('下载文件出现错误,请联系管理员!')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import ImageCompressor from "image-compressor.js";
|
||||||
// 随机颜色 - 把16进制的颜色换成rgba格式
|
// 随机颜色 - 把16进制的颜色换成rgba格式
|
||||||
export function choseRbgb(color,opcity) {
|
export function choseRbgb(color,opcity) {
|
||||||
if(color){
|
if(color){
|
||||||
@ -13,6 +13,36 @@ export function choseRbgb(color,opcity) {
|
|||||||
return `rgba(${r},${g},${b},${a})`
|
return `rgba(${r},${g},${b},${a})`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 随机十六进制颜色
|
||||||
|
export function randomHexColor() { // 随机生成十六进制颜色
|
||||||
|
var hex = Math.floor(Math.random() * 16777216).toString(16);
|
||||||
|
while (hex.length < 6) {
|
||||||
|
hex = '0' + hex;
|
||||||
|
}
|
||||||
|
return '#' + hex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 压缩图片
|
||||||
|
* @param {*} file
|
||||||
|
* @param {*} quality 压缩比
|
||||||
|
*/
|
||||||
|
export function compressImage(file, quality = 0.6) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
new ImageCompressor(file, {
|
||||||
|
quality, //压缩质量
|
||||||
|
success(res) {
|
||||||
|
let fileData = new File([res], res.name, { type: res.type });
|
||||||
|
resolve(fileData);
|
||||||
|
},
|
||||||
|
error(e) {
|
||||||
|
reject("图片压缩失败,请稍后再试");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 今天周几
|
// 今天周几
|
||||||
export function weekValidate() {
|
export function weekValidate() {
|
||||||
let week = new Date().getDay()
|
let week = new Date().getDay()
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="foot">
|
<div class="foot">
|
||||||
<div class="footBtn"><span>发布指令</span></div>
|
<div class="footBtn" @click="gozl"><span>发布指令</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -29,6 +29,11 @@ import Head from "@/views/home/layout/head.vue";
|
|||||||
import ImportantPerson from "./model/importantPerson.vue";
|
import ImportantPerson from "./model/importantPerson.vue";
|
||||||
import Zdrqhd from "./model/zdrqhd.vue";
|
import Zdrqhd from "./model/zdrqhd.vue";
|
||||||
import Yjclqktj from "./model/yjclqktj.vue";
|
import Yjclqktj from "./model/yjclqktj.vue";
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
const router = useRouter()
|
||||||
|
const gozl = () =>{
|
||||||
|
router.push('/InstructionInformation')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@/assets/css/homeScreen.scss";
|
@import "@/assets/css/homeScreen.scss";
|
||||||
|
@ -15,6 +15,16 @@
|
|||||||
<template #qtFxdj="{row}">
|
<template #qtFxdj="{row}">
|
||||||
<DictTag :tag="false" :value="row.qtFxdj" :options="D_GS_ZDQT_FXDJ"/>
|
<DictTag :tag="false" :value="row.qtFxdj" :options="D_GS_ZDQT_FXDJ"/>
|
||||||
</template>
|
</template>
|
||||||
|
<template #bqList="{row}">
|
||||||
|
<span v-if="row.bqList">
|
||||||
|
<span v-for="(it, idx) in row.bqList" :key="idx">{{it.bqMc }}、</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #qbcjList="{row}">
|
||||||
|
<span v-if="row.qbcjList">
|
||||||
|
<span v-for="(it, idx) in row.qbcjList" :key="idx">{{it.xsMc }}、</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
<template #qtZt="{row}">
|
<template #qtZt="{row}">
|
||||||
<DictTag :tag="false" :value="row.qtZt" :options="D_GS_ZDQT_ZT"/>
|
<DictTag :tag="false" :value="row.qtZt" :options="D_GS_ZDQT_ZT"/>
|
||||||
</template>
|
</template>
|
||||||
@ -34,10 +44,7 @@ const keywords = ref(''); // 搜索关键字
|
|||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const { D_GS_ZDQT_ZT,D_BZ_RYBQ,D_GS_ZDQT_FXDJ } = proxy.$dict('D_GS_ZDQT_ZT','D_BZ_RYBQ','D_GS_ZDQT_FXDJ') //获取字典数据
|
const { D_GS_ZDQT_ZT,D_BZ_RYBQ,D_GS_ZDQT_FXDJ } = proxy.$dict('D_GS_ZDQT_ZT','D_BZ_RYBQ','D_GS_ZDQT_FXDJ') //获取字典数据
|
||||||
const pageData = reactive({
|
const pageData = reactive({
|
||||||
tableData: [
|
tableData: [],
|
||||||
{ ryXm: "王五", rySfzh: "330102199505057890", bq: "吸毒人员" },
|
|
||||||
{ ryXm: "王五", rySfzh: "330102199505057890", bq: "吸毒人员" },
|
|
||||||
],
|
|
||||||
keyCount: 0,
|
keyCount: 0,
|
||||||
tableConfiger: {
|
tableConfiger: {
|
||||||
loading: false,
|
loading: false,
|
||||||
@ -54,8 +61,8 @@ const pageData = reactive({
|
|||||||
tableColumn: [
|
tableColumn: [
|
||||||
{ label: "姓名", prop: "ryXm", showOverflowTooltip: true },
|
{ label: "姓名", prop: "ryXm", showOverflowTooltip: true },
|
||||||
{ label: "身份证号码", prop: "rySfzh",showOverflowTooltip: true },
|
{ label: "身份证号码", prop: "rySfzh",showOverflowTooltip: true },
|
||||||
{ label: "标签", prop: "bq",showOverflowTooltip: true },
|
{ label: "标签", prop: "bqList",showOverflowTooltip: true,showSolt:true },
|
||||||
{ label: "所属线索", prop: "xsmc",showOverflowTooltip: true },
|
{ label: "所属线索", prop: "qbcjList",showOverflowTooltip: true,showSolt:true },
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -0,0 +1,109 @@
|
|||||||
|
<template>
|
||||||
|
<div class="dialog" v-if="dialogForm">
|
||||||
|
<div class="head_box">
|
||||||
|
<span class="title">经验分享{{ title }} </span>
|
||||||
|
<div>
|
||||||
|
<el-button type="primary" size="small" :loading="loading" @click="submit">保存</el-button>
|
||||||
|
<el-button size="small" @click="close">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form_cnt">
|
||||||
|
<FormMessage :formList="formData" v-model="listQuery" ref="elform" :rules="rules">
|
||||||
|
</FormMessage>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||||
|
import { qcckGet, qcckPost, qcckPut } from "@/api/qcckApi.js";
|
||||||
|
import Xslist from '@/components/ChooseList/ChooseXs/index.vue'
|
||||||
|
import { ref, defineExpose, reactive, defineEmits, getCurrentInstance } from "vue";
|
||||||
|
const emit = defineEmits(["updateDate"]);
|
||||||
|
const props = defineProps({
|
||||||
|
dic: Object
|
||||||
|
});
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const dialogForm = ref(false); //弹窗
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
jymc: [
|
||||||
|
{ required: true, message: "请输入经验名称", trigger: "blur" }
|
||||||
|
],
|
||||||
|
fbnr: [
|
||||||
|
{ required: true, message: "请输入经验内容", trigger: "blur" }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
const formData = ref([
|
||||||
|
|
||||||
|
]);
|
||||||
|
const listQuery = ref({}); //表单
|
||||||
|
const loading = ref(false);
|
||||||
|
const elform = ref();
|
||||||
|
const title = ref("");
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
const init = (type, row) => {
|
||||||
|
dialogForm.value = true;
|
||||||
|
title.value = type == "add" ? "新增" : "编辑";
|
||||||
|
// 根据id查询详情
|
||||||
|
if (row) {
|
||||||
|
console.log(row,"xxxxx");
|
||||||
|
formData.value = [
|
||||||
|
{ label: "经验名称", prop: "jymc", type: "input", width: "100%" },
|
||||||
|
{ label: "发布时间", prop: "fbsj", type: "input", width: "50%",disabled:true },
|
||||||
|
{ label: "发布人", prop: "fbr", type: "input", width: "50%",disabled:true },
|
||||||
|
{ label: "经验内容", prop: "fbnr", type: "textarea", width: "100%" },
|
||||||
|
]
|
||||||
|
listQuery.value = row;
|
||||||
|
} else {
|
||||||
|
formData.value = [
|
||||||
|
{ label: "经验名称", prop: "jymc", type: "input", width: "100%" },
|
||||||
|
{ label: "任务内容", prop: "fbnr", type: "textarea", width: "100%" },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交
|
||||||
|
const submit = () => {
|
||||||
|
elform.value.submit((data) => {
|
||||||
|
let url = title.value == "新增" ? "/mosty-gsxt/gsxt/jyfx/add" : "/mosty-gsxt/gsxt/jyfx/edit";
|
||||||
|
let params = { ...data };
|
||||||
|
qcckPost(params, url).then(() => {
|
||||||
|
loading.value = false;
|
||||||
|
proxy.$message({ type: "success", message: title.value + "成功" });
|
||||||
|
emit("updateDate");
|
||||||
|
close();
|
||||||
|
}).catch(()=>{
|
||||||
|
loading.value = false;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 关闭
|
||||||
|
const close = () => {
|
||||||
|
listQuery.value = {};
|
||||||
|
loading.value = false;
|
||||||
|
dialogForm.value = false;
|
||||||
|
listQuery.value={}
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({ init });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "~@/assets/css/layout.scss";
|
||||||
|
@import "~@/assets/css/element-plus.scss";
|
||||||
|
|
||||||
|
.boxlist {
|
||||||
|
width: 99%;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
::v-deep .el-textarea__inner {
|
||||||
|
min-height: 550px !important;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,195 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="titleBox">
|
||||||
|
<PageTitle title="经验分享">
|
||||||
|
<el-button type="primary" @click="addEdit('add', '')">
|
||||||
|
<el-icon style="vertical-align: middle"><CirclePlus /></el-icon>
|
||||||
|
<span style="vertical-align: middle">新增</span>
|
||||||
|
</el-button>
|
||||||
|
</PageTitle>
|
||||||
|
</div>
|
||||||
|
<!-- 搜索 -->
|
||||||
|
<div ref="searchBox">
|
||||||
|
<Search
|
||||||
|
:searchArr="searchConfiger"
|
||||||
|
@submit="onSearch"
|
||||||
|
:key="pageData.keyCount"
|
||||||
|
></Search>
|
||||||
|
</div>
|
||||||
|
<!-- 表格 -->
|
||||||
|
<div class="tabBox">
|
||||||
|
<MyTable
|
||||||
|
:tableData="pageData.tableData"
|
||||||
|
:tableColumn="pageData.tableColumn"
|
||||||
|
:tableHeight="pageData.tableHeight"
|
||||||
|
:key="pageData.keyCount"
|
||||||
|
:tableConfiger="pageData.tableConfiger"
|
||||||
|
:controlsWidth="pageData.controlsWidth"
|
||||||
|
>
|
||||||
|
<!-- 操作 -->
|
||||||
|
<template #controls="{ row }">
|
||||||
|
<el-link type="primary" @click="addEdit('edit', row)">编辑</el-link>
|
||||||
|
<el-link type="danger" @click="delDictItem(row.id)">删除</el-link>
|
||||||
|
</template>
|
||||||
|
</MyTable>
|
||||||
|
<Pages
|
||||||
|
@changeNo="changeNo"
|
||||||
|
@changeSize="changeSize"
|
||||||
|
:tableHeight="pageData.tableHeight"
|
||||||
|
:pageConfiger="{
|
||||||
|
...pageData.pageConfiger,
|
||||||
|
total: pageData.total
|
||||||
|
}"
|
||||||
|
></Pages>
|
||||||
|
</div>
|
||||||
|
<!-- 编辑详情 -->
|
||||||
|
<EditAddForm
|
||||||
|
v-if="show"
|
||||||
|
ref="detailDiloag"
|
||||||
|
:dic="{ D_GS_BQ_LX, D_GS_BQ_DJ, D_GS_SSYJ, D_GS_BQ_LB }"
|
||||||
|
@updateDate="getList"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||||
|
import MyTable from "@/components/aboutTable/MyTable.vue";
|
||||||
|
import Pages from "@/components/aboutTable/Pages.vue";
|
||||||
|
import Search from "@/components/aboutTable/Search.vue";
|
||||||
|
import EditAddForm from "./components/editAddForm.vue";
|
||||||
|
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
|
||||||
|
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
|
const detailDiloag = ref();
|
||||||
|
const show = ref(false);
|
||||||
|
const searchBox = ref(); //搜索框
|
||||||
|
const searchConfiger = ref([
|
||||||
|
{
|
||||||
|
label: "发布人",
|
||||||
|
prop: "fbr",
|
||||||
|
placeholder: "请输入发布人",
|
||||||
|
showType: "input"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "经验标题",
|
||||||
|
prop: "jymc",
|
||||||
|
placeholder: "请输入经验标题",
|
||||||
|
showType: "input"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "发布时间",
|
||||||
|
prop: "startTime",
|
||||||
|
placeholder: "请选择发布时间",
|
||||||
|
showType: "daterange"
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const queryFrom = ref({});
|
||||||
|
const pageData = reactive({
|
||||||
|
tableData: [], //表格数据
|
||||||
|
keyCount: 0,
|
||||||
|
tableConfiger: {
|
||||||
|
rowHieght: 61,
|
||||||
|
showSelectType: "null",
|
||||||
|
loading: false
|
||||||
|
},
|
||||||
|
total: 0,
|
||||||
|
pageConfiger: {
|
||||||
|
pageSize: 20,
|
||||||
|
pageCurrent: 1
|
||||||
|
}, //分页
|
||||||
|
controlsWidth: 160, //操作栏宽度
|
||||||
|
tableColumn: [
|
||||||
|
{
|
||||||
|
label: "发布人",
|
||||||
|
prop: "fbr"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "经验名称",
|
||||||
|
prop: "jymc"
|
||||||
|
},{
|
||||||
|
label: "发布时间",
|
||||||
|
prop: "fbsj"
|
||||||
|
},{
|
||||||
|
label: "发布内容",
|
||||||
|
prop: "fbnr",
|
||||||
|
showOverflowTooltip:true
|
||||||
|
},
|
||||||
|
|
||||||
|
]
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
tabHeightFn();
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 搜索
|
||||||
|
const onSearch = (val) => {
|
||||||
|
queryFrom.value = {
|
||||||
|
...val,
|
||||||
|
startTime: val.startTime&&val.startTime.length > 0 ? val.startTime[0] : '',
|
||||||
|
endTime: val.startTime&& val.startTime.length > 0 ? val.startTime[1] : ''
|
||||||
|
};
|
||||||
|
pageData.pageConfiger.pageCurrent = 1;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeNo = (val) => {
|
||||||
|
pageData.pageConfiger.pageCurrent = val;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
const changeSize = (val) => {
|
||||||
|
pageData.pageConfiger.pageSize = val;
|
||||||
|
getList();
|
||||||
|
};
|
||||||
|
|
||||||
|
const getList = () => {
|
||||||
|
pageData.tableConfiger.loading = true;
|
||||||
|
qcckPost(queryFrom.value, "/mosty-gsxt/gsxt/jyfx/selectPage")
|
||||||
|
.then((res) => {
|
||||||
|
pageData.tableData = res.records;
|
||||||
|
pageData.total = res.total;
|
||||||
|
pageData.tableConfiger.loading = false;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
pageData.tableConfiger.loading = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
const delDictItem = (id) => {
|
||||||
|
proxy
|
||||||
|
.$confirm("确定要删除", "警告", { type: "warning" })
|
||||||
|
.then(() => {
|
||||||
|
qcckDelete({}, "/mosty-gsxt/tbGsxtBqzh/" + id).then(() => {
|
||||||
|
proxy.$message({ type: "success", message: "删除成功" });
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 新增
|
||||||
|
const addEdit = (type, row) => {
|
||||||
|
show.value = true;
|
||||||
|
nextTick(() => {
|
||||||
|
detailDiloag.value.init(type, row);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 表格高度计算
|
||||||
|
const tabHeightFn = () => {
|
||||||
|
pageData.tableHeight =
|
||||||
|
window.innerHeight - searchBox.value.offsetHeight - 250;
|
||||||
|
window.onresize = function () {
|
||||||
|
tabHeightFn();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.el-loading-mask {
|
||||||
|
background: rgba(0, 0, 0, 0.5) !important;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,219 @@
|
|||||||
|
<template>
|
||||||
|
<div class="dialog" v-if="dialogForm">
|
||||||
|
<div class="head_box">
|
||||||
|
<span class="title">{{ title }}重点车辆管理</span>
|
||||||
|
<div>
|
||||||
|
<el-button type="primary" size="small" v-if="!disabled" :loading="loading" @click="submit">保存</el-button>
|
||||||
|
<el-button size="small" @click="close">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form_cnt">
|
||||||
|
<FormMessage :disabled="disabled" v-model="listQuery" :formList="formData" labelWidth="100px" ref="elform"
|
||||||
|
:rules="rules"></FormMessage>
|
||||||
|
<!-- 选择审核人 -->
|
||||||
|
<!-- <div class="ww100 mt20 ml50 mr50">
|
||||||
|
<el-steps direction="vertical" :active="listQuery.wccz" space="500" finish-status="success">
|
||||||
|
<el-step title="发起申请">
|
||||||
|
<template #description>
|
||||||
|
<div class="flex align-center ww100 mt10 mb20">
|
||||||
|
<el-input v-model="listQuery.sqrXm" readonly class="ww20"></el-input>
|
||||||
|
<el-input v-model="listQuery.sqrSsbmmc" readonly class="ww20 ml10 mr10"></el-input>
|
||||||
|
<span class="f12" style="color: #333333">
|
||||||
|
备注发起人和部门根据登陆人自动填写</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-step>
|
||||||
|
<el-step title="审核确认">
|
||||||
|
<template #description>
|
||||||
|
<div class="flex align-center ww100 mt10 mb20 depBox">
|
||||||
|
<span class="mr4">审核部门 : </span>
|
||||||
|
<MOSTY.Department :isAll="true" @getDepValue="getShdep" v-model="listQuery.shSsbmdm" clearable :placeholder="listQuery.shSsbmmc ? listQuery.shSsbmmc : ''" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-step>
|
||||||
|
<el-step title="审批确认">
|
||||||
|
<template #description>
|
||||||
|
<div class="flex align-center ww100 mt10 mb20 depBox">
|
||||||
|
<span lass="mr4">审批部门 : </span>
|
||||||
|
<MOSTY.Department :isAll="true" @getDepValue="getSPdep" v-model="listQuery.spSsbmdm" clearable :placeholder="listQuery.spSsbmmc ? listQuery.spSsbmmc : ''" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-step>
|
||||||
|
</el-steps>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import * as rule from "@/utils/rules.js";
|
||||||
|
import * as MOSTY from "@/components/MyComponents/index";
|
||||||
|
import { getItem } from "@/utils/storage";
|
||||||
|
import MyTable from "@/components/aboutTable/MyTable.vue";
|
||||||
|
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||||
|
import { qcckGet, qcckPost, qcckPut } from "@/api/qcckApi.js";
|
||||||
|
import {
|
||||||
|
ref,
|
||||||
|
defineExpose,
|
||||||
|
reactive,
|
||||||
|
onMounted,
|
||||||
|
defineEmits,
|
||||||
|
getCurrentInstance,
|
||||||
|
watch
|
||||||
|
} from "vue";
|
||||||
|
const emit = defineEmits(["updateDate"]);
|
||||||
|
const props = defineProps({
|
||||||
|
dic: Object
|
||||||
|
});
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
const roleIds = ref([]);
|
||||||
|
const chooseMarksVisible = ref(false);
|
||||||
|
const dialogForm = ref(false); //弹窗
|
||||||
|
const pcsList = ref([]);
|
||||||
|
const rules = reactive({
|
||||||
|
ryXm: [{ required: true, message: "请输入姓名", trigger: "blur" }],
|
||||||
|
...rule.identityCardRule({ validator: true },'rySfzh'), //身份证校验
|
||||||
|
...rule.phoneRule({ validator: true }, "ryLxdh"), // 是否必填 是否进行校验,
|
||||||
|
ryXb: [{ required: true, message: "请选择性别", trigger: "change" }],
|
||||||
|
ryMz: [{ required: true, message: "请选择民族", trigger: "change" }],
|
||||||
|
ryCsrq: [{ required: true, message: "请选择出生日期", trigger: "change" }],
|
||||||
|
ryJg: [{ required: true, message: "请选择籍贯", trigger: "change" }],
|
||||||
|
zdrRyjb: [{ required: true, message: "请选择人员级别", trigger: "change" }],
|
||||||
|
zdrYjdj: [{ required: true, message: "请选择预警等级", trigger: "change" }]
|
||||||
|
});
|
||||||
|
const listQuery = ref({}); //表单
|
||||||
|
const formData = ref([]);
|
||||||
|
watch(() => props.dic,(val) => {
|
||||||
|
formData.value = [
|
||||||
|
{ label: "车牌号", prop: "hphm", type: "input" },
|
||||||
|
{ label: "车架号", prop: "clCjh", type: "input" },
|
||||||
|
{
|
||||||
|
label: "车辆颜色",
|
||||||
|
prop: "clYs",
|
||||||
|
type: "input",
|
||||||
|
},
|
||||||
|
{ label: "车辆所有人", prop: "clSyr", type: "input" },
|
||||||
|
{ label: "人员身份证", prop: "clSyrsfzh", type: "input" },
|
||||||
|
{ label: "责任单位", prop: "zrSsbmdm",depMc:'zrSsbmmc', type: "department" },
|
||||||
|
{ label: "管辖单位", prop: "gxSsbmdm",depMc:'gxSsbmmc', type: "department" },
|
||||||
|
{ label: "管控民警姓名", prop: "gkMjXm", type: "input" },
|
||||||
|
{ label: "管控民警警号", prop: "gkMjJh", type: "input" },
|
||||||
|
{ label: "管控原因", prop: "clLkyy", type: "textarea", width: "100%" },
|
||||||
|
{ label: "车辆照片", prop: "fjdz", type: "upload", width: "100%" },
|
||||||
|
];
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
const tableDate = reactive({
|
||||||
|
tableConfiger: {
|
||||||
|
rowHieght: 61,
|
||||||
|
showSelectType: "null",
|
||||||
|
loading: false
|
||||||
|
},
|
||||||
|
controlsWidth: 90, //操作栏宽度
|
||||||
|
keyCount: 0,
|
||||||
|
tableColumn: [
|
||||||
|
{ label: "标签名称", prop: "bqMc" },
|
||||||
|
{ label: "标签代码", prop: "bqDm" },
|
||||||
|
{ label: "标签种类", prop: "bqZl", showSolt: true },
|
||||||
|
{ label: "标签类型", prop: "bqLx", showSolt: true },
|
||||||
|
{ label: "标签类别", prop: "bqLb", showSolt: true }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
const loading = ref(false);
|
||||||
|
const elform = ref();
|
||||||
|
const title = ref("");
|
||||||
|
const showInfo = ref(false);
|
||||||
|
const disabled = ref(false);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
const init = (type, row) => {
|
||||||
|
dialogForm.value = true;
|
||||||
|
title.value = type == "add" ? "新增" : type == "detail" ? "详情" : "编辑";
|
||||||
|
disabled.value = type == "detail" ? true : false;
|
||||||
|
tableDate.tableConfiger.haveControls = type == "detail" ? false : true;
|
||||||
|
setTimeout(() => {
|
||||||
|
showInfo.value = true;
|
||||||
|
}, 5);
|
||||||
|
if (row) getDataById(row.id);
|
||||||
|
};
|
||||||
|
// 根据id查询详情
|
||||||
|
const getDataById = (id) => {
|
||||||
|
qcckGet({id}, "/mosty-gsxt/tbGsxtZdcl/selectByid").then((res) => {
|
||||||
|
listQuery.value = res;
|
||||||
|
listQuery.value.fjdz = listQuery.value.fjdz?.split(",");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交
|
||||||
|
const submit = () => {
|
||||||
|
elform.value.submit((data) => {
|
||||||
|
data.fjdz = data.fjdz?.join(",");
|
||||||
|
let url = title.value == "新增" ? "/mosty-gsxt/tbGsxtZdcl/add" : "/mosty-gsxt/tbGsxtZdcl/update";
|
||||||
|
let params = { ...data };
|
||||||
|
loading.value = true;
|
||||||
|
qcckPost(params, url).then(() => {
|
||||||
|
loading.value = false;
|
||||||
|
proxy.$message({ type: "success", message: title.value + "成功" });
|
||||||
|
emit("updateDate");
|
||||||
|
close();
|
||||||
|
}).catch(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 关闭
|
||||||
|
const close = () => {
|
||||||
|
listQuery.value = {};
|
||||||
|
dialogForm.value = false;
|
||||||
|
loading.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({ init });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "~@/assets/css/layout.scss";
|
||||||
|
@import "~@/assets/css/element-plus.scss";
|
||||||
|
|
||||||
|
::v-deep .el-tabs--card>.el-tabs__header .el-tabs__item.is-active {
|
||||||
|
color: #0072ff;
|
||||||
|
background: rgba(0, 114, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxlist {
|
||||||
|
width: calc(99% - 50px);
|
||||||
|
margin-top: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.depBox {
|
||||||
|
border: 1px solid #e9e9e9;
|
||||||
|
width: 305px;
|
||||||
|
padding: 0 0 0 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
::v-deep .el-input__inner {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-cascader .el-input.is-focus .el-input__inner {
|
||||||
|
border-color: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-input__inner:focus {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-input.is-disabled .el-input__inner {
|
||||||
|
border-color: transparent !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|