feat:ocr2.0开发

ocr_2.0
xiangcongshuai 6 months ago
parent a501d22021
commit 7076e54c4f

@ -10,6 +10,9 @@
"dependencies": {
"@riophae/vue-treeselect": "0.4.0",
"@vue/composition-api": "1.7.1",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^1.0.2",
"@wangeditor/plugin-mention": "^1.0.0",
"axios": "1.6.0",
"core-js": "3.30.1",
"countup.js": "^2.8.0",

@ -11,6 +11,15 @@ dependencies:
'@vue/composition-api':
specifier: 1.7.1
version: 1.7.1(vue@2.6.14)
'@wangeditor/editor':
specifier: ^5.1.23
version: 5.1.23
'@wangeditor/editor-for-vue':
specifier: ^1.0.2
version: 1.0.2(@wangeditor/editor@5.1.23)(vue@2.6.14)
'@wangeditor/plugin-mention':
specifier: ^1.0.0
version: 1.0.0(@wangeditor/editor@5.1.23)(snabbdom@3.6.2)
axios:
specifier: 1.6.0
version: 1.6.0
@ -1674,6 +1683,10 @@ packages:
resolution: {integrity: sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w==}
dev: true
/@transloadit/prettier-bytes@0.0.7:
resolution: {integrity: sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA==}
dev: false
/@trysound/sax@0.2.0:
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
engines: {node: '>=10.13.0'}
@ -1721,6 +1734,10 @@ packages:
/@types/estree@1.0.5:
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
/@types/event-emitter@0.3.5:
resolution: {integrity: sha512-zx2/Gg0Eg7gwEiOIIh5w9TrhKKTeQh7CPCOPNc0el4pLSwzebA8SmnHwZs2dWlLONvyulykSwGSQxQHLhjGLvQ==}
dev: false
/@types/express-serve-static-core@4.19.5:
resolution: {integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==}
dependencies:
@ -1863,6 +1880,47 @@ packages:
'@types/node': 20.14.10
dev: true
/@uppy/companion-client@2.2.2:
resolution: {integrity: sha512-5mTp2iq97/mYSisMaBtFRry6PTgZA6SIL7LePteOV5x0/DxKfrZW3DEiQERJmYpHzy7k8johpm2gHnEKto56Og==}
dependencies:
'@uppy/utils': 4.1.3
namespace-emitter: 2.0.1
dev: false
/@uppy/core@2.3.4:
resolution: {integrity: sha512-iWAqppC8FD8mMVqewavCz+TNaet6HPXitmGXpGGREGrakZ4FeuWytVdrelydzTdXx6vVKkOmI2FLztGg73sENQ==}
dependencies:
'@transloadit/prettier-bytes': 0.0.7
'@uppy/store-default': 2.1.1
'@uppy/utils': 4.1.3
lodash.throttle: 4.1.1
mime-match: 1.0.2
namespace-emitter: 2.0.1
nanoid: 3.3.7
preact: 10.24.3
dev: false
/@uppy/store-default@2.1.1:
resolution: {integrity: sha512-xnpTxvot2SeAwGwbvmJ899ASk5tYXhmZzD/aCFsXePh/v8rNvR2pKlcQUH7cF/y4baUGq3FHO/daKCok/mpKqQ==}
dev: false
/@uppy/utils@4.1.3:
resolution: {integrity: sha512-nTuMvwWYobnJcytDO3t+D6IkVq/Qs4Xv3vyoEZ+Iaf8gegZP+rEyoaFT2CK5XLRMienPyqRqNbIfRuFaOWSIFw==}
dependencies:
lodash.throttle: 4.1.1
dev: false
/@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4):
resolution: {integrity: sha512-YWOQ6myBVPs+mhNjfdWsQyMRWUlrDLMoaG7nvf/G6Y3GKZf8AyjFDjvvJ49XWQ+DaZOftGkHmF1uh/DBeGivJQ==}
peerDependencies:
'@uppy/core': ^2.3.3
dependencies:
'@uppy/companion-client': 2.2.2
'@uppy/core': 2.3.4
'@uppy/utils': 4.1.3
nanoid: 3.3.7
dev: false
/@vue/babel-helper-vue-jsx-merge-props@1.4.0:
resolution: {integrity: sha512-JkqXfCkUDp4PIlFdDQ0TdXoIejMtTHP67/pvxlgeY+u5k3LEdKuWZ3LK6xkxo52uDoABIVyRwqVkfLQJhk7VBA==}
dev: true
@ -2440,6 +2498,202 @@ packages:
resolution: {integrity: sha512-Iu8Tbg3f+emIIMmI2ycSI8QcEuAUgPTgHwesDU1eKMLE4YC/c/sFbGc70QgMq31ijRftV0R7vCm9co6rldCeOA==}
dev: true
/@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2):
resolution: {integrity: sha512-cY9CPkLJaqF05STqfpZKWG4LpxTMeGSIIF1fHvfm/mz+JXatCagjdkbxdikOuKYlxDdeqvOeBmsUBItufDLXZg==}
peerDependencies:
'@wangeditor/core': 1.x
dom7: ^3.0.0
lodash.throttle: ^4.1.1
nanoid: ^3.2.0
slate: ^0.72.0
snabbdom: ^3.1.0
dependencies:
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
dom7: 3.0.0
is-url: 1.2.4
lodash.throttle: 4.1.1
nanoid: 3.3.7
slate: 0.72.8
snabbdom: 3.6.2
dev: false
/@wangeditor/code-highlight@1.0.3(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2):
resolution: {integrity: sha512-iazHwO14XpCuIWJNTQTikqUhGKyqj+dUNWJ9288Oym9M2xMVHvnsOmDU2sgUDWVy+pOLojReMPgXCsvvNlOOhw==}
peerDependencies:
'@wangeditor/core': 1.x
dom7: ^3.0.0
slate: ^0.72.0
snabbdom: ^3.1.0
dependencies:
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
dom7: 3.0.0
prismjs: 1.29.0
slate: 0.72.8
snabbdom: 3.6.2
dev: false
/@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2):
resolution: {integrity: sha512-KevkB47+7GhVszyYF2pKGKtCSj/YzmClsD03C3zTt+9SR2XWT5T0e3yQqg8baZpcMvkjs1D8Dv4fk8ok/UaS2Q==}
peerDependencies:
'@uppy/core': ^2.1.1
'@uppy/xhr-upload': ^2.0.3
dom7: ^3.0.0
is-hotkey: ^0.2.0
lodash.camelcase: ^4.3.0
lodash.clonedeep: ^4.5.0
lodash.debounce: ^4.0.8
lodash.foreach: ^4.5.0
lodash.isequal: ^4.5.0
lodash.throttle: ^4.1.1
lodash.toarray: ^4.4.0
nanoid: ^3.2.0
slate: ^0.72.0
snabbdom: ^3.1.0
dependencies:
'@types/event-emitter': 0.3.5
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
dom7: 3.0.0
event-emitter: 0.3.5
html-void-elements: 2.0.1
i18next: 20.6.1
is-hotkey: 0.2.0
lodash.camelcase: 4.3.0
lodash.clonedeep: 4.5.0
lodash.debounce: 4.0.8
lodash.foreach: 4.5.0
lodash.isequal: 4.5.0
lodash.throttle: 4.1.1
lodash.toarray: 4.4.0
nanoid: 3.3.7
scroll-into-view-if-needed: 2.2.31
slate: 0.72.8
slate-history: 0.66.0(slate@0.72.8)
snabbdom: 3.6.2
dev: false
/@wangeditor/editor-for-vue@1.0.2(@wangeditor/editor@5.1.23)(vue@2.6.14):
resolution: {integrity: sha512-BOENvAXJVtVXlE2X50AAvjV82YlCUeu5cbeR0cvEQHQjYtiVnJtq7HSoj85r2kTgGouI5OrpJG9BBEjSjUSPyA==}
peerDependencies:
'@wangeditor/editor': '>=5.1.0'
vue: ^2.6.14
dependencies:
'@wangeditor/editor': 5.1.23
vue: 2.6.14
dev: false
/@wangeditor/editor@5.1.23:
resolution: {integrity: sha512-0RxfeVTuK1tktUaPROnCoFfaHVJpRAIE2zdS0mpP+vq1axVQpLjM8+fCvKzqYIkH0Pg+C+44hJpe3VVroSkEuQ==}
dependencies:
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
'@wangeditor/basic-modules': 1.1.7(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
'@wangeditor/code-highlight': 1.0.3(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2)
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
'@wangeditor/list-module': 1.0.5(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2)
'@wangeditor/table-module': 1.1.4(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
'@wangeditor/upload-image-module': 1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/basic-modules@1.1.7)(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.6.2)
'@wangeditor/video-module': 1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/core@1.1.19)(dom7@3.0.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
dom7: 3.0.0
is-hotkey: 0.2.0
lodash.camelcase: 4.3.0
lodash.clonedeep: 4.5.0
lodash.debounce: 4.0.8
lodash.foreach: 4.5.0
lodash.isequal: 4.5.0
lodash.throttle: 4.1.1
lodash.toarray: 4.4.0
nanoid: 3.3.7
slate: 0.72.8
snabbdom: 3.6.2
dev: false
/@wangeditor/list-module@1.0.5(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.2):
resolution: {integrity: sha512-uDuYTP6DVhcYf7mF1pTlmNn5jOb4QtcVhYwSSAkyg09zqxI1qBqsfUnveeDeDqIuptSJhkh81cyxi+MF8sEPOQ==}
peerDependencies:
'@wangeditor/core': 1.x
dom7: ^3.0.0
slate: ^0.72.0
snabbdom: ^3.1.0
dependencies:
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
dom7: 3.0.0
slate: 0.72.8
snabbdom: 3.6.2
dev: false
/@wangeditor/plugin-mention@1.0.0(@wangeditor/editor@5.1.23)(snabbdom@3.6.2):
resolution: {integrity: sha512-txQEoHxzil78WoTGXn0ENONZ2sdEL8GI5qBxETn6TMEXQkqiUXA4Kc8bV8D8nZDniC00oFb80kDmOIpT/KUBGw==}
peerDependencies:
'@wangeditor/editor': '>=5.0.0'
snabbdom: ^3.3.1
dependencies:
'@wangeditor/editor': 5.1.23
snabbdom: 3.6.2
dev: false
/@wangeditor/table-module@1.1.4(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2):
resolution: {integrity: sha512-5saanU9xuEocxaemGdNi9t8MCDSucnykEC6jtuiT72kt+/Hhh4nERYx1J20OPsTCCdVr7hIyQenFD1iSRkIQ6w==}
peerDependencies:
'@wangeditor/core': 1.x
dom7: ^3.0.0
lodash.isequal: ^4.5.0
lodash.throttle: ^4.1.1
nanoid: ^3.2.0
slate: ^0.72.0
snabbdom: ^3.1.0
dependencies:
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
dom7: 3.0.0
lodash.isequal: 4.5.0
lodash.throttle: 4.1.1
nanoid: 3.3.7
slate: 0.72.8
snabbdom: 3.6.2
dev: false
/@wangeditor/upload-image-module@1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/basic-modules@1.1.7)(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.6.2):
resolution: {integrity: sha512-z81lk/v71OwPDYeQDxj6cVr81aDP90aFuywb8nPD6eQeECtOymrqRODjpO6VGvCVxVck8nUxBHtbxKtjgcwyiA==}
peerDependencies:
'@uppy/core': ^2.0.3
'@uppy/xhr-upload': ^2.0.3
'@wangeditor/basic-modules': 1.x
'@wangeditor/core': 1.x
dom7: ^3.0.0
lodash.foreach: ^4.5.0
slate: ^0.72.0
snabbdom: ^3.1.0
dependencies:
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
'@wangeditor/basic-modules': 1.1.7(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
dom7: 3.0.0
lodash.foreach: 4.5.0
slate: 0.72.8
snabbdom: 3.6.2
dev: false
/@wangeditor/video-module@1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/core@1.1.19)(dom7@3.0.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2):
resolution: {integrity: sha512-ZdodDPqKQrgx3IwWu4ZiQmXI8EXZ3hm2/fM6E3t5dB8tCaIGWQZhmqd6P5knfkRAd3z2+YRSRbxOGfoRSp/rLg==}
peerDependencies:
'@uppy/core': ^2.1.4
'@uppy/xhr-upload': ^2.0.7
'@wangeditor/core': 1.x
dom7: ^3.0.0
nanoid: ^3.2.0
slate: ^0.72.0
snabbdom: ^3.1.0
dependencies:
'@uppy/core': 2.3.4
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
'@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.7)(slate@0.72.8)(snabbdom@3.6.2)
dom7: 3.0.0
nanoid: 3.3.7
slate: 0.72.8
snabbdom: 3.6.2
dev: false
/@webassemblyjs/ast@1.12.1:
resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==}
dependencies:
@ -3827,6 +4081,10 @@ packages:
- supports-color
dev: true
/compute-scroll-into-view@1.0.20:
resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==}
dev: false
/concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
@ -4699,6 +4957,12 @@ packages:
entities: 2.2.0
dev: true
/dom7@3.0.0:
resolution: {integrity: sha512-oNlcUdHsC4zb7Msx7JN3K0Nro1dzJ48knvBOnDPKJ2GV9wl1i5vydJZUSyOfrkKFDZEud/jBsTk92S/VGSAe/g==}
dependencies:
ssr-window: 3.0.0
dev: false
/domain-browser@4.23.0:
resolution: {integrity: sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==}
engines: {node: '>=10'}
@ -6445,6 +6709,10 @@ packages:
engines: {node: '>=8'}
dev: true
/html-void-elements@2.0.1:
resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==}
dev: false
/html-webpack-plugin@5.6.0(webpack@5.93.0):
resolution: {integrity: sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==}
engines: {node: '>=10.13.0'}
@ -6575,6 +6843,12 @@ packages:
requiresBuild: true
dev: true
/i18next@20.6.1:
resolution: {integrity: sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A==}
dependencies:
'@babel/runtime': 7.24.8
dev: false
/iconv-lite@0.4.24:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
@ -6710,6 +6984,10 @@ packages:
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
dev: false
/immer@9.0.21:
resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==}
dev: false
/immutable@4.3.6:
resolution: {integrity: sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==}
dev: true
@ -6995,6 +7273,10 @@ packages:
is-extglob: 2.1.1
dev: true
/is-hotkey@0.2.0:
resolution: {integrity: sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==}
dev: false
/is-interactive@1.0.0:
resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==}
engines: {node: '>=8'}
@ -7067,6 +7349,11 @@ packages:
dependencies:
isobject: 3.0.1
/is-plain-object@5.0.0:
resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
engines: {node: '>=0.10.0'}
dev: false
/is-png@2.0.0:
resolution: {integrity: sha512-4KPGizaVGj2LK7xwJIz8o5B2ubu1D/vcQsgOGFEDlpcvgZHto4gBnyd0ig7Ws+67ixmwKoNmu0hYnpo6AaKb5g==}
engines: {node: '>=8'}
@ -7145,6 +7432,10 @@ packages:
engines: {node: '>=10'}
dev: true
/is-url@1.2.4:
resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==}
dev: false
/is-weakref@1.0.2:
resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
dependencies:
@ -7431,9 +7722,16 @@ packages:
dependencies:
p-locate: 4.1.0
/lodash.camelcase@4.3.0:
resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
dev: false
/lodash.clonedeep@4.5.0:
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
dev: false
/lodash.debounce@4.0.8:
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
dev: true
/lodash.defaults@4.2.0:
resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==}
@ -7455,6 +7753,10 @@ packages:
resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==}
dev: false
/lodash.foreach@4.5.0:
resolution: {integrity: sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==}
dev: false
/lodash.groupby@4.6.0:
resolution: {integrity: sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==}
dev: false
@ -7495,6 +7797,14 @@ packages:
resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==}
dev: true
/lodash.throttle@4.1.1:
resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==}
dev: false
/lodash.toarray@4.4.0:
resolution: {integrity: sha512-QyffEA3i5dma5q2490+SgCvDN0pXLmRGSyAANuVi0HQ01Pkfr9fuoKQW8wm1wGBnJITs/mS7wQvS6VshUEBFCw==}
dev: false
/lodash.union@4.6.0:
resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==}
dev: false
@ -7711,6 +8021,12 @@ packages:
engines: {node: '>= 0.6'}
dev: true
/mime-match@1.0.2:
resolution: {integrity: sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==}
dependencies:
wildcard: 1.1.2
dev: false
/mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
@ -7854,11 +8170,14 @@ packages:
thenify-all: 1.6.0
dev: true
/namespace-emitter@2.0.1:
resolution: {integrity: sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==}
dev: false
/nanoid@3.3.7:
resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
dev: true
/nanomatch@1.2.13:
resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==}
@ -8968,6 +9287,10 @@ packages:
posthtml-render: 1.4.0
dev: true
/preact@10.24.3:
resolution: {integrity: sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==}
dev: false
/prelude-ls@1.1.2:
resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==}
engines: {node: '>= 0.8.0'}
@ -9007,6 +9330,11 @@ packages:
engines: {node: '>=4'}
dev: true
/prismjs@1.29.0:
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
engines: {node: '>=6'}
dev: false
/process-nextick-args@2.0.1:
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
@ -9582,6 +9910,12 @@ packages:
engines: {node: ^14.13.1 || >=16.0.0}
dev: false
/scroll-into-view-if-needed@2.2.31:
resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==}
dependencies:
compute-scroll-into-view: 1.0.20
dev: false
/seek-bzip@1.0.6:
resolution: {integrity: sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==}
hasBin: true
@ -9798,6 +10132,23 @@ packages:
engines: {node: '>=8'}
dev: true
/slate-history@0.66.0(slate@0.72.8):
resolution: {integrity: sha512-6MWpxGQZiMvSINlCbMW43E2YBSVMCMCIwQfBzGssjWw4kb0qfvj0pIdblWNRQZD0hR6WHP+dHHgGSeVdMWzfng==}
peerDependencies:
slate: '>=0.65.3'
dependencies:
is-plain-object: 5.0.0
slate: 0.72.8
dev: false
/slate@0.72.8:
resolution: {integrity: sha512-/nJwTswQgnRurpK+bGJFH1oM7naD5qDmHd89JyiKNT2oOKD8marW0QSBtuFnwEbL5aGCS8AmrhXQgNOsn4osAw==}
dependencies:
immer: 9.0.21
is-plain-object: 5.0.0
tiny-warning: 1.0.3
dev: false
/slice-ansi@2.1.0:
resolution: {integrity: sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==}
engines: {node: '>=6'}
@ -9807,6 +10158,11 @@ packages:
is-fullwidth-code-point: 2.0.0
dev: true
/snabbdom@3.6.2:
resolution: {integrity: sha512-ig5qOnCDbugFntKi6c7Xlib8bA6xiJVk8O+WdFrV3wxbMqeHO0hXFQC4nAhPVWfZfi8255lcZkNhtIBINCc4+Q==}
engines: {node: '>=12.17.0'}
dev: false
/snapdragon-node@2.1.1:
resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==}
engines: {node: '>=0.10.0'}
@ -9980,6 +10336,10 @@ packages:
frac: 1.1.2
dev: false
/ssr-window@3.0.0:
resolution: {integrity: sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA==}
dev: false
/ssri@8.0.1:
resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==}
engines: {node: '>= 8'}
@ -10450,6 +10810,10 @@ packages:
setimmediate: 1.0.5
dev: false
/tiny-warning@1.0.3:
resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
dev: false
/tmp@0.0.33:
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
engines: {node: '>=0.6.0'}
@ -11419,6 +11783,10 @@ packages:
dependencies:
isexe: 2.0.0
/wildcard@1.1.2:
resolution: {integrity: sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==}
dev: false
/wildcard@2.0.1:
resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==}

@ -0,0 +1,68 @@
import request from '@/utils/request'
/** 案件证据分类树 */
export function getCaseEvidenceTree(data) {
return request({
url: `/caseEvidence/category/tree`,
method: 'get',
params: data
})
}
/** 案件证据文件目录树 */
export function getCaseEvidenceFileTree(data) {
return request({
url: `/caseEvidence/directory/tree`,
method: 'get',
params: data
})
}
/** 创建目录 */
export function createDirectory(data) {
return request({
url: `/caseEvidence/directory/save`,
method: 'post',
data
})
}
/** 证据识别并提取 */
export function ocrAndExtract(data) {
return request({
url: `/caseEvidence/ocrAndExtract`,
method: 'post',
data
})
}
/** 案件证据文件目录树 */
export function getCaseEvidenceDirectoryList(data) {
return request({
url: `/caseEvidence/directory/ls`,
method: 'get',
params: data
})
}
/** 识别并提取列表 */
export function ocrAndExtractList(data) {
return request({
url: `/caseEvidence/ocrAndExtract/list`,
method: 'get',
params: data
})
}
/** 查询证据详情-结果以树的方式展示 */
export function ocrAndExtractDetails(data) {
return request({
url: `/caseEvidence/ocrAndExtract/details`,
method: 'get',
params: data
})
}
/** 核实证据 */
export function caseEvidenceVerify(data) {
return request({
url: `/caseEvidence/verify`,
method: 'post',
data
})
}

@ -1,5 +1,4 @@
import request from '@/utils/request'
import routes from '../gateway-routes'
/** 获取笔录基本信息 */
export function getRocordInfo(data) {

@ -24,13 +24,13 @@ export function saveChunkClassify(data) {
})
}
/** 保存提示词 */
export function addOrUpdPrompt(data) {
return request({
url: `${routes.record}/addOrUpdPrompt`,
method: 'post',
data
})
}
// export function addOrUpdPrompt(data) {
// return request({
// url: `${routes.record}/addOrUpdPrompt`,
// method: 'post',
// data
// })
// }
/** 删除提示词 */
export function delPrompt(data) {
return request({
@ -54,4 +54,21 @@ export function queryResult(data) {
method: 'get',
params: data
})
}
}
/** 提示词列表分页查询 */
export function queryPromptList(data) {
return request({
url: `/prompt/list`,
method: 'post',
data
})
}
/** 添加或更新 */
export function addOrUpdPrompt(data) {
return request({
url: `/record/addOrUpdPrompt`,
method: 'post',
data
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 694 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

@ -9,7 +9,7 @@
<template>
<div ref="screenRef" v-clickoutside="handleClose" class="screen-body">
<div v-if="title" class="title">{{ title }}</div>
<el-form label-width="60px" label-position="left" size="mini">
<el-form label-width="80px" label-position="left" size="mini">
<el-row :gutter="10" type="flex" class="search_header" style="align-items: stretch">
<el-col class="search_left">
<el-row :gutter="40">

@ -5,7 +5,7 @@ const network = {
// 默认的接口地址 如果是开发环境和生产环境走vab-mock-server当然你也可以选择自己配置成需要的接口地址
baseURL:
process.env.NODE_ENV === 'development'
? 'http://192.168.10.137:8097/fu-hsi-server'
? 'http://192.168.10.25:8097/fu-hsi-server'
: '/fuHsiApi',
// 配后端数据的接收方式application/json;charset=UTF-8或者application/x-www-form-urlencoded;charset=UTF-8
contentType: 'application/json;charset=UTF-8',

@ -0,0 +1,7 @@
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20.7777 6.05V19.5556C20.7777 20.9 19.6777 22 18.3333 22H3.66661C2.32217 22 1.22217 20.9 1.22217 19.5556V2.44444C1.22217 1.1 2.32217 0 3.66661 0H14.7277L20.7777 6.05Z" fill="#4F6BF6"/>
<path d="M12.488 16.2343H13.7634L15.8889 9.43262H14.6141L12.488 16.2343Z" fill="white"/>
<path d="M14.7278 4.82778V0L20.7778 6.05H15.95C15.2778 6.05 14.7278 5.5 14.7278 4.82778Z" fill="#243EBB"/>
<path d="M13.7634 16.2343H12.488L10.3626 10.2827H11.6374L13.7634 16.2343ZM9.51192 16.2343H8.23653L6.11108 9.43262H7.38586L9.51192 16.2343Z" fill="white"/>
<path d="M8.23657 16.2338H9.51196L11.6374 10.2822H10.3626L8.23657 16.2338Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 739 B

@ -126,6 +126,37 @@ export const asyncRoutes = [
}
]
},
{
path: '/prompt',
name: 'Prompt',
permission: 'p_promptProject',
component: Layout,
meta: { title: '提示工程' },
children: [
{
path: '/prompt-config',
name: 'PromptConfig',
permission: 'p_promptManagement',
component: () => import('@/views/promptManagement/PromptConfig/index.vue'),
meta: { title: '提示词配置', affix: false }
},
{
path: '/prompt-management',
name: 'PromptManagement',
permission: 'p_promptManagement',
component: () => import('@/views/promptManagement/index.vue'),
meta: { title: '提示词模板', affix: false }
},
{
path: '/prompt-test',
name: 'PromptTest',
permission: 'p_promptTest',
component: () => import('@/views/promptManagement/PromptTest.vue'),
meta: { title: '提示词调试', affix: false }
}
]
},
{
path: '/system',
name: 'System',
@ -191,46 +222,17 @@ export const asyncRoutes = [
permission: 'p_caseDetails',
component: () => import('@/views/caseDetails/components/EditEvidence/index.vue'),
meta: { title: '编辑图像证据', affix: true }
}
]
},
{
path: '/prompt',
name: 'Prompt',
permission: 'p_promptProject',
component: Layout,
meta: { title: '提示工程' },
children: [
{
path: '/prompt-config',
name: 'PromptConfig',
permission: 'p_promptManagement',
component: () => import('@/views/promptManagement/PromptConfig/index.vue'),
meta: { title: '提示词配置', affix: false }
},
{
path: '/add-prompt',
name: 'AddPrompt',
permission: 'p_promptManagement',
component: () => import('@/views/promptManagement/PromptConfig/add/index.vue'),
meta: { title: '新增提示词', affix: false }
},
{
path: '/prompt-management',
name: 'PromptManagement',
permission: 'p_promptManagement',
component: () => import('@/views/promptManagement/index.vue'),
meta: { title: '提示词模板', affix: false }
},
{
path: '/prompt-test',
name: 'PromptTest',
permission: 'p_promptTest',
component: () => import('@/views/promptManagement/PromptTest.vue'),
meta: { title: '提示词调试', affix: false }
meta: { title: '新增提示词', affix: true }
}
]
},
{
path: '*',
redirect: '/404',

@ -2,64 +2,148 @@
<template>
<cs-dialog
:dialog="dialogOptions"
@onSubmit="handleSubmit"
>
<template slot="content">
<div>
<el-form ref="form" :model="addInfo" :rules="rules" label-width="90px">
<el-form-item label="选择目录" prop="caseType">
<el-select v-model="dataInfo['caseType']" clearable placeholder="请选择案件类型">
<el-option v-for="item in caseTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-form-item label="选择目录" prop="directoryList">
<el-cascader
ref="cascaderRef"
v-model="addInfo.directoryList"
style="width: 100%;"
:options="treeData"
:props="{ checkStrictly: true,label:'categoryName',children:'child',value:'id' }"
clearable
@change="selectDirectory"
/>
</el-form-item>
<el-form-item label="提供人" prop="caseNo">
<el-select v-model="dataInfo['caseType']" clearable placeholder="请选择案件类型">
<el-option v-for="item in caseTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-form-item label="提供人" prop="provider">
<div class="flex-row" style="justify-content: space-between">
<el-select
v-model="addInfo.provider"
placeholder="请选择姓名"
style="width: 83%"
@change="selectProvider"
>
<el-option
v-for="item in userList"
:key="item.id"
:value="item.name"
:label="item.name"
>
<span>{{ `${item.name}` }}</span>
</el-option>
</el-select>
<el-button type="primary" @click="handleAdd"></el-button>
</div>
</el-form-item>
<el-form-item label="模版类型" prop="caseNo">
<el-input v-model="dataInfo['name']" clearable placeholder="请输入指令名称" />
<el-form-item label="模版类型" prop="type">
<el-input v-model="addInfo['type']" clearable placeholder="请输入" />
</el-form-item>
<el-form-item label="备注" prop="caseNo">
<el-input v-model="dataInfo['name']" clearable placeholder="请输入指令名称" />
<el-form-item label="文件夹名称" prop="directoryName">
<el-input v-model="addInfo['directoryName']" clearable placeholder="请输入" />
</el-form-item>
</el-form>
<!--新增用户-->
<add-case-user ref="add" @reloadData="getUserList" />
</div>
</template>
</cs-dialog>
</template>
<script>
import AddCaseUser from '../edit/AddCaseUser.vue'
import { queryUserList } from '@/api/caseDetails'
import { createDirectory, getCaseEvidenceTree } from '@/api/caseDetails/evidence'
export default {
name: 'AddFolder',
components: { AddCaseUser },
data() {
return {
dialogOptions: {
show: false,
width: '930px',
width: '510px',
title: {
title: '新建文件夹'
},
hiddenFooter: true,
appendToBody: true
},
addInfo:{
options: [],
rules: {},
treeData: [],
selectName: '',
//
userList: [],
//
roleList: JSON.parse(sessionStorage.getItem('case_role')),
addInfo: {
parentId: '',
directoryList: []
}
}
},
watch: {
selectName: {
handler: function(val) {
if (val && this.addInfo.provider) {
this.$set(this.addInfo, 'directoryName', `${val}-${this.addInfo.provider}`)
}
},
immediate: true
}
},
mounted() {
this.getUserList()
},
methods: {
//
show() {
this.dialogOptions.show = true
this.getTreeList()
},
selectProvider(val) {
if (val && this.selectName) {
this.$set(this.addInfo, 'directoryName', `${this.selectName}-${val}`)
}
},
getTreeList() {
getCaseEvidenceTree({ caseId: this.caseId, caseType: 1 }).then(res => {
if (res.code === 200) {
this.treeData = res.data
}
})
},
handleAdd() {
this.$refs.add.show()
},
selectDirectory(item) {
const nodes = this.$refs.cascaderRef.getCheckedNodes()
console.log(nodes)
this.$set(this.addInfo, 'type', nodes[0].data.promptName)
this.selectName = nodes[0].data.categoryName
// this.addInfo.type = nodes[0].data.promptName
},
//
getUserList() {
queryUserList({ caseId: this.$route.params.id }).then(res => {
this.userList = res.data
})
},
handleSelect(val) {
this.$emit('selectOk', val)
this.dialogOptions.show = false
handleSubmit() {
createDirectory({
caseId: this.$route.params.id,
directoryName: this.addInfo.directoryName,
provider: this.addInfo.provider,
categoryId: this.addInfo.directoryList[this.addInfo.directoryList.length - 1]
}).then(res => {
if (res.code === 200) {
this.$message.success('添加成功')
this.$emit('addOk', res.data)
this.dialogOptions.show = false
}
})
}
}
}

@ -0,0 +1,99 @@
<template>
<cs-dialog
:dialog="dialogOptions"
@onSubmit="handleSubmit"
>
<template slot="content">
<div class="move-tree">
<el-input
v-model="filterText"
prefix-icon="el-icon-search"
placeholder="搜索名称"
/>
<el-tree
:data="treeData"
highlight-current
default-expand-all
:props="defaultProps"
@node-click="handleNodeClick"
/>
</div>
</template>
</cs-dialog>
</template>
<script>
import { getCaseEvidenceFileTree } from '@/api/caseDetails/evidence'
export default {
name: 'MoveFolder',
data() {
return {
dialogOptions: {
show: false,
width: '510px',
title: {
title: '移动文件到'
},
appendToBody: true
},
selectId: '',
filterText: '',
treeData: [],
defaultProps: {
children: 'child',
label: 'directoryName'
}
}
},
mounted() {
},
methods: {
//
show() {
this.dialogOptions.show = true
this.getTreeList()
},
handleNodeClick(data) {
this.selectId = data.id
},
//
getTreeList() {
getCaseEvidenceFileTree({ caseId: this.$route.params.id }).then(res => {
if (res.code === 200) {
this.treeData = res.data
}
})
},
handleSubmit() {
this.dialogOptions.show = false
this.$emit('selectOk', this.selectId)
}
}
}
</script>
<style scoped lang="scss">
.move-tree {
background: #F9FAFB;
::v-deep {
.el-tree {
background: #F9FAFB;
.el-tree-node {
// height: 40px;
font-size: 16px;
color: #333333;
}
.el-tree-node__content {
height: 40px;
}
.el-tree-node.is-current > .el-tree-node__content {
background: #dce3ed;
color: #666666;
}
}
}
}
</style>

@ -0,0 +1,526 @@
<template>
<div class="EvidenceConfirm">
<div class="header">
<div class="nav-list">
<div v-for="(item,index) in navList" :key="index" class="nav-item">
<span>{{ item }}</span>
<span v-if="index !== navList.length -1">></span>
</div>
</div>
<div class="title">
<span>{{ `案件名称:${caseName}` }}</span>
<span>{{ `案件编号:${caseNo}` }}</span>
</div>
</div>
<div class="proofread-content">
<div class="left-tree">
<el-tree
ref="tree"
:data="treeData"
:props="defaultProps"
:expand-on-click-node="false"
default-expand-all
node-key="id"
highlight-current
@node-click="handleNodeClick"
/>
</div>
<div class="mid-content">
<div class="left">
<el-scrollbar v-if="selectList.length > 0" class="left-scroll">
<vuedraggable v-model="selectList" animation="400" class="img_list">
<div v-for="(item,index) in selectList" :key="index" class="img_item" :class="[item.fileId === selectInfo.fileId?'actived':'']">
<img v-if="['jpg', 'png'].includes(item.fileType)" :src="getImgUrl(item.fileId)" @click="selectItem(item)">
</img>
<svg-icon v-if="[ 'doc', 'docx'].includes(item.fileType)" class="svg-img" icon-class="docx" />
</div>
</vuedraggable>
</el-scrollbar>
<div v-if="selectList.length > 0 && ['jpg', 'png'].includes(selectInfo.fileType)" class="act_img">
<img v-if="selectInfo.fileId" :src="getImgUrl(selectInfo.fileId)" alt="">
</div>
<div v-if="selectList.length === 0" class="empty-content">
<img src="@/assets/caseManagement/empty.png" alt="">
<span>暂无本次证据材料</span>
</div>
<span class="boder1" />
<span class="boder2" />
<span class="boder3" />
<span class="boder4" />
</div>
<div class="right">
<div class="title">识别结果</div>
<el-input
v-model="selectInfo.ocrText"
class="right-text"
type="textarea"
/>
<span class="boder1" />
<span class="boder2" />
<span class="boder3" />
<span class="boder4" />
</div>
</div>
<div class="FormInfo">
<el-form ref="form" :model="selectInfo" :rules="rules" label-width="100px" style="margin-top: 10px">
<el-row :gutter="10" class="form-content">
<el-col :span="24">
<el-form-item label="证据名称" prop="title">
<el-input v-model="selectInfo.evidenceInfo.title" placeholder="请输入证据名称" />
</el-form-item>
</el-col>
</el-row>
<el-row v-if="selectInfo.evidenceInfo.property.length > 0" :gutter="10" class="form-content">
<el-col v-for="(item,index) in selectInfo.evidenceInfo.property" :key="index" :span="24">
<el-form-item :label="item.attrName">
<el-input v-if="item.attrValueType ==='text'" v-model="item.attrValue" placeholder="请输入" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
</div>
<div class="footer-btns">
<div class="btn" @click="submit"></div>
<div class="btn" @click="save"></div>
<div class="reset_btn" @click="reset"></div>
</div>
</div>
</template>
<script>
import * as vuedraggable from 'vuedraggable'
import { baseURL } from '@/config'
import { commonDownloadFile } from '@/api/config/uploadApi'
import { ocrAndExtractDetails, caseEvidenceVerify } from '@/api/caseDetails/evidence'
export default {
name: 'RecordProofread',
components: { vuedraggable },
data() {
return {
selectList: [],
activedImg: '',
caseNo: '',
caseName: '',
dataInfo: {},
navList: [],
//
evidenceTypeList: JSON.parse(sessionStorage.getItem('evidence_type')),
defaultProps: {
children: 'child',
label: 'directoryName'
},
rules: {
title: [{ required: true, message: '证据名称不能为空!', trigger: 'blur' }]
},
treeData: [],
flag: true,
selectInfo: {
evidenceInfo: {
property: [],
title: ''
},
ocrText: ''
}
}
},
mounted() {
this.getTreeList()
this.caseNo = this.$route.query.caseNo
this.caseName = this.$route.query.caseName
},
methods: {
getParentNames(node, treeData, parentNames = []) {
//
const parent = treeData.find(parentNode =>
parentNode.child && parentNode.child.some(child => child.id === node.id)
)
//
if (parent) {
parentNames.push(parent.directoryName)
return this.getParentNames(parent, treeData, parentNames)
}
//
return parentNames
},
//
getTreeList() {
ocrAndExtractDetails({ caseId: this.$route.params.id, batchNo: this.$route.query.recordId }).then(res => {
if (res.code === 200) {
this.treeData = res.data
this.$nextTick(() => {
this.handleNodeClick(res.data[0])
})
}
})
},
getImgUrl(id) {
return `${baseURL}${commonDownloadFile}${id}`
},
selectItem(item) {
this.selectInfo = item
this.activedImg = `${baseURL}${commonDownloadFile}${this.selectInfo.fileId}`
},
reset() {
},
findNodeById(nodes, id) {
for (const node of nodes) {
if (node.id === id) {
return node
} else if (node.child) {
const foundNode = this.findNodeById(node.child, id)
if (foundNode) {
return foundNode
}
}
}
return null
},
// list
getFileList(nodes) {
for (const node of nodes) {
if (node.fileInfoList.length > 0) {
return node
} else if (node.child) {
const foundNode = this.getFileList(node.child)
if (foundNode) {
return foundNode
}
}
}
return null
},
handleNodeClick(data) {
this.selectId = data.id
this.navList = []
this.navList = this.getParentNames(data, this.treeData)
const nodeItem = this.findNodeById(this.treeData, this.selectId)
if (nodeItem.fileInfoList.length === 0) {
const newNodeItem = this.getFileList(nodeItem.child)
this.$refs.tree.setCurrentKey(newNodeItem.id)
this.selectList = newNodeItem.fileInfoList
this.selectInfo = this.selectList[0]
} else {
this.selectList = nodeItem.fileInfoList
this.selectInfo = this.selectList[0]
}
this.navList.push(data.directoryName)
},
checkEvidence(nodes) {
for (const item of nodes) {
if (item.fileInfoList.length > 0) {
for (let i = 0; i < item.fileInfoList.length; i++) {
if (!item.fileInfoList[i].evidenceInfo.title) {
this.handleNodeClick(item)
this.selectItem(item.fileInfoList[i])
this.flag = false
break
}
}
} else if (item.child) {
this.checkEvidence(item.child)
}
}
},
save() {
this.checkEvidence(this.treeData)
if (this.flag) {
caseEvidenceVerify({
batchNo: this.$route.query.recordId,
caseId: this.$route.params.id,
evidenceDirectoryList: this.treeData
}).then(res => {
if (res.code === 200) {
this.$baseMessage.success(res.msg || '保存成功!')
this.$store.dispatch(
'tabsBar/delRoute',
this.$route
)
this.$router.push({ path: `/case-details/${this.$route.params.id}/${this.$route.query.caseName}`, query: { isEdit: 1, caseNo: this.$route.query.caseNo }})
}
})
} else {
this.$baseMessage.error('证据不能为空!')
}
},
submit() {
this.save()
this.$emit('submit')
}
}
}
</script>
<style lang="scss" scoped>
.EvidenceConfirm {
display: flex;
flex: 1;
padding: 0 24px;
flex-direction: column;
:deep(.el-scrollbar__wrap) {
overflow-x: hidden;
}
.left-tree {
width: 210px;
margin-right: 16px;
background: #F9FAFB;
::v-deep {
.el-tree {
background: #F9FAFB;
.el-tree-node {
// height: 40px;
font-size: 16px;
color: #333333;
}
.el-tree-node__content {
height: 40px;
}
.el-tree-node.is-current > .el-tree-node__content {
background: #dce3ed;
color: #666666;
}
}
}
}
.proofread-content {
flex: 1;
margin-left: 18px;
display: flex;
.mid-content {
display: flex;
flex: 1;
.left {
width: 55%;
margin-right: 24px;
position: relative;
// background: #F6F8F9;
border: 1px solid #DCE3EB;
display: flex;
padding: 8px;
.empty-content {
flex: 1;
padding: 24px;
display: flex;
margin-top: 16px;
flex-direction: column;
display: flex;
justify-content: center;
align-items: center;font-size: 16px;
color: #333333;
img {
width: 200px;
height: 200px;
}
}
.left-scroll {
background: #F6F8F9;
width: 150px;
margin-right: 14px;
}
.act_img {
padding: 16px 28px;
flex: 1;
background: #F6F8F9;
height: calc(100vh - 420px);
background-size: 100% 100%;
display: flex;
align-items: center;
justify-content: center;
img {
height: 100%;
}
}
.actived {
border: 2px solid #3763FF !important;
}
}
.right {
width: 45%;
position: relative;
border: 1px solid #DCE3EB;
display: flex;
padding: 8px;
flex-direction: column;
.title {
background: #F6F8F9;
border-bottom: 1px solid #DCE3EB;
height: 70px;
padding-left: 24px;
line-height: 70px;
font-weight: bold;
font-size: 18px;
color: #333333;
}
.right-text {
width: 100%;
height: 500px;
}
}
}
.FormInfo {
width: 410px;
background: #F6F8F9;
border-radius: 8px 8px 8px 8px;
margin-left: 24px;
// height: calc(100vh - 350px);
padding: 0 24px;
margin-bottom: 72px;
.expand {
display: flex;
flex-direction: row-reverse;
padding: 0 24px;
align-items: center;
cursor: pointer;
margin-bottom: 16px;
img {
width: 18px;
height: 18px;
margin-right: 8px;
}
.line {
flex: 1;
height: 1px;
background: #E9E9E9;
margin-right: 8px;
}
}
}
.img_list {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 25px;
overflow-x: hidden;
padding: 24px;
background: #F6F8F9;
.img_item {
width: 98px;
height: 138px;
margin-bottom: 16px;
border-radius: 6px 6px 6px 6px;
border: 1px solid #D1D3D6;
cursor: move;
}
.svg-img {
width: 98px;
height: 138px;
margin-bottom: 16px;
border-radius: 6px 6px 6px 6px;
border: 1px solid #D1D3D6;
cursor: move;
}
}
.boder1 {
position: absolute;
width: 15px;
height: 15px;
left: 0;
top: 0;
border-top: 2px solid #2073FF;
border-left: 2px solid #2073FF;
}
.boder2 {
position: absolute;
width: 15px;
height: 15px;
right: 0;
top: 0;
border-top: 2px solid #2073FF;
border-right: 2px solid #2073FF;
}
.boder3 {
position: absolute;
width: 15px;
height: 15px;
left: 0;
bottom: 0;
border-bottom: 2px solid #2073FF;
border-left: 2px solid #2073FF;
}
.boder4 {
position: absolute;
width: 15px;
height: 15px;
right: 0;
bottom: 0;
border-bottom: 2px solid #2073FF;
border-right: 2px solid #2073FF;
}
}
.header {
display: flex;
justify-content: space-between;
padding-left: 210px;
.nav-list {
display: flex;
font-size: 16px;
color: #333333;
margin-bottom: 16px;
.nav-item {
display: flex;
span {
margin-right: 16px;
}
}
}
.title {
// display: flex;
text-align: right;font-size: 16px;
color: #333333;
margin-bottom: 24px;
span {
margin-left: 32px;
}
}
}
.footer-btns {
padding-top: 24px;
height: 68px;
display: flex;
flex-direction: row-reverse;
.btn {
width: 188px;
height: 48px;
background: #3763FF;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.04);
border-radius: 6px 6px 6px 6px;
text-align: center;
line-height: 48px;
font-size: 16px;
color: #FFFFFF;
cursor: pointer;
margin-left: 24px;
}
.reset_btn {
width: 188px;
height: 48px;
background: #FFFFFF;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.04);
border-radius: 6px 6px 6px 6px;
border: 1px solid #3763FF;
text-align: center;
line-height: 48px;
font-size: 16px;
color: #3763FF;
cursor: pointer;
margin-left: 24px;
}
}
}
</style>
<style lang="scss" scoped>
::v-deep .el-textarea__inner {
height: calc(100vh - 450px);
border: none;
box-shadow: none;
}
</style>

@ -0,0 +1,216 @@
<template>
<div class="EvidenceExtract">
<div class="title">
<span>{{ `案件名称:${caseName}` }}</span>
<span>{{ `案件编号:${caseNo}` }}</span>
</div>
<vxe-grid v-bind="gridOptions" class="record_table">
<template #status="{row}">
<div v-if="row.status === '2'" class="status">
<img src="@/assets/record/success.png" alt="">
<span>识别成功</span>
</div>
<div v-if="row.status === '3'" class="status">
<img src="@/assets/record/error.png" alt="">
<span>识别失败</span>
</div>
<!-- <div v-if="row.status === '0'">
<img src="@/assets/record/error.png" alt="">
<span>未识别</span>
</div> -->
<div v-if="row.status === '1' || row.status === '0'" class="status">
<!-- <img src="@/assets/record/error.png" alt=""> -->
<div v-loading="true" style="width: 20px;height: 20px;margin-right: 8px;position: relative;top: 12px;" />
<span>正在识别</span>
</div>
</template>
<template #opera="{ row, rowIndex}">
<div class="btn-list">
<!-- <img src="@/assets/record/reset_identify.png" alt=""> -->
<!-- <img src="@/assets/record/view_detail.png" alt=""> -->
<el-image
style="width: 16px; height: 16px;margin-right: 16px;"
:src="detailImg"
:preview-src-list="getImgUrlList(row)"
fit="cover"
@click="openDeatils(row)"
/>
<!-- <img src="@/assets/record/del.png" alt="" @click="del(row,rowIndex )"> -->
</div>
</template>
</vxe-grid>
<div class="footer-btns">
<div class="reset_btn" @click="closed"></div>
<div class="btn" @click="next"></div>
</div>
</div>
</template>
<script>
import * as vuedraggable from 'vuedraggable'
import { baseURL } from '@/config'
import { commonDownloadFile } from '@/api/config/uploadApi'
import { saveRecord, deleteFile } from '@/api/caseDetails/ocr'
import { ocrAndExtractList } from '@/api/caseDetails/evidence'
export default {
name: 'EvidenceExtract',
components: { vuedraggable },
data() {
return {
detailImg: require('@/assets/record/view_detail.png'),
caseNo: '',
caseName: '',
props: {
recordId: {
type: String,
default: ''
}
},
gridOptions: {
columns: [
{ title: '序号', type: 'seq', width: '80px' },
{ title: '证据名称', field: 'evidenceName' },
{ title: '附件名称', field: 'attachmentName' },
{ title: '模板类型', field: 'templateName',width:'200px' },
{ title: '证据类型', field: 'evidenceTypeName',width:'200px' },
{ title: '附件大小', field: 'attachmentSize',width:'150px' },
{ title: '状态', slots: { default: 'status' }, align: 'center' },
// { title: '', slots: { default: 'opera' }, fixed: 'right', width: '200px' }
],
data: [
]
},
srcList: []
}
},
mounted() {
this.getDataList()
this.caseNo = this.$route.query.caseNo
this.caseName = this.$route.query.caseName
},
methods: {
getImgUrlList(row) {
return [`${baseURL}${commonDownloadFile}${row.fileId}`]
},
getDataList() {
ocrAndExtractList({
batchNo: this.$route.query.recordId,
caseId: this.$route.params.id
}).then(res => {
if (res.code === 200) {
this.$set(this.gridOptions, 'data', res.data)
this.gridOptions.data = res.data
for (const item of res.data) {
if (item.status !== '2' && item.status !== '3') {
setTimeout(() => {
this.getDataList()
}, 3000)
return
}
}
}
})
},
del(row, index) {
if (this.gridOptions.data.length === 1) {
this.$baseMessage.error('至少保留一条数据!')
return
}
deleteFile({ recordId: this.$route.query.recordId, fileId: row.fileId }).then(res => {
if (res.code === 200) {
this.gridOptions.data.splice(index, 1)
this.$baseMessage.success('删除成功!')
}
})
},
closed() {
this.$store.dispatch(
'tabsBar/delRoute',
this.$route
)
this.$router.push({ path: `/case-details/${this.$route.params.id}/${this.$route.query.caseName}`, query: { isEdit: 1, caseNo: this.$route.query.caseNo }})
},
next() {
this.$emit('save', this.$route.query.recordId)
}
}
}
</script>
<style lang="scss" scoped>
.EvidenceExtract {
display: flex;
flex-direction: column;
padding: 0 24px;
.title {
// display: flex;
text-align: right;font-size: 16px;
color: #333333;
margin-bottom: 24px;
span {
margin-left: 32px;
}
}
.record_table {
flex: 1;
margin-left: 18px;
}
.status {
display: flex;
justify-content: center;
align-items: center;
img {
width: 20px;
height: 20px;
margin-right: 8px;
}
::v-deep {
.el-loading-spinner .circular {
width: 20px;
height: 20px;
}
}
}
.btn-list {
img {
width: 16px;
height: 16px;
cursor: pointer;
margin-right: 16px;
}
}
.footer-btns {
position: absolute;
right: 24px;
bottom: 24px;
display: flex;
.reset_btn {
width: 188px;
height: 48px;
background: #FFFFFF;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.04);
border-radius: 6px 6px 6px 6px;
border: 1px solid #3763FF;
text-align: center;
line-height: 48px;
font-size: 16px;
color: #3763FF;
cursor: pointer;
margin-left: 24px;
}
.btn {
width: 188px;
height: 48px;
background: #3763FF;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.04);
border-radius: 6px 6px 6px 6px;
text-align: center;
line-height: 48px;
font-size: 16px;
color: #FFFFFF;
cursor: pointer;
margin-left: 24px;
}
}
}
</style>

@ -0,0 +1,516 @@
<template>
<div class="UploadEvidence">
<div class="left-tree">
<el-input
v-model="filterText"
prefix-icon="el-icon-search"
placeholder="搜索名称"
/>
<el-tree
:data="treeData"
:props="defaultProps"
node-key="id"
current-node-key="1"
highlight-current
default-expand-all
@node-click="handleNodeClick"
/>
</div>
<div class="main-content">
<div class="nav-list">
<div v-for="(item,index) in navList" :key="index" class="nav-item">
<span>{{ item }}</span>
<span v-if="index !== navList.length -1">></span>
</div>
</div>
<div class="btn-list">
<el-button type="primary" icon="el-icon-folder-add" @click="addFolder"></el-button>
<el-upload
:headers="{
token: token
}"
:action="uploadOption.action"
:accept="uploadOption.accept"
multiple
:on-success="handleSuccess"
:before-upload="beforeUpload"
:show-file-list="false"
class="drag-content btn-list"
>
<el-button type="primary" style="height: 42px;margin-left: 24px;" icon="el-icon-circle-plus-outline">添加证据</el-button>
</el-upload>
<div class="plain-btn" @click="move"></div>
<!-- <div class="plain-btn">删除文件夹</div> -->
<div class="plain-btn" @click="del"></div>
<div class="case-content">
<span>{{ `案件名称:${caseName}` }}</span>
<span>{{ `案件编号:${caseNo}` }}</span>
</div>
</div>
<div v-if="selectList.length > 0" class="file-content">
<vuedraggable v-model="selectList" animation="400" class="file-list">
<div v-for="(item,index) in selectList" :key="index" class="file-item" @click="selectItem(index)">
<div class="main-content">
<img v-if="item.type === 1" src="@/assets/file/type1.png" alt="">
<svg-icon v-if="item.type === 3" class="svg-img" icon-class="docx" />
<img v-if="item.type === 2" class="file-img" :src="getImgUrl(item.fileId)" alt="">
</div>
<div class="footer">{{ item.fileName }}</div>
<div v-if="!item.check" class="no-select" />
<img v-else src="@/assets/file/check.png" class="selected" alt="">
</div>
</vuedraggable>
</div>
<div v-else class="empty-content">
<img src="@/assets/caseManagement/empty.png" alt="">
<span>暂无本次证据材料</span>
</div>
<div class="footer-btns">
<div class="btn" @click="save"></div>
<div class="reset_btn" @click="closed"></div>
</div>
</div>
<AddFolder ref="AddFolderRef" @addOk="addFolderOk" />
<MoveFolder ref="MoveFolderRef" @selectOk="selectOk" />
</div>
</template>
<script>
import { baseURL } from '@/config'
import { getAccessToken } from '@/utils/accessToken'
import { commonDownloadFile } from '@/api/config/uploadApi'
import * as vuedraggable from 'vuedraggable'
import AddFolder from '../AddFolder.vue'
import MoveFolder from '../MoveFolder.vue'
import { getCaseEvidenceFileTree, ocrAndExtract } from '@/api/caseDetails/evidence'
export default {
name: 'UploadEvidence',
components: { vuedraggable, AddFolder, MoveFolder },
data() {
return {
//
uploadOption: {
action: `${baseURL}/minio/uploadFile`,
accept: '.bmp,.jpg,.png,.doc,.docx'
},
token: getAccessToken(),
filterText: '',
defaultProps: {
children: 'child',
label: 'directoryName'
},
navList: ['未分类'],
caseNo: '',
caseName: '',
selectList: [],
selectId: '1',
treeData: []
}
},
mounted() {
this.getTreeList()
this.caseNo = this.$route.query.caseNo
this.caseName = this.$route.query.caseName
},
methods: {
beforeUpload(file) {
const isLt5M = file.size / 1024 / 1024 < 5
const filename = file.name
const postfix = filename.substring(filename.lastIndexOf('.'))
if (!['.jpg', '.png', '.doc', '.docx'].includes(postfix)) {
this.$message.error('上传的文件格式不符合要求!')
return false
}
if (!isLt5M) {
this.$message.error('上传文件大小不能超过 5MB!')
return false
}
return true
},
handleSuccess(res, file) {
const filename = file.name
const postfix = filename.substring(filename.lastIndexOf('.'))
const obj = {
fileName: file.name,
fileId: res.data,
type: 2,
check: false
}
if (['.doc', '.docx'].includes(postfix)) {
obj.type = 3
}
// const selectItem = this.findSelectNode(this.treeData)
this.addNodeProperty(this.selectId, obj)
this.selectList.push(obj)
},
del() {
const list = this.getSelectList()
if (list.length === 0) {
this.$baseMessage.error('请选择文件!')
return
}
list.forEach(e => {
if (e.type === 1) {
this.$baseMessage.error('不能删除文件夹!')
return
}
})
this.delFiles()
},
//
delFiles() {
const node = this.findNodeById(this.treeData, this.selectId)
for (let i = node.fileInfoList.length - 1; i >= 0; i--) {
if (node.fileInfoList[i].check === true) {
node.fileInfoList.splice(i, 1)
}
}
this.selectList = JSON.parse(JSON.stringify(node.fileInfoList))
},
//
selectOk(val) {
if (this.selectId === val) {
this.$message.error('不能移动到相同的文件夹')
return false
}
const list = this.getSelectList()
this.moveNodeFileList(val, list)
this.delFiles()
},
moveNodeFileList(toId, list) {
const node = this.findNodeById(this.treeData, toId)
for (const item of list) {
node.fileInfoList.push(item)
}
},
addNodeProperty(nodeId, data) {
const node = this.findNodeById(this.treeData, nodeId)
if (node) {
node.fileInfoList.push(data)
node.fileIdList.push(data.fileId)
}
console.log('111', this.treeData)
},
findNodeById(nodes, id) {
for (const node of nodes) {
if (node.id === id) {
return node
} else if (node.child) {
const foundNode = this.findNodeById(node.child, id)
if (foundNode) {
return foundNode
}
}
}
return null
},
getParentNames(node, treeData, parentNames = []) {
//
const parent = treeData.find(parentNode =>
parentNode.child && parentNode.child.some(child => child.id === node.id)
)
//
if (parent) {
parentNames.push(parent.directoryName)
return this.getParentNames(parent, treeData, parentNames)
}
//
return parentNames
},
//
getTreeList() {
getCaseEvidenceFileTree({ caseId: this.$route.params.id }).then(res => {
if (res.code === 200) {
this.treeData = res.data
this.treeData.unshift({
directoryName: '未分类',
id: '1',
fileIdList: [],
fileInfoList: []
})
}
})
},
handleNodeClick(data) {
this.selectId = data.id
this.selectList = []
this.navList = []
if (this.selectId === '1') {
this.selectList = JSON.parse(JSON.stringify(this.treeData[0].fileInfoList))
} else {
const nodeItem = this.findNodeById(this.treeData, this.selectId)
if (nodeItem.child && nodeItem.child.length > 0) {
for (const item of nodeItem.child) {
this.selectList.push({
fileName: item.directoryName,
type: 1,
check: false
})
}
}
for (const item of nodeItem.fileInfoList) {
this.selectList.push(item)
}
}
this.navList = this.getParentNames(data, this.treeData)
this.navList.push(data.directoryName)
},
//
selectItem(index) {
this.selectList[index].check = !this.selectList[index].check
},
addFolderOk(item) {
const node = this.findNodeById(this.treeData, item.parentId)
node.child.push({
...item,
child: [],
fileIdList: [],
fileInfoList: []
})
},
getSelectList() {
const list = []
for (const item of this.selectList) {
if (item.check) {
list.push(item)
}
}
return list
},
//
move() {
const list = this.getSelectList()
if (list.length === 0) {
this.$baseMessage.error('请选择文件!')
return
}
list.forEach(e => {
if (e.type === 1) {
this.$baseMessage.error('不能移动文件夹!')
return
}
})
this.$refs.MoveFolderRef.show()
},
closed() {
this.$store.dispatch(
'tabsBar/delRoute',
this.$route
)
this.$router.push({ path: `/case-details/${this.$route.params.id}/${this.$route.query.caseName}`, query: { isEdit: 1, caseNo: this.$route.query.caseNo }})
},
save() {
if (this.treeData[0].fileInfoList && this.treeData[0].fileInfoList.length > 0) {
this.$baseMessage.error('请分类!')
return
}
const list = JSON.parse(JSON.stringify(this.treeData))
list.splice(0, 1)
ocrAndExtract({
evidenceFileList: list,
caseId: this.$route.params.id
}).then(res => {
if (res.code === 200) {
this.$baseMessage.success('新增成功!')
this.$emit('save', res.data)
}
})
},
addFolder() {
this.$refs.AddFolderRef.show()
},
getImgUrl(id) {
return `${baseURL}${commonDownloadFile}${id}`
}
}
}
</script>
<style lang="scss" scoped>
.UploadEvidence {
display: flex;
padding: 0 24px;
flex: 1;
.left-tree {
width: 210px;
margin-right: 16px;
background: #F9FAFB;
::v-deep {
.el-tree {
background: #F9FAFB;
.el-tree-node {
// height: 40px;
font-size: 16px;
color: #333333;
}
.el-tree-node__content {
height: 40px;
}
.el-tree-node.is-current > .el-tree-node__content {
background: #dce3ed;
color: #666666;
}
}
}
}
.main-content {
display: flex;
flex-direction: column;
flex: 1;
.svg-img {
}
.nav-list {
display: flex;
font-size: 16px;
color: #333333;
margin-bottom: 16px;
.nav-item {
display: flex;
span {
margin-right: 16px;
}
}
}
.btn-list {
display: flex;
position: relative;
.plain-btn {
height: 42px;
background: #FFFFFF;
border-radius: 6px 6px 6px 6px;
border: 1px solid #3763FF;
padding: 0 24px;
line-height: 42px;
cursor: pointer;
margin-left: 24px;font-size: 16px;
color: #3763FF;
}
.case-content {
position: absolute;
right: 0px;
span {
font-size: 16px;
color: #333333;
margin-left: 32px;
}
}
}
.file-content {
flex: 1;
border: 1px dashed #3763ff;
padding: 24px;
display: flex;
margin-top: 16px;
.file-list {
display: flex;
}
.file-item {
width: 190px;
height: 230px;
position: relative;
margin-right: 16px;
cursor: pointer;
.main-content {
background: #F5F5F5;
height: 188px;
display: flex;
justify-content: center;
align-items: center;
.svg-img, img {
width: 120px;
height: 120px;
}
.file-img {
width: 132px;
height: 188px;
}
}
.footer {
line-height: 42px;
height: 42px;
background: #FFFFFF;
border-radius: 0px 0px 12px 12px;
padding-left: 16px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
vertical-align: middle;
box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.08);font-size: 16px;
color: #333333;
}
.no-select {
position: absolute;
top: 12px;
right: 12px;width: 22px;
height: 22px;
background: #FFFFFF;
border-radius: 4px 4px 4px 4px;
border: 1px solid #D9D9D9;
cursor: pointer;
}
.selected {
width: 22px;
height: 22px;
position: absolute;
top: 12px;
right: 12px;
cursor: pointer;
}
}
}
.empty-content {
flex: 1;
border: 1px dashed #3763ff;
padding: 24px;
display: flex;
margin-top: 16px;
flex-direction: column;
display: flex;
justify-content: center;
align-items: center;font-size: 16px;
color: #333333;
img {
width: 200px;
height: 200px;
}
}
.footer-btns {
display: flex;
flex-direction: row-reverse;
padding: 24px 0;
.reset_btn {
width: 188px;
height: 48px;
background: #FFFFFF;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.04);
border-radius: 6px 6px 6px 6px;
border: 1px solid #3763FF;
text-align: center;
line-height: 48px;
font-size: 16px;
color: #3763FF;
cursor: pointer;
margin-left: 24px;
}
.btn {
width: 188px;
height: 48px;
background: #3763FF;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.04);
border-radius: 6px 6px 6px 6px;
text-align: center;
line-height: 48px;
font-size: 16px;
color: #FFFFFF;
cursor: pointer;
margin-left: 24px;
}
}
}
}
</style>

@ -0,0 +1,162 @@
<template>
<div class="EditEvidence">
<div class="step-list">
<div class="step-list-item">
<img :src="actUploadImg" alt="">
<span class="actived">证据上传并归档</span>
</div>
<div :class="[activeStep > 0 ?'act-step-line':'step-line']">
<span>>></span>
</div>
<div class="step-list-item">
<img v-if="activeStep > 0" :src="actIdentifyImg" alt="">
<img v-else :src="identifyImg" alt="">
<span :class="[activeStep > 0 ?'actived':'']">证据识别并提取</span>
</div>
<div :class="[activeStep > 0 ?'act-step-line':'step-line']">
<span>>></span>
</div>
<div class="step-list-item">
<img v-if="activeStep > 1" :src="actUploadImg" alt="">
<img v-else :src="uploadImg" alt="">
<span :class="[activeStep > 1 ?'actived':'']">证据确认</span>
</div>
</div>
<UploadEvidence v-show="activeStep === 0" ref="UploadEvidenceRef" @save="saveOk" />
<EvidenceExtract v-if="activeStep === 1" ref="EvidenceExtractRef" @save="saveOk" />
<EvidenceConfirm v-if="activeStep === 2" ref="EvidenceConfirmRef" />
</div>
</template>
<script>
import { baseURL } from '@/config'
import { commonDownloadFile } from '@/api/config/uploadApi'
import * as vuedraggable from 'vuedraggable'
import UploadEvidence from './components/UploadEvidence.vue'
import EvidenceExtract from './components/EvidenceExtract.vue'
import EvidenceConfirm from './components/EvidenceConfirm.vue'
export default {
name: 'EditEvidence',
components: { vuedraggable, UploadEvidence, EvidenceExtract, EvidenceConfirm },
data() {
return {
fileList: [],
actRecordImg: require('@/assets/record/act_record.png'),
actIdentifyImg: require('@/assets/record/act_identify.png'),
actUploadImg: require('@/assets/record/act_upload.png'),
identifyImg: require('@/assets/record/identify.png'),
uploadImg: require('@/assets/record/upload.png'),
activeStep: 0,
status: '1',
interval: undefined
}
},
mounted() {
},
methods: {
getImgUrl(id) {
return `${baseURL}${commonDownloadFile}${id}`
},
beforeUpload(file) {
const isLt5M = file.size / 1024 / 1024 < 5
const filename = file.name
const postfix = filename.substring(filename.lastIndexOf('.'))
if (!['.jpg', '.png'].includes(postfix)) {
this.$message.error('上传图片只能是 JPG,PNG 格式!')
return false
}
if (!isLt5M) {
this.$message.error('上传头像图片大小不能超过 5MB!')
return false
}
if (this.fileList >= 12) {
this.$message.error('上传文件数量不能超过12张!')
return false
}
return true
},
del(index) {
this.fileList.splice(index, 1)
},
handleSuccess(res, file) {
const obj = {
name: file.name,
fileId: res.data
}
this.fileList.push(obj)
this.imgOcrIdentify(res.data)
},
saveOk() {
this.activeStep += 1
},
async submit() {
}
}
}
</script>
<style scoped lang="scss">
.EditEvidence {
width: 100%;
height: 100%;
background: #fff;
display: flex;
flex-direction: column;
.step-list {
display: flex;
align-items: center;
width: 100%;
justify-content: center;
padding-top: 36px;
margin-bottom: 32px;
.step-list-item {
display: flex;
align-items: center;
span {
font-size: 20px;
color: #999999;
margin-left: 16px;
margin-right: 16px;
}
.actived {
color: #3763FF;
}
}
.step-line {
width: 137px;
height: 2px;
border-top: 2px dashed #999999;
display: flex;
position: relative;
margin-right: 42px;
span {
position: absolute;
right: -24px;
top: -11px;
color: #999999;
font-size: 16px;
}
}
.act-step-line {
width: 137px;
height: 2px;
border-top: 2px dashed #3763FF;
display: flex;
position: relative;
margin-right: 42px;
span {
position: absolute;
right: -24px;
top: -11px;
color: #3763FF;
font-size: 16px;
}
}
img {
width: 36px;
height: 36px;
}
}
}
</style>

@ -1,108 +1,56 @@
<template>
<div v-loading="loading" element-loading-text="识别中..." class="AddEvidence">
<div v-if="fileList.length === 0 && status === '1'" class="no-upload-main">
<el-upload
drag
:headers="{
token: token
}"
:action="uploadOption.action"
:accept="uploadOption.accept"
multiple
:on-success="handleSuccess"
:before-upload="beforeUpload"
:show-file-list="false"
class="drag-content"
>
<div class="upload-content">
<!-- <div>点击或将文件拖拽到这里上传</div>
<div>支持PNGJPGJPEGBMPWEBP图片格式OCR转换一次可以处理12张</div>
<el-button type="primary" icon="el-icon-upload2" style="margin-top: 10px">点击上传</el-button> -->
<img src="@/assets/record/upload_content.png" alt="">
<div class="upload-content-main">
<span class="title">点击或将文件拖拽到这里上传</span>
<span class="desc">支持PNGJPGJPEG图片格式OCR转换一次可以处理12张</span>
</div>
</div>
</el-upload>
</div>
<div v-if=" fileList.length > 0&& status === '1'" class="handle-upload-main">
<el-upload
drag
:headers="{
token: token
}"
:action="uploadOption.action"
:accept="uploadOption.accept"
multiple
:on-success="handleSuccess"
:before-upload="beforeUpload"
:show-file-list="false"
class="handle-drag-content"
>
<div class="upload-content-main">
<span class="title">点击或将文件拖拽到这里上传</span>
<span class="desc">支持PNGJPGJPEG图片格式OCR转换一次可以处理12张</span>
<div class="up-btn">
<img src="@/assets/record/upload_btn.png" alt="">
<span>选择文件</span>
</div>
</div>
</el-upload>
<div class="upload-list">
<vuedraggable v-model="fileList" animation="400" class="img_list">
<!-- <transition-group> -->
<div v-for="(item,index) in fileList" :key="index" class="img_item">
<!-- <img :src="getImgUrl(item.id)" alt=""> -->
<el-image
class="img_item_url"
:src="getImgUrl(item.fileId)"
:zoom-rate="1.2"
:max-scale="7"
:min-scale="0.2"
:preview-src-list="[getImgUrl(item.fileId)]"
fit="cover"
/>
<span>{{ item.name }}</span>
<img class="del" @click="del(index)" src="@/assets/record/del_img.png" alt="">
</div>
<!-- </transition-group> -->
</vuedraggable>
<div class="AddEvidence">
<div class="step-list">
<div class="step-list-item">
<img :src="actUploadImg" alt="">
<span class="actived">证据上传并归档</span>
</div>
<div :class="[activeStep > 0 ?'act-step-line':'step-line']">
<span>>></span>
</div>
<div class="step-list-item">
<img v-if="activeStep > 0" :src="actIdentifyImg" alt="">
<img v-else :src="identifyImg" alt="">
<span :class="[activeStep > 0 ?'actived':'']">证据识别并提取</span>
</div>
<div :class="[activeStep > 0 ?'act-step-line':'step-line']">
<span>>></span>
</div>
<div class="step-list-item">
<img v-if="activeStep > 1" :src="actUploadImg" alt="">
<img v-else :src="uploadImg" alt="">
<span :class="[activeStep > 1 ?'actived':'']">证据确认</span>
</div>
<div class="submit-btn" @click="submit"></div>
</div>
<EvidenceProofread v-if="status ==='2'" :file-list="fileList" />
<UploadEvidence v-show="activeStep === 0" ref="UploadEvidenceRef" @save="saveOk" />
<EvidenceExtract v-if="activeStep === 1" ref="EvidenceExtractRef" @save="saveOk" />
<EvidenceConfirm v-if="activeStep === 2" ref="EvidenceConfirmRef" />
</div>
</template>
<script>
import { baseURL } from '@/config'
import { getAccessToken } from '@/utils/accessToken'
import { commonDownloadFile } from '@/api/config/uploadApi'
import * as vuedraggable from 'vuedraggable'
import EvidenceProofread from './EvidenceProofread.vue'
import { submitOrcTask, retrieveTitle, retrieveTitleProcess } from '@/api/caseDetails/ocr'
import UploadEvidence from './components/UploadEvidence.vue'
import EvidenceExtract from './components/EvidenceExtract.vue'
import EvidenceConfirm from './components/EvidenceConfirm.vue'
export default {
name: 'AddEvidence',
components: { vuedraggable, EvidenceProofread },
components: { vuedraggable, UploadEvidence, EvidenceExtract, EvidenceConfirm },
data() {
return {
fileList: [],
actRecordImg: require('@/assets/record/act_record.png'),
actIdentifyImg: require('@/assets/record/act_identify.png'),
actUploadImg: require('@/assets/record/act_upload.png'),
identifyImg: require('@/assets/record/identify.png'),
uploadImg: require('@/assets/record/upload.png'),
activeStep: 0,
recordId: '',
status: '1',
loading: false,
//
uploadOption: {
action: `${baseURL}/minio/uploadFile`,
accept: '.bmp,.jpg,.png'
},
interval: undefined,
token: getAccessToken()
interval: undefined
}
},
beforeDestroy() {
clearInterval(this.interval) //
},
mounted() {
},
@ -119,11 +67,7 @@ export default {
return false
}
if (!isLt5M) {
this.$message.error('上传头像图片大小不能超过 5MB!')
return false
}
if (this.fileList >= 12) {
this.$message.error('上传文件数量不能超过12张!')
this.$message.error('上传图片大小不能超过 5MB!')
return false
}
return true
@ -139,34 +83,13 @@ export default {
this.fileList.push(obj)
this.imgOcrIdentify(res.data)
},
//
imgOcrIdentify(id) {
submitOrcTask({ fileId: id })
},
//
queryProcess() {
const list = []
this.fileList.forEach(e => {
list.push(e.fileId)
})
retrieveTitleProcess(list).then(res => {
if (res.code === 200 && res.data === true) {
this.loading = false
this.status = '2'
clearInterval(this.interval)
}
})
saveOk(val) {
this.activeStep += 1
this.recordId = val
this.$route.query.recordId = val
},
async submit() {
const list = []
this.fileList.forEach(e => {
list.push(e.fileId)
})
this.loading = true
const res = await retrieveTitle(list)
if (res.code === 200) {
this.interval = setInterval(this.queryProcess, 3000)
}
}
}
}
@ -174,184 +97,65 @@ export default {
<style scoped lang="scss">
.AddEvidence {
display: flex;
background: #FFFFFF;
height: 100%;
.no-upload-main {
margin: auto 270px;
flex: 1;
border: 1px dashed #3763FF;
display: flex;
align-items: center;
justify-content: center;
height: calc(100vh - 400px);
.drag-content {
.upload-content {
position: relative;
display: flex;
align-items: center;
justify-content: center;
img {
width: 463px;
height:361px ;
}
.upload-content-main {
position: absolute;
top: 200px;
display: flex;
flex-direction: column;
.title {
font-size: 20px;
color: #333333;
}
.desc {
font-size: 16px;
color: #999999;
margin-top: 12px;
}
}
}
}
}
.handle-upload-main {
width: 100%;
height: 100%;
background: #fff;
display: flex;
flex-direction: column;
margin-top: 16px;
flex: 1;
// align-items: center;
justify-content: center;
height: calc(100vh - 330px);
padding: 0 26px;
.handle-drag-content {
height: 240px;
border: 1px dashed transparent;
background: linear-gradient(#fff,#fff) padding-box,
repeating-linear-gradient(-45deg,#3763FF 0, #3763FF 0.3em, #fff 0,#fff 0.6em);
.step-list {
display: flex;
width: 100%;
align-items: center;
width: 100%;
justify-content: center;
margin-bottom: 16px;
::v-deep {
.el-upload-dragger {
border: 0;
}
}
.upload-content-main {
padding-top: 36px;
margin-bottom: 32px;
.step-list-item {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.title {
font-size: 20px;
color: #333333;
span {
font-size: 20px;
color: #999999;
margin-left: 16px;
margin-right: 16px;
}
.desc {
font-size: 16px;
color: #999999;
margin-top: 12px;
.actived {
color: #3763FF;
}
.up-btn {
margin-left: 16px;
display: flex;
align-items: center;
justify-content: center;
width: 122px;
height: 42px;
background: #3763FF;
border-radius: 6px 6px 6px 6px;
cursor: pointer;
font-size: 16px;
color: #FFFFFF;
margin-top: 32px;
img {
width: 20px;
height: 20px;
margin-right: 6px;
}
}
.step-line {
width: 137px;
height: 2px;
border-top: 2px dashed #999999;
display: flex;
position: relative;
margin-right: 42px;
span {
position: absolute;
right: -24px;
top: -11px;
color: #999999;
font-size: 16px;
}
}
.act-step-line {
width: 137px;
height: 2px;
border-top: 2px dashed #3763FF;
display: flex;
position: relative;
margin-right: 42px;
span {
position: absolute;
right: -24px;
top: -11px;
color: #3763FF;
font-size: 16px;
}
}
img {
width: 36px;
height: 36px;
}
}
.upload-list {
flex: 1;
width: 100%;
border: 1px dashed transparent;
background: linear-gradient(#fff,#fff) padding-box,
repeating-linear-gradient(-45deg,#3763FF 0, #3763FF 0.3em, #fff 0,#fff 0.6em);
.img_list {
display: flex;
flex-wrap: wrap;
padding: 24px 0 0 24px;
.img_item {
display: flex;
flex-direction: column;
margin-right: 16px;
margin-bottom: 16px;
position: relative;
.img_item_url {
width: 136px;
height: 190px;
border-radius: 6px 6px 6px 6px;
border: 1px solid #D1D3D6;
margin-bottom: 8px;
cursor: move;
}
span {
font-size: 16px;
color: #333333;
word-break: break-all;
}
.del {
position: absolute;
width: 24px;
height: 24px;
right: 8px;
top: 8px;
display: none;
cursor: pointer;
}
}
.img_item:hover {
.del {
display: block;
}
}
}
}
.submit-btn {
position: absolute;
bottom: 16px;
right: 16px;width: 188px;
height: 48px;
background: #3763FF;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.04);
border-radius: 6px 6px 6px 6px;font-size: 16px;
color: #FFFFFF;
text-align: center;
line-height: 48px;
cursor: pointer;
}
}
::v-deep {
.el-upload {
width: 100%;
}
.el-upload-dragger {
width: 100%;
height: 100%;
}
.el-steps--simple {
padding: 0;
background: none;
}
.el-step.is-simple .el-step__title {
font-size: 14px;
}
}
}
</style>

@ -2,16 +2,31 @@
<template>
<div class="evidence-content">
<div class="evidence-tree">
11
<el-tree
ref="tree"
node-key="id"
:data="treeData"
current-node-key="1"
:props="defaultProps"
highlight-current
default-expand-all
@node-click="handleNodeClick"
/>
</div>
<div class="evidence-main">
<div v-if="isEdit" class="flex-row" style="align-items: center; justify-content: space-between">
<div>
<el-button type="primary" icon="el-icon-folder-add" @click="addFolder"></el-button>
<el-button type="primary" icon="el-icon-circle-plus-outline" @click="handleAdd"></el-button>
<el-button type="primary" icon="el-icon-circle-plus-outline" @click="addEvidence"></el-button>
</div>
<el-input v-model="searchName" placeholder="搜索名称" style="width: 300px" />
<!-- <el-input v-model="searchName" placeholder="搜索名称" style="width: 300px" /> -->
</div>
<div class="nav-list">
<div v-for="(item,index) in navList" :key="index" class="nav-item">
<span>{{ item }}</span>
<span v-if="index !== navList.length -1">></span>
</div>
</div>
<vxe-grid v-bind="gridOptions" style="margin-top: 10px">
<template #opera="{row}">
@ -28,7 +43,7 @@
/>
</div>
</div>
<AddFolder ref="AddFolderRef" @addOk="getTreeList" />
<!--编辑/新增证据-->
<!-- <edit-evidence ref="edit" @onClose="fetchData" /> -->
<!--选择上传笔录方式-->
@ -40,12 +55,14 @@
import mixin from '@/views/mixin'
import EditEvidence from '@/views/caseDetails/components/edit/EditEvidence.vue'
import AddFolder from './AddEvidence/AddFolder.vue'
import { queryEvidenceList, deleteEvidence } from '@/api/caseDetails'
import { debounce } from '@/utils'
import { getCaseEvidenceFileTree, getCaseEvidenceDirectoryList } from '@/api/caseDetails/evidence'
import SelectUploadType from './SelectUploadType.vue'
export default {
name: 'CaseEvidence',
components: { EditEvidence, SelectUploadType },
components: { EditEvidence, SelectUploadType, AddFolder },
mixins: [mixin],
props: {
//
@ -73,6 +90,13 @@ export default {
{ title: '操作', slots: { default: 'opera' }, fixed: 'right', width: '100px' }
],
data: [{}]
},
treeData: [],
selectId: '',
navList: ['全部'],
defaultProps: {
children: 'child',
label: 'directoryName'
}
}
},
@ -80,7 +104,7 @@ export default {
isExpand: {
handler: function(newVal, oldVal) {
if (newVal !== oldVal) {
this.tableHeight(this.isExpand ? this.isEdit ? 580 : 530 : this.isEdit ? 400 : 320)
this.tableHeight(this.isExpand ? this.isEdit ? 630 : 580 : this.isEdit ? 450 : 370)
}
},
immediate: true
@ -92,8 +116,9 @@ export default {
mounted() {
this.caseId = this.$route.params.id
this.$nextTick(() => {
this.tableHeight(this.isExpand ? (this.isEdit ? 580 : 530) : (this.isEdit ? 400 : 320))
this.tableHeight(this.isExpand ? (this.isEdit ? 630 : 580) : (this.isEdit ? 450 : 370))
})
this.getTreeList()
this.fetchData()
},
methods: {
@ -102,7 +127,11 @@ export default {
_this.fetchData()
}),
addFolder() {
this.$refs.AddFolderRef.show()
},
//
addEvidence() {
this.$router.push({ path: `/add-evidence/${this.caseId}`, query: { caseName: this.$route.params.caseName, caseNo: this.$route.query.caseNo }})
},
//
fetchData() {
@ -110,13 +139,49 @@ export default {
caseId: this.caseId,
evidenceName: this.searchName,
pageNum: this.queryForm.page,
pageSize: this.queryForm.size
pageSize: this.queryForm.size,
directoryId: this.selectId === '1' ? '' : this.selectId
}
queryEvidenceList(params).then(res => {
this.gridOptions.data = res.data.records
this.queryForm.total = res.data.total
})
},
//
getTreeList() {
getCaseEvidenceFileTree({ caseId: this.caseId }).then(res => {
if (res.code === 200) {
this.treeData = res.data
this.treeData.unshift({
directoryName: '全部',
id: '1'
})
// this.$refs.tree.setCurrentKey(this.treeData[0].id)
}
})
},
getParentNames(node, treeData, parentNames = []) {
//
const parent = treeData.find(parentNode =>
parentNode.child && parentNode.child.some(child => child.id === node.id)
)
//
if (parent) {
parentNames.push(parent.directoryName)
return this.getParentNames(parent, treeData, parentNames)
}
//
return parentNames
},
handleNodeClick(data) {
this.selectId = data.id
this.navList = []
this.navList = this.getParentNames(data, this.treeData)
this.navList.push(data.directoryName)
this.fetchData()
},
//
handleAdd() {
// this.$refs.edit.show()
@ -151,10 +216,42 @@ export default {
.evidence-content {
display: flex;
.evidence-tree {
width: 200px;
width: 210px;
margin-right: 16px;
background: #F9FAFB;
::v-deep {
.el-tree {
background: #F9FAFB;
.el-tree-node {
// height: 40px;
font-size: 16px;
color: #333333;
}
.el-tree-node__content {
height: 40px;
}
.el-tree-node.is-current > .el-tree-node__content {
background: #dce3ed;
color: #666666;
}
}
}
}
.evidence-main {
flex: 1;
}
.nav-list {
display: flex;
font-size: 16px;
color: #333333;
margin-bottom: 16px;
margin-top: 24px;
.nav-item {
display: flex;
span {
margin-right: 16px;
}
}
}
}
</style>

@ -1,101 +1,32 @@
<template>
<div class="EditEvidence">
<div class="EvidenceProofread">
<div class="FormInfo">
<el-form ref="form" :model="dataInfo" :rules="rules" label-width="100px" style="margin-top: 10px">
<el-row :gutter="10" class="form-content">
<el-col :span="24">
<el-form-item label="案件编号">
<span>{{ caseNo }}</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="案件名称">
<span>{{ caseName }}</span>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="证据名称" prop="evidenceName">
<el-input v-model="dataInfo['evidenceName']" placeholder="请输入证据名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="证据类型" prop="evidenceType">
<el-select v-model="dataInfo['evidenceType']" style="width: 100%" placeholder="请选择证据类型">
<el-option
v-for="item in evidenceTypeList"
:key="item.value"
:value="item.value"
:label="item.label"
/>
</el-select></el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="提供人" prop="provider">
<el-input v-model="dataInfo.property['provider']" placeholder="请输入提供人" />
</el-form-item>
</el-col>
<div class="expand" @click="handleExpand">
<span v-show="isExpand"></span>
<span v-show="!isExpand"></span>
<img v-show="isExpand" :src="expandImg" alt="">
<img v-show="!isExpand" :src="unExpandImg" alt="">
<span class="line" />
</div>
<div v-show="isExpand">
<el-col :span="24">
<el-form-item label="受害人" prop="victim">
<el-input v-model="dataInfo.property['victim']" placeholder="请输入受害人名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="合同标的物" prop="contractSubject">
<el-input v-model="dataInfo.property['contractSubject']" placeholder="请输入合同标的物" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="合同签订时间" prop="contractSignTime">
<el-date-picker
v-model="dataInfo.property['contractSignTime']"
type="datetime"
format="yyyy-MM-dd HH:MM:ss"
value-format="yyyy-MM-dd HH:MM:ss"
placeholder="请选择合同签订时间"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="金额" prop="amount">
<el-input v-model="dataInfo.property['amount']" type="number" placeholder="请输入金额" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="证据结果" prop="evidenceResult">
<el-input v-model="dataInfo.property['evidenceResult']" placeholder="请输入证据结果" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="其他" prop="otherDesc">
<el-input
v-model="dataInfo.property.otherDesc"
row
type="textarea"
/>
</el-form-item>
</el-col>
</div>
</el-row>
</el-form>
<div class="header">
<div class="title">
<span>{{ `案件名称:${caseName}` }}</span>
<span>{{ `案件编号:${caseNo}` }}</span>
</div>
<div class="proofread-content">
</div>
<div class="proofread-content">
<div class="mid-content">
<div class="left">
<div class="show-img">
<img :src="activedImg" alt="">
</div>
<el-scrollbar v-if="selectList.length > 0" class="left-scroll">
<vuedraggable v-model="selectList" animation="400" class="img_list">
<div v-for="(item,index) in selectList" :key="index" :class="[item.fileId === selectInfo.fileId?'actived':'']">
<img v-if="['jpg', 'png'].includes(item.fileType)" class="img_item" :src="getImgUrl(item.fileId)" @click="selectItem(item)">
</img>
<svg-icon v-if="[ 'doc', 'docx'].includes(item.fileType)" class="svg-img" icon-class="docx" />
</div>
</vuedraggable>
</el-scrollbar>
<div v-if="selectList.length > 0 && ['jpg', 'png'].includes(selectInfo.fileType)" class="act_img">
<img v-if="selectInfo.fileId" :src="getImgUrl(selectInfo.fileId)" alt="">
</div>
<div v-if="selectList.length === 0" class="empty-content">
<img src="@/assets/caseManagement/empty.png" alt="">
<span>暂无本次证据材料</span>
</div>
<span class="boder1" />
<span class="boder2" />
<span class="boder3" />
@ -104,8 +35,7 @@
<div class="right">
<div class="title">识别结果</div>
<el-input
v-model="dataInfo.ocrText"
readonly
v-model="selectInfo.ocrText"
class="right-text"
type="textarea"
/>
@ -115,11 +45,30 @@
<span class="boder4" />
</div>
</div>
<div class="footer-btns">
<div class="reset_btn" @click="reset"></div>
<div class="btn" @click="submit"></div>
<div class="FormInfo">
<el-form ref="form" :model="selectInfo" :rules="rules" label-width="100px" style="margin-top: 10px">
<el-row :gutter="10" class="form-content">
<el-col :span="24">
<el-form-item label="证据名称" prop="title">
<el-input v-model="selectInfo.evidenceInfo.title" placeholder="请输入证据名称" />
</el-form-item>
</el-col>
</el-row>
<el-row v-if="selectInfo.evidenceInfo.property" :gutter="10" class="form-content">
<el-col v-for="(item,index) in selectInfo.evidenceInfo.property" :key="index" :span="24">
<el-form-item :label="item.attrName">
<el-input v-if="item.attrValueType ==='text'" v-model="item.attrValue" placeholder="请输入" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
</div>
<div class="footer-btns">
<div class="btn" @click="submit"></div>
<div class="reset_btn" @click="reset"></div>
</div>
</div>
</template>
@ -127,249 +76,375 @@
import * as vuedraggable from 'vuedraggable'
import { baseURL } from '@/config'
import { commonDownloadFile } from '@/api/config/uploadApi'
import { queryEvidenceInfo, updateEvidence } from '@/api/caseDetails/ocr'
import { ocrAndExtractDetails, caseEvidenceVerify } from '@/api/caseDetails/evidence'
export default {
name: 'EvidenceProofread',
name: 'EditEvidence',
components: { vuedraggable },
data() {
return {
dataList: [],
isExpand: true,
rules: {
evidenceName: [{ required: true, message: '证据名称不能为空!', trigger: 'blur' }],
evidenceType: [{ required: true, message: '证据类型不能为空!', trigger: 'blur' }]
},
//
evidenceTypeList: JSON.parse(sessionStorage.getItem('evidence_type')),
expandImg: require('@/assets/record/expand.png'),
unExpandImg: require('@/assets/record/unExpand.png'),
selectList: [],
activedImg: '',
caseNo: '',
caseName: '',
dataInfo: {
fileId: '',
ocrText: '',
property: {}
dataInfo: {},
//
evidenceTypeList: JSON.parse(sessionStorage.getItem('evidence_type')),
rules: {
title: [{ required: true, message: '证据名称不能为空!', trigger: 'blur' }]
},
activedImg: ''
flag: true,
treeData: [],
selectInfo: {
evidenceInfo: {
property: [],
title: ''
},
ocrText: ''
}
}
},
mounted() {
this.getTreeList()
this.caseNo = this.$route.query.caseNo
this.caseName = this.$route.query.caseName
this.getData()
},
methods: {
getImgUrl(id) {
return `${baseURL}${commonDownloadFile}${id}`
},
handleExpand() {
this.isExpand = !this.isExpand
},
getData() {
queryEvidenceInfo({ evidenceId: this.$route.query.evidenceId }).then(res => {
this.dataInfo = res.data
this.dataInfo.fileId = res.data.fileList[0].fileId
this.dataInfo.ocrText = res.data.fileList[0].ocrText
this.activedImg = `${baseURL}${commonDownloadFile}${this.dataInfo.fileId}`
})
selectItem(item) {
this.selectInfo = item
this.activedImg = `${baseURL}${commonDownloadFile}${this.selectInfo.fileId}`
},
reset() {
this.getData()
this.getTreeList()
},
submit() {
const loading = this.$baseLoading(1, '保存中...')
this.dataInfo.caseId = this.$route.params.id
this.dataInfo.fileIdList = [this.dataInfo.fileList[0].fileId]
updateEvidence(this.dataInfo).then(res => {
loading.close()
getTreeList() {
ocrAndExtractDetails({ caseId: this.$route.params.id, evidenceId: this.$route.query.evidenceId }).then(res => {
if (res.code === 200) {
this.$store.dispatch(
'tabsBar/delRoute',
this.$route
)
this.$router.push({ path: `/case-details/${this.$route.params.id}/${this.$route.query.caseName}`, query: { currentKey: '1-2', isEdit: 1 }})
this.treeData = res.data
this.$nextTick(() => {
this.handleNodeClick(res.data[0])
})
}
})
},
findNodeById(nodes, id) {
for (const node of nodes) {
if (node.id === id) {
return node
} else if (node.child) {
const foundNode = this.findNodeById(node.child, id)
if (foundNode) {
return foundNode
}
}
}
return null
},
// list
getFileList(nodes) {
for (const node of nodes) {
if (node.fileInfoList.length > 0) {
return node
} else if (node.child) {
const foundNode = this.getFileList(node.child)
if (foundNode) {
return foundNode
}
}
}
return null
},
handleNodeClick(data) {
this.selectId = data.id
const nodeItem = this.findNodeById(this.treeData, this.selectId)
if (nodeItem.fileInfoList.length === 0) {
const newNodeItem = this.getFileList(nodeItem.child)
this.selectList = newNodeItem.fileInfoList
this.selectId = newNodeItem.id
this.selectInfo = this.selectList[0]
} else {
this.selectList = nodeItem.fileInfoList
this.selectInfo = this.selectList[0]
this.selectId = nodeItem.id
}
console.log('111', this.selectList, this.selectInfo)
},
checkEvidence(nodes) {
for (const item of nodes) {
if (item.fileInfoList.length > 0) {
for (let i = 0; i < item.fileInfoList.length; i++) {
if (!item.fileInfoList[i].evidenceInfo.title) {
this.handleNodeClick(item)
this.selectItem(item.fileInfoList[i])
this.flag = false
break
}
}
} else if (item.child) {
this.checkEvidence(item.child)
}
}
},
save() {
this.checkEvidence(this.treeData)
if (this.flag) {
caseEvidenceVerify({
batchNo: this.$route.query.recordId,
caseId: this.$route.params.id,
evidenceDirectoryList: this.treeData
}).then(res => {
if (res.code === 200) {
this.$baseMessage.success(res.msg || '保存成功!')
this.$store.dispatch(
'tabsBar/delRoute',
this.$route
)
this.$router.push({ path: `/case-details/${this.$route.params.id}/${this.$route.query.caseName}`, query: { isEdit: 1, caseNo: this.$route.query.caseNo }})
}
})
} else {
this.$baseMessage.error('证据不能为空!')
}
},
submit() {
this.save()
}
}
}
</script>
<style lang="scss" scoped>
.EditEvidence {
display: flex;
background: #FFFFFF;
height: 100%;
.EvidenceProofread {
display: flex;
margin: 24px;
width: 100%;
.FormInfo {
width: 470px;
background: #F6F8F9;
border-radius: 8px 8px 8px 8px;
// height: calc(100vh - 350px);
padding: 0 24px;
margin-bottom: 72px;
.expand {
<style lang="scss" scoped>
.EditEvidence {
display: flex;
flex-direction: row-reverse;
padding: 0 24px;
align-items: center;
cursor: pointer;
margin-bottom: 16px;
img {
width: 18px;
height: 18px;
margin-right: 8px;
}
.line {
flex: 1;
height: 1px;
background: #E9E9E9;
margin-right: 8px;
}
flex-direction: column;
background: #fff;
height: 100%;
:deep(.el-scrollbar__wrap) {
overflow-x: hidden;
}
}
:deep(.el-scrollbar__wrap) {
overflow-x: hidden;
}
.proofread-content {
flex: 1;
margin-left: 18px;
display: flex;
margin-bottom: 72px;
.left {
width: 55%;
margin-right: 24px;
position: relative;
// background: #F6F8F9;
border: 1px solid #DCE3EB;
display: flex;
padding: 8px;
.show-img {
padding: 16px 28px;
flex: 1;
background: #F6F8F9;
img {
width: 100%;
height: 100%;
.proofread-content {
flex: 1;
margin-left: 18px;
display: flex;
.mid-content {
display: flex;
flex: 1;
.left {
margin-right: 24px;
position: relative;
// background: #F6F8F9;
border: 1px solid #DCE3EB;
display: flex;
padding: 8px;
.empty-content {
flex: 1;
padding: 24px;
display: flex;
margin-top: 16px;
flex-direction: column;
display: flex;
justify-content: center;
align-items: center;font-size: 16px;
color: #333333;
img {
width: 200px;
height: 200px;
}
}
.left-scroll {
background: #F6F8F9;
width: 150px;
margin-right: 14px;
}
.act_img {
padding: 16px 28px;
flex: 1;
background: #F6F8F9;
height: calc(100vh - 420px);
background-size: 100% 100%;
display: flex;
align-items: center;
justify-content: center;
img {
height: 100%;
}
}
.svg-img {
width: 98px;
height: 138px;
// margin-bottom: 16px;
border-radius: 6px 6px 6px 6px;
border: 1px solid #D1D3D6;
cursor: move;
}
.actived {
border: 2px solid #3763FF !important;
}
}
}
}
.right {
width: 45%;
position: relative;
border: 1px solid #DCE3EB;
display: flex;
padding: 8px;
flex-direction: column;
.title {
background: #F6F8F9;
border-bottom: 1px solid #DCE3EB;
height: 70px;
padding-left: 24px;
line-height: 70px;
font-weight: bold;
font-size: 18px;
color: #333333;
width: 100%;
}
::v-deep .el-textarea__inner {
height: calc(100vh - 450px);
border: none;
box-shadow: none;
.right {
flex: 1;
position: relative;
border: 1px solid #DCE3EB;
display: flex;
padding: 8px;
flex-direction: column;
.title {
background: #F6F8F9;
border-bottom: 1px solid #DCE3EB;
height: 70px;
padding-left: 24px;
line-height: 70px;
font-weight: bold;
font-size: 18px;
color: #333333;
}
.right-text {
width: 100%;
height: 500px;
}
}
}
.img_list {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 25px;
overflow-x: hidden;
padding: 24px;
}
.FormInfo {
width: 410px;
background: #F6F8F9;
.img_item {
width: 98px;
height: 138px;
margin-bottom: 16px;
border-radius: 6px 6px 6px 6px;
border: 1px solid #D1D3D6;
cursor: pointer;
border-radius: 8px 8px 8px 8px;
margin-left: 24px;
// height: calc(100vh - 350px);
padding: 0 24px;
margin-bottom: 72px;
.expand {
display: flex;
flex-direction: row-reverse;
padding: 0 24px;
align-items: center;
cursor: pointer;
margin-bottom: 16px;
img {
width: 18px;
height: 18px;
margin-right: 8px;
}
.line {
flex: 1;
height: 1px;
background: #E9E9E9;
margin-right: 8px;
}
}
}
.boder1 {
position: absolute;
width: 15px;
height: 15px;
left: 0;
top: 0;
border-top: 2px solid #2073FF;
border-left: 2px solid #2073FF;
}
.boder2 {
position: absolute;
width: 15px;
height: 15px;
right: 0;
top: 0;
border-top: 2px solid #2073FF;
border-right: 2px solid #2073FF;
.img_list {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 25px;
overflow-x: hidden;
padding: 24px;
background: #F6F8F9;
.img_item {
width: 98px;
height: 138px;
// margin-bottom: 16px;
border-radius: 6px 6px 6px 6px;
border: 1px solid #D1D3D6;
cursor: move;
}
}
.boder1 {
position: absolute;
width: 15px;
height: 15px;
left: 0;
top: 0;
border-top: 2px solid #2073FF;
border-left: 2px solid #2073FF;
}
.boder2 {
position: absolute;
width: 15px;
height: 15px;
right: 0;
top: 0;
border-top: 2px solid #2073FF;
border-right: 2px solid #2073FF;
}
.boder3 {
position: absolute;
width: 15px;
height: 15px;
left: 0;
bottom: 0;
border-bottom: 2px solid #2073FF;
border-left: 2px solid #2073FF;
}
.boder4 {
position: absolute;
width: 15px;
height: 15px;
right: 0;
bottom: 0;
border-bottom: 2px solid #2073FF;
border-right: 2px solid #2073FF;
}
}
.boder3 {
position: absolute;
width: 15px;
height: 15px;
left: 0;
bottom: 0;
border-bottom: 2px solid #2073FF;
border-left: 2px solid #2073FF;
.header {
display: flex;
justify-content: space-between;
padding-top: 24px;
.title {
// display: flex;
text-align: right;font-size: 16px;
color: #333333;
margin-bottom: 24px;
span {
margin-left: 32px;
}
}
}
.boder4 {
position: absolute;
width: 15px;
height: 15px;
right: 0;
bottom: 0;
border-bottom: 2px solid #2073FF;
border-right: 2px solid #2073FF;
.footer-btns {
padding-top: 24px;
height: 68px;
display: flex;
flex-direction: row-reverse;
.btn {
width: 188px;
height: 48px;
background: #3763FF;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.04);
border-radius: 6px 6px 6px 6px;
text-align: center;
line-height: 48px;
font-size: 16px;
color: #FFFFFF;
cursor: pointer;
margin-left: 24px;
}
.reset_btn {
width: 188px;
height: 48px;
background: #FFFFFF;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.04);
border-radius: 6px 6px 6px 6px;
border: 1px solid #3763FF;
text-align: center;
line-height: 48px;
font-size: 16px;
color: #3763FF;
cursor: pointer;
margin-left: 24px;
}
}
}
.footer-btns {
position: absolute;
right: 24px;
bottom: 24px;
display: flex;
.btn {
width: 188px;
height: 48px;
background: #3763FF;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.04);
border-radius: 6px 6px 6px 6px;
text-align: center;
line-height: 48px;
font-size: 16px;
color: #FFFFFF;
cursor: pointer;
margin-left: 24px;
}
.reset_btn {
width: 188px;
height: 48px;
background: #FFFFFF;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.04);
border-radius: 6px 6px 6px 6px;
border: 1px solid #3763FF;
text-align: center;
line-height: 48px;
font-size: 16px;
color: #3763FF;
cursor: pointer;
margin-left: 24px;
}
}
}
}
</style>
</style>
<style lang="scss" scoped>
::v-deep .el-textarea__inner {
height: calc(100vh - 450px);
border: none;
box-shadow: none;
}
</style>

@ -146,7 +146,6 @@ export default {
const loading = this.$baseLoading(1, '保存中...')
this.$refs.form.validate(valid => {
if (valid) {
const params = {
...this.evidenceForm,
caseId: this.$route.params.id

@ -334,6 +334,53 @@ export default {
height: 100%;
color: #333333;
box-sizing: border-box;
.info-left {
::v-deep {
.el-descriptions__body {
background: none;
}
.el-tree-node__content {
background: linear-gradient( 90deg, rgba(69, 105, 255, .1) 0%, #FFFFFF 100%);
border-radius: 5px;
height: 35px;
line-height: 35px;
margin-bottom: 10px;
.el-tree-node__expand-icon {
padding: 6px;
}
}
.el-tree-node__children{
margin-left: 10px;
border-left: 1px solid rgba(51, 51, 51, 0.20);
}
.el-tree-node__children .el-tree-node__content {
background: #FFFFFF;
padding-left: 0 !important;
margin-left: 8px;
}
.el-tree-node__children .el-tree-node__content .el-tree-node__expand-icon {
padding: 0;
}
.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
background: #3763FF;
color: white;
}
.el-descriptions-item__label {
font-weight: 400;
font-size: 16px;
color: #666666;
}
.el-descriptions-item__content {
font-weight: 400;
font-size: 16px;
color: #333333;
}
.el-descriptions--small:not(.is-bordered) .el-descriptions-item__cell {
padding-bottom: 16px !important;
}
}
}
.details-header {
padding: 10px;
box-sizing: border-box;
@ -471,32 +518,6 @@ export default {
.el-descriptions__body {
background: none;
}
.el-tree-node__content {
background: linear-gradient( 90deg, rgba(69, 105, 255, .1) 0%, #FFFFFF 100%);
border-radius: 5px;
height: 35px;
line-height: 35px;
margin-bottom: 10px;
.el-tree-node__expand-icon {
padding: 6px;
}
}
.el-tree-node__children{
margin-left: 10px;
border-left: 1px solid rgba(51, 51, 51, 0.20);
}
.el-tree-node__children .el-tree-node__content {
background: #FFFFFF;
padding-left: 0 !important;
margin-left: 8px;
}
.el-tree-node__children .el-tree-node__content .el-tree-node__expand-icon {
padding: 0;
}
.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
background: #3763FF;
color: white;
}
.el-descriptions-item__label {
font-weight: 400;
font-size: 16px;

@ -0,0 +1,182 @@
<template>
<cs-drawer
:drawer-option="drawerOption"
>
<div slot="content" class="PromptDebug">
<div class="left">
<div class="title">识别结果预览</div>
<div class="left-content">
<div class="top">证据模板买卖合同</div>
<!-- <div class="empty">
<img src="@/assets/common/file_empty.png" alt="">
<span>暂无结果请在右侧输入调试内容或上传文档</span>
</div> -->
</div>
</div>
<div class="right">
<div class="right-item">
<span>调试内容</span>
<el-input
v-model="textarea"
type="textarea"
:rows="8"
placeholder="请输入"
/>
</div>
<div class="right-item">
<span>选择文件</span>
<el-upload
:headers="{
token: token
}"
:action="uploadOption.action"
:accept="uploadOption.accept"
:data="{
temp: true
}"
:on-success="handleSuccess"
:before-upload="beforeUpload"
>
<div class="up-btn">
请选择文件
</div>
<div class="desc">支持上传扩展名为txtdocdocx文件且仅限一份文件</div>
</el-upload>
</div>
</div>
</div>
</cs-drawer>
</template>
<script>
import { baseURL } from '@/config'
import { getAccessToken } from '@/utils/accessToken'
export default {
name: 'PromptDebug',
data() {
return {
drawerOption: {
show: false,
title: '提示词调试',
width: '1200px',
hiddenFooter: true
},
textarea: '',
//
uploadOption: {
action: `${baseURL}/minio/uploadFile`,
accept: '.txt,.doc,.docx'
},
token: getAccessToken(),
fileId: '',
fileList: [],
dataInfo: undefined
}
},
methods: {
show(data) {
this.drawerOption.show = true
this.dataInfo = data
},
beforeUpload(file) {
const isLt5M = file.size / 1024 / 1024 < 5
const filename = file.name
const postfix = filename.substring(filename.lastIndexOf('.'))
if (!['.txt', '.doc', '.docx'].includes(postfix)) {
this.$message.error('上传图片只能是 txt,doc,docx 格式!')
return false
}
if (!isLt5M) {
this.$message.error('上传头像图片大小不能超过 5MB!')
return false
}
return true
},
handleSuccess(res, file) {
this.fileId = res.data
// const obj = {
// name: file.name,
// fileId: res.data
// }
// this.fileList.push(obj)
// this.imgOcrIdentify(res.data)
}
}
}
</script>
<style scoped lang="scss">
.PromptDebug {
display: flex;
padding: 16px;
overflow: auto;
.left {
width: 50%;
.title {
font-size: 18px;
color: #333333;
margin-bottom: 16px;
}
.left-content {
border-radius: 6px 6px 6px 6px;
border: 1px solid #D9D9D9;
width: 100%;
height: calc(100vh - 300px);
.empty {
margin: 260px auto;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
img {
width: 200px;
height: 200px;
}
span {
font-size: 16px;
color: #333333;
}
}
.top {
height: 53px;
background: #F2F6FA;font-size: 16px;
color: #888888;
line-height: 53px;
padding-left: 24px;
}
}
}
.right {
margin-left: 32px;
flex: 1;
.right-item {
display: flex;
flex-direction: column;
margin-top: 24px;
span {
font-size: 16px;
color: #333333;
margin-bottom: 16px;
}
.up-btn {
width: 128px;
height: 42px;
background: #FFFFFF;
border-radius: 6px 6px 6px 6px;
border: 1px solid #3763FF;
line-height: 42px;
font-size: 16px;
color: #3763FF;
cursor: pointer;
}
.desc {
font-size: 16px;
color: #B4B4B4;
margin-top: 16px;
}
}
}
}
</style>

@ -0,0 +1,831 @@
<template>
<div class="custom-at-box">
<div class="custom-textarea-box">
<div
ref="customInput"
:class="[
'custom-textarea custom-scroll',
{ 'show-word-limit': showWordLimit && maxlength },
{ 'custom-textarea-disabled': disabled },
]"
:contenteditable="!disabled"
:placeholder="placeholder"
@input="onInput($event)"
@keydown="onKeyDownInput($event)"
@paste="onPaste($event)"
@copy="onCopy($event)"
@click="showList(false)"
/>
<div v-if="showWordLimit && maxlength" class="custom-at-limit">
{{ inputValueLen }}/{{ maxlength }}
</div>
</div>
<div :key="`customInput${taskPanelIsInFullScreen}`">
<el-popover
ref="popoverRef"
v-model="showPopover"
trigger="click"
class="custom-select-box"
:append-to-body="taskPanelPopoverAppendToBody"
:style="{ top: popoverOffset + 'px' }"
@hide="hidePoppver"
>
<div
ref="customSelectContent"
class="custom-select-content custom-scroll"
>
<div
v-for="(item, index) in dataList"
:key="index"
:class="[
'custom-select-item',
{ hoverItem: selectedIndex === index },
]"
@click="handleClickOperatorItem(item)"
>
<div class="custom-select-item-content">
{{ item.name }}
</div>
</div>
</div>
</el-popover>
</div>
</div>
</template>
<script>
import Vue from 'vue'
export default {
props: {
// placeholder
placeholder: {
type: String,
default: '请输入...'
},
//
showWordLimit: {
type: Boolean,
default: false
},
//
disabled: {
type: Boolean,
default: false
},
//
maxlength: {
type: [Number, String],
default: '3000'
},
setRefresh: {
type: Object,
default: () => {}
},
//
value: {
type: String,
default: ''
}
},
data() {
return {
//
inputValueLen: 0,
top: '',
left: '',
message: '',
startOffset: 0,
// @dom
searSpan: null,
//
dataList: [
{
name: 'xxxx'
},
{
name: 'dddd'
}
],
// @
selectionIndex: 0,
// dom
dom: null,
// domindex
domIndex: 0,
// domchildNodesindex
childDomIndex: 0,
// dom
beforeDomVal: '',
//
showPopover: false,
//
popoverOffset: 0,
listInput: false,
listInputValue: '',
//
timer: null,
//
addDataLoad: false,
//
selectedIndex: 0
}
},
computed: {
//
model: {
get() {
return this.value
},
set(newValue) {
this.$emit('input', newValue)
if (this.$refs.customInput) {
this.$emit('inputText', this.$refs.customInput.textContent)
}
const nodeList = this.$refs.customInput.childNodes
const list = []
nodeList.forEach((e) => {
if (e.childNodes) {
e.childNodes.forEach(i => {
if (i.className === 'active-text') {
list.push({
jobNumber: i.getAttribute('data-id'),
name: i.textContent.replace(/{/g, '').replace(/\s/g, '')
})
}
})
}
if (e.className === 'active-text') {
list.push({
jobNumber: e.getAttribute('data-id'),
name: e.textContent.replace(/{/g, '').replace(/\s/g, '')
})
}
})
this.$emit('changeChosen', list)
}
},
taskPanelIsInFullScreen() {
return this.$store.getters.taskPanelIsInFullScreen
},
taskPanelPopoverAppendToBody() {
return this.$store.getters.taskPanelPopoverAppendToBody
}
},
mounted() {
this.setNativeInputValue()
},
methods: {
//
setNativeInputValue() {
if (this.$refs.customInput) {
if (this.value === this.$refs.customInput.innerHTML) return
this.$refs.customInput.innerHTML = this.value
this.inputValueLen = this.$refs.customInput.innerText.length
}
},
//
handleClickOperatorItem(item) {
this.addData(JSON.parse(JSON.stringify(item)))
this.$refs.customSelectContent.scrollTop = 0
this.selectedIndex = 0
this.showPopover = false
this.listInput = false
this.listInputValue = ''
},
//
hidePoppver() {
this.$refs.customSelectContent.scrollTop = 0
this.selectedIndex = 0
this.showPopover = false
this.listInput = false
this.listInputValue = ''
},
//
createAtDom(item) {
//
const dom = document.createElement('span')
dom.classList.add('active-text')
// contenteditablefalse
dom.setAttribute('contenteditable', 'false')
// iddom便
dom.setAttribute('data-id', item.name)
dom.innerHTML = `{${item.name}}&nbsp;`
return dom
},
//
addData(item) {
const spanElement = this.createAtDom(item)
const maxlength = Number(this.maxlength) || 3000
// @1
if (maxlength - this.inputValueLen < spanElement.innerText.length - 1) {
this.$message('剩余字数不足')
return
}
this.$refs.customInput.focus()
//
const selection = window.getSelection()
const range = selection.getRangeAt(0)
//
const nodes = Array.from(this.$refs.customInput.childNodes)
let insertNode = ''
//
let domIsCustomInputChild = true
if (nodes[this.domIndex].nodeType === Node.TEXT_NODE) {
insertNode = nodes[this.domIndex]
} else {
const childNodeList = nodes[this.domIndex].childNodes
insertNode = childNodeList[this.childDomIndex]
domIsCustomInputChild = false
}
// @
// <span>
const html = insertNode.textContent
//
const textLeft = document.createTextNode(
html.substring(0, this.selectionIndex - 1) + ''
)
const emptySpan = document.createElement('span')
//
if (insertNode) {
if (!textLeft.textContent) {
if (domIsCustomInputChild) {
this.$refs.customInput.insertBefore(emptySpan, insertNode)
} else {
nodes[this.domIndex].insertBefore(emptySpan, insertNode)
}
}
insertNode.parentNode.insertBefore(spanElement, insertNode.nextSibling)
// @
const textContent = insertNode.textContent.slice(
0,
-(1 + this.listInputValue.length)
)
if (!textContent && insertNode.nodeName === '#text') {
insertNode.remove()
} else {
insertNode.textContent = textContent
}
} else {
//
this.$refs.customInput.appendChild(spanElement)
}
// span
const nextNode = spanElement.nextSibling
range.setStart(
nextNode || spanElement.parentNode,
nextNode ? 0 : spanElement.parentNode.childNodes.length
)
range.setEnd(
nextNode || spanElement.parentNode,
nextNode ? 0 : spanElement.parentNode.childNodes.length
)
selection.removeAllRanges()
selection.addRange(range)
this.model = this.$refs.customInput.innerHTML
this.inputValueLen = this.$refs.customInput.innerText.length
this.showList(false)
},
//
isSelectAll() {
const selection = window.getSelection()
return selection.toString() === this.$refs.customInput.innerText
},
//
isSelect() {
try {
const selection = window.getSelection()
return selection.toString().length
} catch (error) {
return 0
}
},
//
onKeyDownInput(event) {
//
const currentLength = this.$refs.customInput.innerText.length
//
const maxLength = Number(this.maxlength) || 3000
//
if (currentLength >= maxLength) {
// keyCode
var keyCode = event.keyCode || event.which
// Ctrl
var ctrlKey = event.ctrlKey || event.metaKey // metaKey macOS Command
// Backspace8Delete46
var allowedKeys = [8, 46, 37, 38, 39, 40]
// Ctrl+ACtrl+CCtrl+V
const allowedCtrlKey = [65, 67, 86]
//
if (!allowedKeys.includes(keyCode) && !this.isSelect()) {
if ((allowedCtrlKey.includes(keyCode) && ctrlKey)) {
return
}
//
event.preventDefault()
return false
}
}
if (this.showPopover) {
const listElement = this.$refs.customSelectContent
const itemHeight = listElement.children[0].clientHeight
if (event.key === 'ArrowDown') {
//
event.preventDefault()
//
if (this.selectedIndex === this.dataList.length - 1) {
this.selectedIndex = 0 //
listElement.scrollTop = 0 //
} else {
this.selectedIndex++
const itemBottom = (this.selectedIndex + 1) * itemHeight
const scrollBottom = listElement.scrollTop + listElement.clientHeight
if (itemBottom > scrollBottom) {
listElement.scrollTop += itemHeight
}
}
} else if (event.key === 'ArrowUp') {
event.preventDefault()
if (this.selectedIndex === 0) {
this.selectedIndex = this.dataList.length - 1 //
listElement.scrollTop = listElement.scrollHeight //
} else {
this.selectedIndex--
const itemTop = this.selectedIndex * itemHeight
if (itemTop < listElement.scrollTop) {
listElement.scrollTop -= itemHeight
}
}
} else if (event.key === 'Enter') {
event.preventDefault()
this.handleClickOperatorItem(
this.dataList[this.selectedIndex]
)
}
} else if (event.key === 'Backspace' && this.isSelectAll()) {
//
this.$refs.customInput.innerText = ''
this.model = this.$refs.customInput.innerHTML
this.inputValueLen = 0
}
},
//
onInput(e) {
this.inputValueLen = this.$refs.customInput.innerText.length
if (
['<div><br></div>', '<br>', '<span></span><br>'].includes(
this.$refs.customInput.innerHTML
)
) {
this.$refs.customInput.innerHTML = ''
this.inputValueLen = 0
} else if (e.data === '{') {
//
this.saveIndex()
this.showList()
this.listInput = true
} else if (this.showPopover) {
const { diffChars } = Vue.internal
const diffResult = diffChars(
this.beforeDomVal,
this.dom.textContent
)
let result = ''
//
for (let i = 0; i < diffResult.length; i++) {
const change = diffResult[i]
//
if (change.added) {
result += change.value
} else if (change.removed && change.value === '{') {
this.showList(false)
this.listInputValue = ''
}
}
if (this.timer) {
clearTimeout(this.timer)
}
this.listInputValue = result
this.timer = setTimeout(() => {
this.remoteMethod()
}, 300)
}
this.model = this.$refs.customInput.innerHTML
},
onPaste(event) {
event.preventDefault()
// HTML
const html = (event.clipboardData || window.clipboardData).getData(
'text/html'
)
const text = (event.clipboardData || window.clipboardData).getData(
'text/plain'
)
//
const maxLength = Number(this.maxlength) || 3000
//
const selection1 = window.getSelection()
const range1 = selection1.getRangeAt(0)
const clonedSelection = range1.cloneContents()
let selectTextLen = 0
if (clonedSelection.textContent && clonedSelection.textContent.length) {
selectTextLen = clonedSelection.textContent.length
}
//
const remainingLength = maxLength - this.inputValueLen + selectTextLen
//
const cleanText = text.replace(/\s/g, '')
// div HTML
const tempDiv = document.createElement('div')
tempDiv.innerHTML = html
//
const fragment = document.createDocumentFragment()
let totalLength = 0
if (cleanText) {
if (remainingLength >= cleanText.length) {
fragment.appendChild(document.createTextNode(cleanText))
} else {
const truncatedText = cleanText.substr(0, remainingLength)
fragment.appendChild(document.createTextNode(truncatedText))
}
} else {
Array.from(tempDiv.childNodes).forEach((node) => {
const regex = /<span class="active-text" contenteditable="false" data-id="(\d+)">{([^<]+)<\/span>/g
//
if (
node.nodeType !== 8 &&
!(node.nodeType === 3 && !/\S/.test(node.textContent))
) {
const childText = node.textContent || ''
const childLength = childText.length
const childHtml = node.outerHTML || node.innerHTML
//
if ((regex.exec(childHtml) !== null) && totalLength + childLength <= remainingLength) {
fragment.appendChild(node.cloneNode(true))
totalLength += childLength
} else if (remainingLength - totalLength > 0) {
//
const lastNodeLength = remainingLength - totalLength
const truncatedText = childText.substr(0, lastNodeLength)
fragment.appendChild(document.createTextNode(truncatedText))
totalLength += truncatedText.length
} else {
//
return
}
}
})
}
//
const selection = window.getSelection()
const range = selection.getRangeAt(0)
range.deleteContents()
range.insertNode(fragment)
//
this.model = this.$refs.customInput.innerHTML
this.inputValueLen = this.$refs.customInput.innerText.length
//
const newRange = document.createRange()
newRange.setStart(range.endContainer, range.endOffset)
newRange.collapse(true)
selection.removeAllRanges()
selection.addRange(newRange)
},
//
onCopy(e) {
e.preventDefault()
const selection = window.getSelection()
const range = selection.getRangeAt(0)
const clonedSelection = range.cloneContents()
//
const hasActiveText =
clonedSelection.querySelector(
'.active-text[contenteditable="false"][data-id]'
) !== null
const clipboardData = e.clipboardData || window.clipboardData
if (hasActiveText) {
const div = document.createElement('div')
div.appendChild(clonedSelection)
const selectedHtml = div.innerHTML
clipboardData.setData('text/html', selectedHtml)
} else {
clipboardData.setData('text/plain', clonedSelection.textContent || '')
}
},
//
async saveIndex() {
const selection = getSelection()
this.selectionIndex = selection.anchorOffset
const nodeList = this.$refs.customInput.childNodes
const range = selection.getRangeAt(0)
// dom
for (const [index, value] of nodeList.entries()) {
// truebug
// (range.startContainer.contains(value) && range.endContainer.contains(value))
if (
selection.containsNode(value, true) ||
(range.startContainer.contains(value) &&
range.endContainer.contains(value))
) {
if (value.nodeType === Node.TEXT_NODE) {
this.dom = value
this.beforeDomVal = value.textContent
this.domIndex = index
const selection = window.getSelection()
const range = selection.getRangeAt(0)
this.startOffset = range.startOffset - 1
} else {
const childNodeList = value.childNodes
for (const [childIndex, childValue] of childNodeList.entries()) {
if (selection.containsNode(childValue, true)) {
this.dom = value
this.beforeDomVal = value.textContent
this.domIndex = index
this.childDomIndex = childIndex
const selection = window.getSelection()
const range = selection.getRangeAt(0)
this.startOffset = range.startOffset - 1
}
}
}
}
}
},
//
showList(bool = true) {
this.showPopover = bool
if (bool) {
const offset =
this.getCursorDistanceFromDivBottom(this.$refs.customInput) || -1
if (offset < 0) {
this.popoverOffset = 0
} else {
this.popoverOffset = -(offset - 1)
}
}
if (!bool) {
this.listInputValue = ''
this.remoteMethod()
}
},
//
getCursorDistanceFromDivBottom(editableDiv) {
//
const selection = window.getSelection()
//
const range = selection.rangeCount > 0 ? selection.getRangeAt(0) : null
if (range) {
//
const markerElement = document.createElement('span')
//
range.insertNode(markerElement)
markerElement.appendChild(document.createTextNode('\u200B')) //
//
const markerOffsetTop = markerElement.offsetTop
const markerHeight = markerElement.offsetHeight
// div
const cursorDistanceFromBottom =
editableDiv.offsetHeight - (markerOffsetTop + markerHeight)
//
const scrollTop = editableDiv.scrollTop || 0
//
markerElement.parentNode.removeChild(markerElement)
//
return cursorDistanceFromBottom + scrollTop
}
// -1
return -1
},
//
async remoteMethod() {
},
handleNameShift(item) {
const name = item.name || ''
if (!name) return '--'
if (name.length > 1) {
return name.slice(0, 1)
} else {
return name
}
},
// div textarea
handleBtnBoxClick() {
this.$refs.customInput.focus()
},
getInnerText() {
const customInput = this.$refs.customInput
if (!customInput) return
return customInput.innerText
},
getJobId() {
const nodeList = this.$refs.customInput.childNodes
const list = []
nodeList.forEach((e) => {
if (e.className === 'active-text') {
list.push(e.getAttribute('data-id'))
}
})
return list
},
clearInput() {
this.$refs.customInput.innerText = ''
this.$refs.customInput.innerHTML = ''
this.inputValueLen = 0
this.$emit('input', '')
this.$emit('inputText', '')
this.$emit('changeChosen', [])
}
}
}
</script>
<style lang="scss" scoped>
.custom-textarea-btn {
position: absolute;
bottom: 1px;
right: 4px;
left: 4px;
text-align: right;
// background: #fff;
padding-bottom: 3px;
.el-button {
font-size: 12px;
padding: 4px 10px;
}
}
.custom-textarea-box {
position: relative;
}
.custom-at-limit {
position: absolute;
right: 12px;
bottom: 4px;
font-size: 12px;
color: #999;
line-height: 12px;
}
::v-deep.custom-textarea {
height: calc(100vh - 400px);
background-color: #ffffff;
padding: 5px 15px;
color: #606266;
overflow-y: auto;
line-height: 20px;
font-size: 14px;
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
position: relative;
word-break: break-all;
.el-textarea__inner {
border: none;
resize: none;
}
&.show-word-limit {
padding-bottom: 16px;
}
&.custom-textarea-disabled {
cursor: not-allowed;
background-color: #f5f7fa;
border-color: #e4e7ed;
color: #c0c4cc;
}
&:focus {
border-color: #f98600 !important;
}
&:empty::before {
content: attr(placeholder);
font-size: 14px;
color: #c0c4cc;
}
.active-text {
color: #909399;
// padding: 2px 6px;
// background: #f4f4f5;
margin-right: 4px;
// border-radius: 4px;
// font-size: 12px;
}
// &:focus::before {
// content: "";
// }
}
::v-deep.custom-select-box {
position: relative;
.el-popover {
padding: 0;
top: 0;
box-shadow: 0 4px 8px 0 rgba(89, 88, 88, 0.8);
}
.custom-select-content {
width: 259px;
padding: 8px;
max-height: 260px;
overflow-y: auto;
}
.custom-select-item {
// font-size: 14px;
// padding: 0 20px;
// position: relative;
// height: 34px;
// line-height: 34px;
// box-sizing: border-box;
display: flex;
padding: 8px 12px;
border-bottom: 1px solid #ebebeb;
align-items: center;
color: #606266;
cursor: pointer;
&:last-child {
border-bottom: none;
}
.avatar-box {
flex-shrink: 0;
.custom-select-item-avatar {
width: 24px;
height: 24px;
background-color: #ffb803;
border-radius: 50%;
text-align: center;
line-height: 24px;
color: #ffffff;
}
}
.custom-select-item-content {
flex: 1;
padding-left: 12px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
&:hover {
background-color: #f5f7fa;
}
&.hoverItem {
background-color: #dbdbdb;
}
}
.custom-select-empty {
padding: 10px 0;
text-align: center;
color: #999;
font-size: 14px;
&.load {
display: flex;
align-items: center;
justify-content: center;
}
}
.custom-scroll {
overflow: auto;
&::-webkit-scrollbar {
width: 8px;
height: 8px;
}
&::-webkit-scrollbar-thumb {
border-radius: 8px;
background-color: #b4b9bf;
}
}
}
</style>

@ -0,0 +1,90 @@
<template>
<cs-dialog
:dialog="dialogOptions"
>
<template slot="content">
<div class="SelectImg">
<img v-for="(item,index) in imgList" :key="index" :class="[selectId === item.id ? 'actived':'']" class="img-item" :src="item.url" @click="selectItem(item.id)">
</img>
</div>
</template>
</cs-dialog>
</template>
<script>
export default {
name: 'SelectImg',
data() {
return {
dialogOptions: {
show: false,
width: '520px',
title: {
title: '选择目录图片'
},
// hiddenFooter: true,
appendToBody: true
},
selectId: '',
imgList: [
{
url: require('@/assets/file/type1.png'),
id: 1
}, {
url: require('@/assets/file/type2.png'),
id: 2
}, {
url: require('@/assets/file/type3.png'),
id: 3
}, {
url: require('@/assets/file/type4.png'),
id: 4
}, {
url: require('@/assets/file/type5.png'),
id: 5
}, {
url: require('@/assets/file/type6.png'),
id: 6
}
]
}
},
mounted() {
},
methods: {
//
show() {
this.dialogOptions.show = true
},
selectItem(id) {
this.selectId = id
},
handleSelect(val) {
this.$emit('selectOk', val)
this.dialogOptions.show = false
}
}
}
</script>
<style scoped lang="scss">
.SelectImg {
display: flex;
flex-wrap: wrap;
img {
width: 100px;
height: 100px;
margin: 0 16px 16px 0;
cursor: pointer;
}
.actived {
border: 2px solid rgba(55, 99, 255, 1);
border-radius: 8px 8px 8px 8px;
}
}
</style>

@ -1,62 +1,428 @@
<template>
<div class="add-prompt">
<div class="left">
<div class="title">基础配置</div>
<el-form ref="form" :model="dataInfo" :rules="rules" label-width="90px">
<el-form-item label="案件类型" prop="caseType">
<el-select v-model="dataInfo['caseType']" clearable placeholder="请选择案件类型">
<el-option v-for="item in caseTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="指令类型" prop="caseNo">
<el-select v-model="dataInfo['caseType']" clearable placeholder="请选择案件类型">
<el-option v-for="item in caseTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="指令类型" prop="caseNo">
<el-input v-model="dataInfo['name']" clearable placeholder="请输入指令名称" />
</el-form-item>
<el-form-item label="关键词" prop="caseNo">
<el-input v-model="dataInfo['name']" clearable placeholder="请输入指令名称" />
</el-form-item>
<el-form-item label="选择目录" prop="caseType">
<el-select v-model="dataInfo['caseType']" clearable placeholder="请选择案件类型">
<el-option v-for="item in caseTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-form>
</div>
<div class="right">
<div class="tip">提示词配置对于自动识别属性内容和生成知识图谱至关重要通过上传测试文件检验其效果能有效提升案件指标判别的准确性</div>
<div class="main-content">
<div class="left">
<div class="title">基础配置</div>
<el-form ref="form" :model="dataInfo" :rules="rules" label-width="120px">
<el-form-item label="案件类型" prop="caseType">
<el-select v-model="dataInfo['caseType']" style="width: 100%;" clearable placeholder="请选择案件类型">
<el-option v-for="item in caseTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="提示词类型" prop="type">
<el-select v-model="dataInfo['type']" style="width: 100%;" placeholder="请选择提示词类型">
<el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="提示词名称" prop="name">
<el-input v-model="dataInfo['name']" clearable placeholder="请输入提示词名称" />
</el-form-item>
<el-form-item v-if="dataInfo.type ==='1'" label="所属目录" prop="evidenceCategoryList">
<el-cascader v-model="dataInfo.evidenceCategoryList" style="width: 100%;" :props="defaultProps" :options="treeData" />
</el-form-item>
<!-- <el-form-item v-if="dataInfo.type ==='1'" label="类目图标" prop="caseType">
<div class="select-img">
<div class="sel-btn" @click="openSelectImg"></div>
</div>
</el-form-item> -->
<el-form-item v-if="dataInfo.type ==='1'" label="提取属性" prop="extractAttributes">
<div class="params-table">
<div class="top">
<span style="width: 450px;">字典标签</span>
<span style="width: 150px;">字典数值</span>
<span style="width: 80px;">操作</span>
</div>
<div v-for="(item,index) in dataInfo.extractAttributes" :key="index" class="table-item">
<el-input v-model="item.attrName" style="width: 400px;margin-right: 40px;" placeholder="请输入" />
<el-select v-model="item.attrValueType" style="width: 120px;margin-right: 40px;" clearable placeholder="请选择">
<el-option v-for="items in extractList" :key="items.value" :label="items.label" :value="items.value" />
</el-select>
<i class="el-icon-delete" @click="delItem(index)" />
</div>
<div class="add-table" @click="addItem">
<i class="el-icon-circle-plus-outline" style="color: #3763FF;font-size: 16px;" />
<span>添加数据</span>
</div>
</div>
</el-form-item>
</el-form>
</div>
<div class="right">
<div class="right-header">
<span>提示词配置</span>
<div class="btn-list">11</div>
<span>提示词配置</span>
<div class="btn-list">
<div class="ai-btn">
<i class="el-icon-refresh" />
<span>AI自动生成</span>
</div>
<div class="btn" @click="handleDebug"></div>
</div>
</div>
<div class="content">
<!-- <el-input
v-model="dataInfo['prompt']"
type="textarea"
:rows="24"
placeholder="请输入提示词模板"
/> -->
<PromptInput
v-model="customInputHTML"
placeholder=""
@inputText="handleChangeInputText"
@changeChosen="handleChangeChosen"
/>
</div>
<div class="content">222</div>
</div>
</div>
<div class="footer-btns">
<div class="btn" @click="submit"></div>
<div class="btn" @click="submit"></div>
<div class="reset_btn" @click="reset"></div>
</div>
<PromptDebug ref="PromptDebugRef" />
<SelectImg ref="SelectImgRef" />
</div>
</template>
<script>
import PromptDebug from './PromptDebug.vue'
import SelectImg from './SelectImg.vue'
import { getCaseEvidenceTree } from '@/api/caseDetails/evidence'
import { addOrUpdPrompt } from '@/api/promptManagement'
import PromptInput from './PromptInput.vue'
export default {
name: 'AddPrompt',
components: {
PromptDebug,
SelectImg,
PromptInput
},
data() {
return {
dataInfo: {
caseType: ''
// html
customInputHTML: '',
// 使使
customInputText: '',
// @
customInputMentions: [],
caseType: '',
type: '1',
name: '',
evidenceCategoryList: [],
extractAttributes: [],
prompt: '请根据属性定义从源文本中提取属性:\n' +
'\n' +
'示例文本:\n' +
'"\n' +
'甲方:张三公司\n' +
'乙方:\n' +
'数量5000吨水泥\n' +
'合同金额8346元\n' +
'支付时间2022年11月30日\n' +
'履行期限2022年12月1日至2023年12月1日\n' +
'签订日期2022年11月23日\n' +
'"\n' +
'\n' +
'示例结果:\n' +
'{\n' +
' "甲方名称": "张三公司",\n' +
' "乙方名称": "",\n' +
' "数量": "5000吨水泥",\n' +
' "合同金额": "8346.00",\n' +
' "支付时间": "2022-11-30",\n' +
' "履行期限": "2022年12月1日至2023年12月1日",\n' +
' "签订日期": "2022-11-23"\n' +
'}\n' +
'\n' +
'源文本:\n' +
'{ocr_txt}\n' +
'\n' +
'属性定义:\n' +
'{attr_define}\n' +
'\n' +
'### 注意事项:\n' +
'1. 将结果以JSON格式返回。不需要进行解释。\n' +
'2. 如果某字段提取不到,则返回""。\n' +
'3. 日期格式为yyyy-MM-dd数字格式返回保留两位小数。\n' +
'4. 值为文本类型的数据,尽量使用原文中的文字。\n' +
'5. 只可以使用原文中的文字,不可以自行添加内容。\n' +
'\n' +
'回溯你输出的结果确保你的输出结果符合json格式。'
},
tableList: [{
name: '',
type: ''
}],
rules: {
caseType: [{ required: true, message: '案件类型不能为空!', trigger: 'blur' }],
type: [{ required: true, message: '提示词类型不能为空!', trigger: 'blur' }],
name: [{ required: true, message: '提示词名称不能为空!', trigger: 'blur' }],
extractAttributes: [{ required: true, message: '提取属性不能为空!', trigger: 'blur' }]
},
defaultProps: {
children: 'child',
label: 'categoryName',
value: 'id',
checkStrictly: true
},
treeData: [],
id: '',
extractList: [
{
label: '输入框',
value: 'text'
},
{
label: '日期',
value: 'date'
}
],
//
caseTypeOptions: JSON.parse(sessionStorage.getItem('case_type'))
caseTypeOptions: JSON.parse(sessionStorage.getItem('case_type')),
typeOptions: JSON.parse(sessionStorage.getItem('prompt_type'))
}
},
mounted() {
this.getTreeList()
},
methods: {
//
handleChangeInputText(val) {
this.customInputText = val
},
//
handleChangeChosen(val) {
this.customInputMentions = val
}, handleDebug() {
this.$refs.PromptDebugRef.show()
},
openSelectImg() {
this.$refs.SelectImgRef.show()
},
//
getTreeList() {
getCaseEvidenceTree({ caseType: 1 }).then(res => {
if (res.code === 200) {
this.treeData = res.data
}
})
},
addItem() {
this.dataInfo.extractAttributes.push({
attrName: '',
attrValueType: ''
})
},
delItem(index) {
this.dataInfo.extractAttributes.splice(index, 1)
},
reset() {
},
submit() {
this.$refs.form.validate(valid => {
if (valid) {
const params = {
id: this.id,
...this.dataInfo,
evidenceCategoryId: this.dataInfo.evidenceCategoryList[this.dataInfo.evidenceCategoryList.length - 1 ]
}
addOrUpdPrompt(params).then(res => {
const { code, msg } = res
code === 200 ? (this.id ? this.$baseMessage.success(msg || '编辑成功!') : this.$baseMessage.success(msg || '新增成功!')) : (this.id ? this.$baseMessage.error(msg || '编辑失败!') : this.$baseMessage.error(msg || '新增失败!'))
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
.add-prompt {
background-color: #fff;
height: 100%;
display: flex;
flex-direction: column;
padding: 0 40px;
.tip {
width: 100%;
height: 70px;
background: #F6F8F9;
border-radius: 8px 8px 8px 8px;
line-height: 70px;
padding-left: 24px;
font-size: 16px;
color: #333333;
margin-top: 24px;
margin-bottom: 16px;
}
.main-content {
display: flex;
flex: 1;
.left {
width: 750px;
border-right: 1px solid rgba(51, 51, 51, 0.20);
padding-right: 40px;
.title {
font-weight: bold;
font-size: 18px;
color: #333333;
margin-top: 24px;
margin-bottom: 24px;
}
.select-img {
width: 96px;
height: 42px;
background: #FFFFFF;
border-radius: 6px 6px 6px 6px;
border: 1px solid #3763FF;
line-height: 42px;
text-align: center;font-size: 16px;
color: #3763FF;
cursor: pointer;
}
.params-table {
border-radius: 6px 6px 6px 6px;
border: 1px solid #D9D9D9;
.top {
background: #F2F6FA;
height: 42px;
display: flex;
line-height: 42px;
span {
text-align: center;font-size: 16px;
color: #888888;
}
}
.add-table {
height: 56px;
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
color: #3763FF;
cursor: pointer;
span {
margin-left: 8px;
}
}
.table-item {
display: flex;
padding: 16px;
align-items: center;
border-bottom: 1px solid #FFEAEAEA;
i {
color: #FF3429;
cursor: pointer;
}
}
}
}
.right {
flex: 1;
padding: 24px 40px;
display: flex;
flex-direction: column;
.right-header {
display: flex;
justify-content: space-between;
span {
font-weight: bold;
font-size: 18px;
color: #333333;
}
.btn-list {
display: flex;
.ai-btn {
width: 154px;
height: 42px;
border-radius: 6px 6px 6px 6px;
border: 1px solid #3763FF;
display: flex;
justify-content: center;
align-items: center;
margin-right: 24px;
cursor: pointer;
i {
font-size: 16px;
color: #3763FF;
}
span {
font-size: 16px;
color: #3763FF;
margin-left: 8px;
font-weight: 400;
}
}
.btn {
width: 98px;
height: 42px;
background: #3763FF;
border-radius: 6px 6px 6px 6px;text-align: center;
line-height: 42px;
font-size: 16px;
color: #FFFFFF;
cursor: pointer;
}
}
}
.content {
border-radius: 6px 6px 6px 6px;
border: 1px solid #D9D9D9;
margin-top: 14px;
flex: 1;
// padding: 16px;
::v-deep {
.el-textarea__inner {
border: none;
resize: none;
}
}
}
}
}
.footer-btns {
height: 96px;
background: #FFFFFF;
box-shadow: 2px -4px 12px 0px rgba(0,0,0,0.04);
border-radius: 8px 8px 8px 8px;
display: flex;
flex-direction: row-reverse;
align-items: center;
.btn {
width: 188px;
height: 48px;
background: #3763FF;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.04);
border-radius: 6px 6px 6px 6px;
text-align: center;
line-height: 48px;
font-size: 16px;
color: #FFFFFF;
cursor: pointer;
margin-left: 24px;
}
.reset_btn {
width: 188px;
height: 48px;
background: #FFFFFF;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.04);
border-radius: 6px 6px 6px 6px;
border: 1px solid #3763FF;
text-align: center;
line-height: 48px;
font-size: 16px;
color: #3763FF;
cursor: pointer;
margin-left: 24px;
}
}
}
</style>

@ -1,6 +1,6 @@
<template>
<div class="content">
<div ref="htmlContent" class="content">
<cs-search title="提示词检索" :data="searchData" :span="6" direction="row" @onSearch="onSearch" @getData="onSearch" />
<div class="index-content">
<div class="header">
@ -26,44 +26,28 @@
<script>
import mixin from '@/views/mixin'
import { queryIndexData, deleteModelIndex } from '@/api/indexRule'
import { queryPromptList } from '@/api/promptManagement'
export default {
name: 'Index',
name: 'PromptConfig',
mixins: [mixin],
data() {
return {
//
searchData: [
{ label: '指标名称', model: 'name', type: 'input' },
{ label: '指标类别', model: 'indexType', type: 'select', option: JSON.parse(sessionStorage.getItem('index_type')) },
// { label: '', model: 'doer', type: 'input' },
{ label: '案件类型', model: 'caseType', type: 'select', option: JSON.parse(sessionStorage.getItem('case_type')) },
{ label: '原子指标', model: 'atomicIndexName', type: 'input' }
{ label: '提示词名称', model: 'name', type: 'input' },
{ label: '提示词类型', model: 'type', type: 'select', option: JSON.parse(sessionStorage.getItem('prompt_type')) }
],
//
gridOptions: {
...mixin.data().gridOptions,
//
cellClassName: ({ column }) => {
if (column.field === 'indexName') {
return 'text-blue'
}
return null
},
//
expandConfig: {
iconClose: 'vxe-icon-square-plus',
iconOpen: 'vxe-icon-square-minus'
},
columns: [
{ title: '序号', type: 'seq', width: '50px' },
{ title: '指标名称', field: 'name', align: 'left' },
{ title: '指标类别', field: 'indexTypeName', width: '150px' },
{ title: '指标分数', field: 'indexScore', width: '150px', sortable: true },
{ title: '原子指标数量', field: 'atomicIndexNum', width: '150px' },
{ title: '最新时间', field: 'updateTime', width: '150px' },
{ title: '操作', slots: { default: 'operate' }, fixed: 'right', width: '150px' }
{ title: 'ID', field: 'id', width: '300px' },
{ title: '提示词名称', field: 'name', width: '300px' },
{ title: '提示词类型', field: 'type', width: '200px' },
{ title: '匹配值', field: 'matchNum', width: '200px' },
{ title: '提示词', field: 'prompt' },
{ title: '操作', slots: { default: 'operate' }, width: '150px' }
],
data: []
}
@ -75,21 +59,22 @@ export default {
methods: {
//
fetchData() {
queryIndexData({ ...this.searchFormData }, this.queryForm.page, this.queryForm.size).then(res => {
this.gridOptions.data = res.data.result
queryPromptList({ ...this.searchFormData, page: this.queryForm.page, size: this.queryForm.size }).then(res => {
this.gridOptions.data = res.data.records
this.queryForm.total = res.data.total
})
},
//
handleAdd() {
this.$router.push({ path: `/add-prompt` })
},
//
handleDel(row) {
this.$baseConfirm('确定要删除吗?', null, async() => {
const { code, msg } = await deleteModelIndex(row.id)
code === 200 ? this.$baseMessage.success(msg || '删除成功!') : this.$baseMessage.error(msg || '删除失败!')
this.fetchData()
})
// this.$baseConfirm('?', null, async() => {
// const { code, msg } = await deleteModelIndex(row.id)
// code === 200 ? this.$baseMessage.success(msg || '!') : this.$baseMessage.error(msg || '!')
// this.fetchData()
// })
},
//
onSearch(data, callback) {

@ -13,91 +13,105 @@
@onSubmit="handleSubmit"
>
<template slot="content">
<el-form ref="form" :model="ruleForm" :rules="rules" label-width="120px">
<el-form-item label="案件类型" prop="caseType">
<el-select v-model="ruleForm.caseType" :disabled="isView" placeholder="请选择案件类型" style="width: 100%">
<el-option
v-for="item in caseTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
<div class="add-atomic">
<el-form ref="form" :model="ruleForm" :rules="rules" label-width="120px">
<el-form-item label="案件类型" prop="caseType">
<el-select v-model="ruleForm.caseType" :disabled="isView" placeholder="请选择案件类型" style="width: 100%">
<el-option
v-for="item in caseTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="原子指标名称" prop="name">
<el-input
v-model="ruleForm.name"
:disabled="isView"
placeholder="请输入原子指标名称"
/>
</el-select>
</el-form-item>
<el-form-item label="原子指标名称" prop="name">
<el-input
v-model="ruleForm.name"
:disabled="isView"
placeholder="请输入原子指标名称"
/>
</el-form-item>
<el-form-item label="指标算法" prop="indexSource">
<el-radio-group v-model="ruleForm['indexSource']" :disabled="isView" @change="changeType">
<el-radio
v-for="item in sourceOptions"
:key="item.value"
:label="item.value"
>
{{ item.label }}
</el-radio>
</el-form-item>
<el-form-item label="指标算法" prop="indexSource">
<el-radio-group v-model="ruleForm['indexSource']" :disabled="isView" @change="changeType">
<el-radio
v-for="item in sourceOptions"
:key="item.value"
:label="item.value"
>
{{ item.label }}
</el-radio>
<!-- <el-radio label="1">人工指定</el-radio>-->
<!-- <el-radio label="2">数据库查询</el-radio>-->
<!-- <el-radio label="3">图谱生成</el-radio>-->
<!-- <el-radio label="4">大模型</el-radio>-->
</el-radio-group>
</el-form-item>
<el-form-item v-if="ruleForm['indexSource'] === '4'" label="prompt标签" prop="recordType">
<el-select v-model="ruleForm['recordType']" :disabled="isView" placeholder="请选择prompt标签" style="width: 100%">
<el-option
v-for="item in promptTagOptions"
:key="item.value"
:label="item.label"
:value="item.value"
</el-radio-group>
</el-form-item>
<el-form-item label="查询语句" prop="indexSource">
<div class="select-btn" @click="selectSql"></div>
<div v-if="ruleForm['indexSource'] === '3'" class="sel-name">{{ `` }}</div>
<div v-if="ruleForm['indexSource'] === '4'" class="sel-name">{{ `` }}</div>
<span v-if="ruleForm['indexSource'] === '3'" class="sel-desc">{{ `--` }}</span>
<div v-if="ruleForm['indexSource'] === '4'" class="select-model-list">
<div v-for="(item,index) in modelList" :key="index" class="model-list-item">
<span>{{ item.name }}</span>
<i class="el-icon-circle-close" />
</div>
</div>
</el-form-item>
<el-form-item v-if="ruleForm['indexSource'] === '4'" label="prompt标签" prop="recordType">
<el-select v-model="ruleForm['recordType']" :disabled="isView" placeholder="请选择prompt标签" style="width: 100%">
<el-option
v-for="item in promptTagOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item v-if="ruleForm['indexSource'] === '4'" label="prompt内容" prop="prompt">
<el-input
v-model="ruleForm.prompt"
:disabled="isView"
type="textarea"
:rows="5"
placeholder="请输入prompt内容"
/>
</el-form-item>
<el-form-item v-if="ruleForm['indexSource'] === '2' || ruleForm['indexSource'] === '3'" label="查询语句" prop="queryLang">
<el-input
v-model="ruleForm['queryLang']"
:disabled="isView"
type="textarea"
:rows="5"
placeholder="请输入查询语句"
/>
</el-select>
</el-form-item>
<el-form-item v-if="ruleForm['indexSource'] === '4'" label="prompt内容" prop="prompt">
<el-input
v-model="ruleForm.prompt"
:disabled="isView"
type="textarea"
:rows="5"
placeholder="请输入prompt内容"
/>
</el-form-item>
<el-form-item v-if="ruleForm['indexSource'] === '2' || ruleForm['indexSource'] === '3'" label="查询语句" prop="queryLang">
<el-input
v-model="ruleForm['queryLang']"
:disabled="isView"
type="textarea"
:rows="5"
placeholder="请输入查询语句"
/>
</el-form-item>
</el-form-item>
<!-- <el-form-item label="判断结果" prop="judgeResult">-->
<!-- <el-select v-model="ruleForm['judgeResult']" :disabled="isView" placeholder="请选择判断结果" style="width: 100%">-->
<!-- <el-option-->
<!-- v-for="item in resultOptions"-->
<!-- :key="item.value"-->
<!-- :label="item.label"-->
<!-- :value="item.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item label="原子指标说明" prop="remark">
<el-input
v-model="ruleForm.remark"
:disabled="isView"
type="textarea"
:rows="5"
placeholder="请输入原子指标说明"
/>
</el-form-item>
</el-form>
<!-- <el-form-item label="判断结果" prop="judgeResult">-->
<!-- <el-select v-model="ruleForm['judgeResult']" :disabled="isView" placeholder="请选择判断结果" style="width: 100%">-->
<!-- <el-option-->
<!-- v-for="item in resultOptions"-->
<!-- :key="item.value"-->
<!-- :label="item.label"-->
<!-- :value="item.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item label="原子指标说明" prop="remark">
<el-input
v-model="ruleForm.remark"
:disabled="isView"
type="textarea"
:rows="5"
placeholder="请输入原子指标说明"
/>
</el-form-item>
</el-form>
</div>
<SelectSql ref="SelectSqlRef" />
</template>
<SelectSql ref="SelectSqlRef" />
</cs-drawer>
</template>
@ -116,6 +130,17 @@ export default {
title: '指标配置',
width: '40%'
},
modelList: [
{
name: '属性1'
}, {
name: '属性2'
}, {
name: '属性3'
}, {
name: '属性4'
}
],
//
caseTypeOptions: JSON.parse(sessionStorage.getItem('case_type')),
// prompt
@ -169,6 +194,9 @@ export default {
this.ruleForm = { indexSource: '1' }
// this.$refs.form.clearValidate()
},
selectSql() {
this.$refs.SelectSqlRef.show()
},
//
handleSubmit() {
this.$refs.form.validate(async valid => {
@ -193,5 +221,41 @@ export default {
</script>
<style scoped lang="scss">
.add-atomic {
.select-btn {
width: 96px;
height: 36px;
background: #FFFFFF;
border-radius: 6px 6px 6px 6px;
border: 1px solid #3763FF;
line-height: 36px;
text-align: center;font-size: 16px;
color: #3763FF;
cursor: pointer;
}
.sel-name {
margin-top: 8px;font-size: 16px;
color: #3763FF;
}
.sel-desc {
margin-top: 8px;font-size: 16px;
color: #333333
}
.select-model-list {
display: flex;
.model-list-item {
padding: 0 12px;
height: 32px;
margin:0 8px 8px 0;
background: #F0F0F0;
border-radius: 6px 6px 6px 6px;font-size: 14px;
color: #333333;
display: flex;
align-items: center;
span {
margin-right: 16px;
}
}
}
}
</style>

@ -6,6 +6,7 @@
@onSubmit="handleSubmit"
>
<template slot="content">
<el-form v-model="searchForm" label-width="120px">
<el-row :gutter="10">
<el-col :span="10">
@ -13,35 +14,37 @@
<el-input v-model="searchForm['name']" clearable placeholder="请选择原子指标名称" />
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="指令类型" prop="indexSource">
<el-select v-model="searchForm['indexSource']" clearable placeholder="请选择指标算法">
<el-option
v-for="item in indexAlgorithmOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="handleSearch"></el-button>
</el-col>
</el-row>
</el-form>
<div class="main">
<vxe-grid
ref="xTable"
row-id="id"
v-bind="gridOptions"
style="margin-top: 10px"
:checkbox-config="{ labelField: '', highlight: true, trigger: 'row', reserve: true , range: true}"
style="margin-top: 10px;width: 850px;"
:radio-config-config="{ labelField: '', highlight: true, trigger: 'row', reserve: true , range: true}"
@checkbox-change="selectChangeEvent"
@radioConfig-change="selectChangeEvent"
/>
<div class="main-right">
111
<!-- <div class="chart-content">
<span class="title">提示词配置内容</span>
</div> -->
<div class="model-content">
<vxe-grid
ref="modelTable"
row-id="id"
v-bind="modelGridOptions"
:checkbox-config-config="{ labelField: '', highlight: true, trigger: 'row', reserve: true , range: true}"
@checkbox-change="selectChangeEvent"
/>
<div class="title">提示词配置内容</div>
</div>
</div>
</div>
@ -69,6 +72,8 @@ export default {
dialogOption: {
show: false,
appendToBody: true,
width: '1400px',
height: '800px',
title: {
title: '选择原子指标查询语句'
}
@ -83,14 +88,23 @@ export default {
//
gridOptions: {
...mixin.data().gridOptions,
height: '320px',
columns: [
{ type: 'radio', width: '80px' },
{ title: '指令名称', field: 'name', align: 'left' },
{ title: '指令类型', field: 'indexSourceName' },
{ title: '三元组', field: 'remark' },
{ title: '属性', field: 'remark' }
],
data: [{}]
},
modelGridOptions: {
height: '240px',
columns: [
{ type: 'checkbox', width: '80px' },
{ title: '原子指标名称', field: 'name', align: 'left' },
{ title: '指标来源', field: 'indexSourceName' },
{ title: '指标说明', field: 'remark' }
{ title: '属性名称', field: 'remark' },
{ title: '属性类型', field: 'remark' }
],
data: []
data: [{}]
},
//
selectionRows: []
@ -98,11 +112,11 @@ export default {
},
methods: {
//
show(data) {
show() {
this.dialogOption.show = true
this.selectionRows = data
this.searchForm['name'] = ''
this.fetchData()
// this.selectionRows = data
// this.searchForm['name'] = ''
// this.fetchData()
},
//
fetchData() {
@ -180,5 +194,43 @@ export default {
<style lang="scss">
.SelectSql .el-dialog {
background: #fff;
.main {
display: flex;
margin-bottom: 20px;
height: 550px;
.main-right {
flex: 1;
margin-left: 24px;
.chart-content {
background: #FFFFFF;
border-radius: 6px 6px 6px 6px;
border: 1px solid #D9D9D9;
padding: 16px;
height: 100%;
.title {
font-weight: bold;
font-size: 18px;
color: #333333;
margin-bottom: 16px;
}
}
.model-content {
background: #FFFFFF;
border-radius: 6px 6px 6px 6px;
border: 1px solid #D9D9D9;
padding: 16px;
height: 100%;
.title {
font-weight: bold;
font-size: 18px;
color: #333333;
margin-bottom: 16px;
margin-top: 16px;
}
}
}
}
}
</style>

@ -40,41 +40,58 @@
{{ logic.label }}
</el-radio-button>
</el-radio-group>
<div v-for="(subItem, subIndex) in item.atomicData" :key="subIndex" class="flex-row row-content">
<span class="row-line" />
<el-button
icon="el-icon-remove-outline"
type="text"
style="color: red"
:disabled="item.atomicData.length === 1"
@click="handleRowClick(item, subItem)"
/>
<el-select
v-model="subItem.atomicIndex"
placeholder="请选择"
clearable
style="width: 300px"
>
<el-option
v-for="option in atomicIndexData"
:key="option.id"
:label="option.name"
:value="option.id"
/>
</el-select>
<el-select
v-model="subItem.relationalSymbol"
placeholder="请选择"
clearable
style="width: 150px;margin-left: 20px"
>
<el-option
v-for="option in symbolOptions"
:key="option.value"
:label="option.label"
:value="option.value"
<div v-for="(subItem, subIndex) in item.atomicData" :key="subIndex">
<div class="flex-row row-content">
<span class="row-line" />
<el-button
icon="el-icon-remove-outline"
type="text"
style="color: red"
:disabled="item.atomicData.length === 1"
@click="handleRowClick(item, subItem)"
/>
</el-select>
<el-select
v-model="subItem.atomicIndex"
placeholder="请选择"
clearable
style="width: 300px"
>
<el-option
v-for="option in atomicIndexData"
:key="option.id"
:label="option.name"
:value="option.id"
/>
</el-select>
<el-select
v-model="subItem.relationalSymbol"
placeholder="请选择"
clearable
style="width: 150px;margin-left: 20px"
>
<el-option
v-for="option in symbolOptions"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</el-select>
</div>
<div class="row-sku">
<div class="row-sku-top">
<i class="el-icon-circle-plus-outline" style="color: #3763FF;font-size: 14px;" />
<span>添加单个条件</span>
<el-radio-group v-model="subItem.groupLogic" class="group-logic">
<el-radio-button
v-for="logic in logicSymbolOptions"
:key="logic.value"
:label="logic.value"
>
{{ logic.label }}
</el-radio-button>
</el-radio-group></div>
<div v-for="(items,i) in "></div>
</div>
</div>
<el-button
icon="el-icon-circle-plus-outline"
@ -108,7 +125,7 @@
<script>
import mixin from '@/views/mixin'
// import { CirclePlus } from "@element-plus/icons-vue";
export default {
name: 'CustomLogic',
mixins: [mixin],
@ -128,7 +145,9 @@ export default {
return {
//
logicData: [
{ groupLogic: '1', rowLogic: '1', atomicData: [{ atomicIndex: '', relationalSymbol: '' }] }
{ groupLogic: '1', rowLogic: '1', atomicData: [{ atomicIndex: '', relationalSymbol: '', attributeList:[{
}] }] }
],
//
logicSymbolOptions: JSON.parse(sessionStorage.getItem('logic_symbol'))
@ -240,6 +259,7 @@ export default {
.group {
border: 1px dashed #999999;
position: relative;
padding-bottom: 40px;
.group-title {
position: absolute;
top: -10px;
@ -254,7 +274,7 @@ export default {
background: #ffffff;
}
.row-content {
margin: 30px 0;
margin: 30px 0 16px 0;
align-items: center;
.row-line {
width: 50px;
@ -277,6 +297,18 @@ export default {
bottom: -15px;
left: 310px;
}
.row-sku {
padding-left: 50px;
.row-sku-top {
span {
font-size: 14px;
color: #3763FF;
margin-left: 4px;
cursor: pointer;
margin-right: 16px;
}
}
}
}
.group-logic-content {
padding: 30px 0;

Loading…
Cancel
Save