Compare commits
9 Commits
58abe5ebdf
...
e98aa61cd2
| Author | SHA1 | Date | |
|---|---|---|---|
| e98aa61cd2 | |||
| cec4c323a7 | |||
| a176608019 | |||
| 3a262216c7 | |||
| 2c08d0c362 | |||
| b36aefc7c4 | |||
| 9d512ebad4 | |||
| 5dc3c2d2c5 | |||
| 70ebe31103 |
@@ -34,6 +34,7 @@
|
|||||||
"sm-crypto": "^0.4.0",
|
"sm-crypto": "^0.4.0",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-i18n": "^11.4.2",
|
"vue-i18n": "^11.4.2",
|
||||||
|
"vue-pdf-embed": "^2.1.6",
|
||||||
"vue-router": "^4.3.2",
|
"vue-router": "^4.3.2",
|
||||||
"vue3-clipboard": "^1.0.0",
|
"vue3-clipboard": "^1.0.0",
|
||||||
"vuex": "^4.1.0",
|
"vuex": "^4.1.0",
|
||||||
|
|||||||
@@ -4,11 +4,6 @@ settings:
|
|||||||
autoInstallPeers: true
|
autoInstallPeers: true
|
||||||
excludeLinksFromLockfile: false
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
patchedDependencies:
|
|
||||||
'@smallwei/avue':
|
|
||||||
hash: 5ba15ad41b2c301250bf24adf39da2ed526b8375143da2c5a495361b29e862db
|
|
||||||
path: patches/@smallwei__avue.patch
|
|
||||||
|
|
||||||
importers:
|
importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
@@ -33,7 +28,7 @@ importers:
|
|||||||
version: 1.7.0
|
version: 1.7.0
|
||||||
'@smallwei/avue':
|
'@smallwei/avue':
|
||||||
specifier: ~3.9.2
|
specifier: ~3.9.2
|
||||||
version: 3.9.2(patch_hash=5ba15ad41b2c301250bf24adf39da2ed526b8375143da2c5a495361b29e862db)(@element-plus/icons-vue@2.3.2(vue@3.5.34))(element-plus@2.14.2(vue@3.5.34))(vue@3.5.34)
|
version: 3.9.2(@element-plus/icons-vue@2.3.2(vue@3.5.34))(element-plus@2.14.2(vue@3.5.34))(vue@3.5.34)
|
||||||
animate.css:
|
animate.css:
|
||||||
specifier: ^4.1.1
|
specifier: ^4.1.1
|
||||||
version: 4.1.1
|
version: 4.1.1
|
||||||
@@ -88,6 +83,9 @@ importers:
|
|||||||
vue-i18n:
|
vue-i18n:
|
||||||
specifier: ^11.4.2
|
specifier: ^11.4.2
|
||||||
version: 11.4.2(vue@3.5.34)
|
version: 11.4.2(vue@3.5.34)
|
||||||
|
vue-pdf-embed:
|
||||||
|
specifier: ^2.1.6
|
||||||
|
version: 2.1.6(vue@3.5.34)
|
||||||
vue-router:
|
vue-router:
|
||||||
specifier: ^4.3.2
|
specifier: ^4.3.2
|
||||||
version: 4.6.4(vue@3.5.34)
|
version: 4.6.4(vue@3.5.34)
|
||||||
@@ -1791,6 +1789,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-o8MolyzirkkLrcdsae/HEOiIcXWI7DS5zGpvqW8xTC2YUsW30rltFw2bDGvw/fskUdEMrQm2br68jzDS5BH2vw==}
|
resolution: {integrity: sha512-o8MolyzirkkLrcdsae/HEOiIcXWI7DS5zGpvqW8xTC2YUsW30rltFw2bDGvw/fskUdEMrQm2br68jzDS5BH2vw==}
|
||||||
engines: {node: '>=22.13.0 || >=24'}
|
engines: {node: '>=22.13.0 || >=24'}
|
||||||
|
|
||||||
|
pdfjs-dist@6.2.108:
|
||||||
|
resolution: {integrity: sha512-YxFb+SQcodN2rnX9Tn3dHYlqfb7NjlzzfONPpJd+AKoKtUjEdevTfbC07d5TcczzOK6261auRkP/M8OBHs9vFQ==}
|
||||||
|
engines: {node: '>=22.13.0 || >=24'}
|
||||||
|
|
||||||
picocolors@1.1.1:
|
picocolors@1.1.1:
|
||||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||||
|
|
||||||
@@ -2123,6 +2125,11 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
vue: ^3.0.0
|
vue: ^3.0.0
|
||||||
|
|
||||||
|
vue-pdf-embed@2.1.6:
|
||||||
|
resolution: {integrity: sha512-cNmclL9jGuRIqgm13fx/3ZZd1nW/Nn0zXfQUo/yd8AQU9GTFLLYRgFc5HM41v1+bMoj1wW59mZoB/cNQx8Y2Rw==}
|
||||||
|
peerDependencies:
|
||||||
|
vue: ^3.3.0
|
||||||
|
|
||||||
vue-router@4.6.4:
|
vue-router@4.6.4:
|
||||||
resolution: {integrity: sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==}
|
resolution: {integrity: sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -2641,7 +2648,7 @@ snapshots:
|
|||||||
countup.js: 2.10.0
|
countup.js: 2.10.0
|
||||||
signature_pad: 5.1.3
|
signature_pad: 5.1.3
|
||||||
|
|
||||||
'@smallwei/avue@3.9.2(patch_hash=5ba15ad41b2c301250bf24adf39da2ed526b8375143da2c5a495361b29e862db)(@element-plus/icons-vue@2.3.2(vue@3.5.34))(element-plus@2.14.2(vue@3.5.34))(vue@3.5.34)':
|
'@smallwei/avue@3.9.2(@element-plus/icons-vue@2.3.2(vue@3.5.34))(element-plus@2.14.2(vue@3.5.34))(vue@3.5.34)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@element-plus/icons-vue': 2.3.2(vue@3.5.34)
|
'@element-plus/icons-vue': 2.3.2(vue@3.5.34)
|
||||||
axios: 0.21.4
|
axios: 0.21.4
|
||||||
@@ -2780,30 +2787,30 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
vue: 3.5.34
|
vue: 3.5.34
|
||||||
|
|
||||||
'@wangeditor-next/basic-modules@2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.throttle@4.1.1)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)':
|
'@wangeditor-next/basic-modules@2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@wangeditor-next/core': 1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)
|
'@wangeditor-next/core': 1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3)
|
||||||
dom7: 4.0.6
|
dom7: 3.0.0
|
||||||
is-url: 1.2.4
|
is-url: 1.2.4
|
||||||
lodash.throttle: 4.1.1
|
lodash.throttle: 4.1.1
|
||||||
nanoid: 5.1.11
|
nanoid: 3.3.12
|
||||||
slate: 0.123.0
|
slate: 0.72.8
|
||||||
snabbdom: 3.6.3
|
snabbdom: 3.6.3
|
||||||
|
|
||||||
'@wangeditor-next/code-highlight@2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.123.0)(snabbdom@3.6.3)':
|
'@wangeditor-next/code-highlight@2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.123.0)(snabbdom@3.6.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@wangeditor-next/core': 1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)
|
'@wangeditor-next/core': 1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3)
|
||||||
dom7: 4.0.6
|
dom7: 4.0.6
|
||||||
prismjs: 1.30.0
|
prismjs: 1.30.0
|
||||||
slate: 0.123.0
|
slate: 0.123.0
|
||||||
snabbdom: 3.6.3
|
snabbdom: 3.6.3
|
||||||
|
|
||||||
'@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)':
|
'@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/event-emitter': 0.3.5
|
'@types/event-emitter': 0.3.5
|
||||||
'@uppy/core': 2.3.4
|
'@uppy/core': 2.3.4
|
||||||
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
|
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
|
||||||
dom7: 4.0.6
|
dom7: 3.0.0
|
||||||
event-emitter: 0.3.5
|
event-emitter: 0.3.5
|
||||||
html-void-elements: 3.0.0
|
html-void-elements: 3.0.0
|
||||||
i18next: 23.16.8
|
i18next: 23.16.8
|
||||||
@@ -2814,9 +2821,9 @@ snapshots:
|
|||||||
lodash.foreach: 4.5.0
|
lodash.foreach: 4.5.0
|
||||||
lodash.throttle: 4.1.1
|
lodash.throttle: 4.1.1
|
||||||
lodash.toarray: 4.4.0
|
lodash.toarray: 4.4.0
|
||||||
nanoid: 5.1.11
|
nanoid: 3.3.12
|
||||||
scroll-into-view-if-needed: 3.1.0
|
scroll-into-view-if-needed: 3.1.0
|
||||||
slate: 0.123.0
|
slate: 0.72.8
|
||||||
slate-history: 0.115.0(slate@0.123.0)
|
slate-history: 0.115.0(slate@0.123.0)
|
||||||
snabbdom: 3.6.3
|
snabbdom: 3.6.3
|
||||||
|
|
||||||
@@ -2824,13 +2831,13 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@uppy/core': 2.3.4
|
'@uppy/core': 2.3.4
|
||||||
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
|
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
|
||||||
'@wangeditor-next/basic-modules': 2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.throttle@4.1.1)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)
|
'@wangeditor-next/basic-modules': 2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3)
|
||||||
'@wangeditor-next/code-highlight': 2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.123.0)(snabbdom@3.6.3)
|
'@wangeditor-next/code-highlight': 2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.123.0)(snabbdom@3.6.3)
|
||||||
'@wangeditor-next/core': 1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)
|
'@wangeditor-next/core': 1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3)
|
||||||
'@wangeditor-next/list-module': 2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.123.0)(snabbdom@3.6.3)
|
'@wangeditor-next/list-module': 2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.123.0)(snabbdom@3.6.3)
|
||||||
'@wangeditor-next/table-module': 2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.debounce@4.0.8)(lodash.throttle@4.1.1)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)
|
'@wangeditor-next/table-module': 2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.debounce@4.0.8)(lodash.throttle@4.1.1)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)
|
||||||
'@wangeditor-next/upload-image-module': 2.0.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/basic-modules@2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.foreach@4.5.0)(slate@0.123.0)(snabbdom@3.6.3)
|
'@wangeditor-next/upload-image-module': 2.0.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/basic-modules@2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.throttle@4.1.1)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.foreach@4.5.0)(slate@0.123.0)(snabbdom@3.6.3)
|
||||||
'@wangeditor-next/video-module': 2.0.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)
|
'@wangeditor-next/video-module': 2.0.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(dom7@4.0.6)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)
|
||||||
dom7: 4.0.6
|
dom7: 4.0.6
|
||||||
is-hotkey: 0.2.0
|
is-hotkey: 0.2.0
|
||||||
lodash.camelcase: 4.3.0
|
lodash.camelcase: 4.3.0
|
||||||
@@ -2843,16 +2850,16 @@ snapshots:
|
|||||||
slate: 0.123.0
|
slate: 0.123.0
|
||||||
snabbdom: 3.6.3
|
snabbdom: 3.6.3
|
||||||
|
|
||||||
'@wangeditor-next/list-module@2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.123.0)(snabbdom@3.6.3)':
|
'@wangeditor-next/list-module@2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(dom7@4.0.6)(slate@0.123.0)(snabbdom@3.6.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@wangeditor-next/core': 1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)
|
'@wangeditor-next/core': 1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3)
|
||||||
dom7: 4.0.6
|
dom7: 4.0.6
|
||||||
slate: 0.123.0
|
slate: 0.123.0
|
||||||
snabbdom: 3.6.3
|
snabbdom: 3.6.3
|
||||||
|
|
||||||
'@wangeditor-next/table-module@2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.debounce@4.0.8)(lodash.throttle@4.1.1)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)':
|
'@wangeditor-next/table-module@2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.debounce@4.0.8)(lodash.throttle@4.1.1)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@wangeditor-next/core': 1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)
|
'@wangeditor-next/core': 1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3)
|
||||||
dom7: 4.0.6
|
dom7: 4.0.6
|
||||||
lodash.debounce: 4.0.8
|
lodash.debounce: 4.0.8
|
||||||
lodash.throttle: 4.1.1
|
lodash.throttle: 4.1.1
|
||||||
@@ -2860,22 +2867,22 @@ snapshots:
|
|||||||
slate: 0.123.0
|
slate: 0.123.0
|
||||||
snabbdom: 3.6.3
|
snabbdom: 3.6.3
|
||||||
|
|
||||||
'@wangeditor-next/upload-image-module@2.0.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/basic-modules@2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.foreach@4.5.0)(slate@0.123.0)(snabbdom@3.6.3)':
|
'@wangeditor-next/upload-image-module@2.0.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/basic-modules@2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.throttle@4.1.1)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.foreach@4.5.0)(slate@0.123.0)(snabbdom@3.6.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@uppy/core': 2.3.4
|
'@uppy/core': 2.3.4
|
||||||
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
|
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
|
||||||
'@wangeditor-next/basic-modules': 2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(lodash.throttle@4.1.1)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)
|
'@wangeditor-next/basic-modules': 2.0.0(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3)
|
||||||
'@wangeditor-next/core': 1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)
|
'@wangeditor-next/core': 1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3)
|
||||||
dom7: 4.0.6
|
dom7: 4.0.6
|
||||||
lodash.foreach: 4.5.0
|
lodash.foreach: 4.5.0
|
||||||
slate: 0.123.0
|
slate: 0.123.0
|
||||||
snabbdom: 3.6.3
|
snabbdom: 3.6.3
|
||||||
|
|
||||||
'@wangeditor-next/video-module@2.0.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3))(dom7@4.0.6)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)':
|
'@wangeditor-next/video-module@2.0.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor-next/core@1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3))(dom7@4.0.6)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@uppy/core': 2.3.4
|
'@uppy/core': 2.3.4
|
||||||
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
|
'@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4)
|
||||||
'@wangeditor-next/core': 1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@4.0.6)(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.11)(slate@0.123.0)(snabbdom@3.6.3)
|
'@wangeditor-next/core': 1.8.0(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(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.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.12)(slate@0.72.8)(snabbdom@3.6.3)
|
||||||
dom7: 4.0.6
|
dom7: 4.0.6
|
||||||
nanoid: 5.1.11
|
nanoid: 5.1.11
|
||||||
slate: 0.123.0
|
slate: 0.123.0
|
||||||
@@ -3822,6 +3829,10 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@napi-rs/canvas': 1.0.2
|
'@napi-rs/canvas': 1.0.2
|
||||||
|
|
||||||
|
pdfjs-dist@6.2.108:
|
||||||
|
optionalDependencies:
|
||||||
|
'@napi-rs/canvas': 1.0.2
|
||||||
|
|
||||||
picocolors@1.1.1: {}
|
picocolors@1.1.1: {}
|
||||||
|
|
||||||
picomatch@2.3.2: {}
|
picomatch@2.3.2: {}
|
||||||
@@ -4171,6 +4182,11 @@ snapshots:
|
|||||||
'@vue/devtools-api': 6.6.4
|
'@vue/devtools-api': 6.6.4
|
||||||
vue: 3.5.34
|
vue: 3.5.34
|
||||||
|
|
||||||
|
vue-pdf-embed@2.1.6(vue@3.5.34):
|
||||||
|
dependencies:
|
||||||
|
pdfjs-dist: 6.2.108
|
||||||
|
vue: 3.5.34
|
||||||
|
|
||||||
vue-router@4.6.4(vue@3.5.34):
|
vue-router@4.6.4(vue@3.5.34):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/devtools-api': 6.6.4
|
'@vue/devtools-api': 6.6.4
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 254 KiB |
|
Before Width: | Height: | Size: 310 KiB |
|
Before Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 254 KiB |
|
Before Width: | Height: | Size: 310 KiB |
|
Before Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 136 KiB |
@@ -4,6 +4,12 @@ const baseUrl = '/blade-transport/payment-application';
|
|||||||
export const getList = (current, size, params) =>
|
export const getList = (current, size, params) =>
|
||||||
request({ url: `${baseUrl}/list`, method: 'get', params: { current, size, ...params } });
|
request({ url: `${baseUrl}/list`, method: 'get', params: { current, size, ...params } });
|
||||||
export const getDetail = id => request({ url: `${baseUrl}/detail`, method: 'get', params: { id } });
|
export const getDetail = id => request({ url: `${baseUrl}/detail`, method: 'get', params: { id } });
|
||||||
|
export const getReferenceAmount = (paymentType, referenceId, excludeId) =>
|
||||||
|
request({
|
||||||
|
url: `${baseUrl}/reference-amount`,
|
||||||
|
method: 'get',
|
||||||
|
params: { paymentType, referenceId, excludeId: excludeId || undefined },
|
||||||
|
});
|
||||||
export const save = data => request({ url: `${baseUrl}/save`, method: 'post', data });
|
export const save = data => request({ url: `${baseUrl}/save`, method: 'post', data });
|
||||||
export const remove = id => request({ url: `${baseUrl}/remove`, method: 'post', params: { id } });
|
export const remove = id => request({ url: `${baseUrl}/remove`, method: 'post', params: { id } });
|
||||||
export const submit = data => request({ url: `${baseUrl}/submit`, method: 'post', data });
|
export const submit = data => request({ url: `${baseUrl}/submit`, method: 'post', data });
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
<template>
|
||||||
|
<div v-loading="loading" class="pdf-preview">
|
||||||
|
<el-empty v-if="error" description="PDF预览失败" :image-size="72" />
|
||||||
|
<vue-pdf-embed
|
||||||
|
v-else-if="source"
|
||||||
|
:key="source"
|
||||||
|
:source="source"
|
||||||
|
annotation-layer
|
||||||
|
text-layer
|
||||||
|
@loaded="handleLoaded"
|
||||||
|
@loading-failed="handleError"
|
||||||
|
@rendering-failed="handleError"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import VuePdfEmbed from 'vue-pdf-embed';
|
||||||
|
import 'vue-pdf-embed/dist/styles/annotationLayer.css';
|
||||||
|
import 'vue-pdf-embed/dist/styles/textLayer.css';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'PdfPreview',
|
||||||
|
components: { VuePdfEmbed },
|
||||||
|
props: {
|
||||||
|
source: {
|
||||||
|
type: [String, Object],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: ['error', 'loaded'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: true,
|
||||||
|
error: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
source: {
|
||||||
|
handler() {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = false;
|
||||||
|
},
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleLoaded(pdf) {
|
||||||
|
this.loading = false;
|
||||||
|
this.$emit('loaded', pdf);
|
||||||
|
},
|
||||||
|
handleError(error) {
|
||||||
|
this.loading = false;
|
||||||
|
this.error = true;
|
||||||
|
this.$emit('error', error);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.pdf-preview {
|
||||||
|
width: 100%;
|
||||||
|
height: 72vh;
|
||||||
|
overflow: auto;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
|
||||||
|
:deep(.vue-pdf-embed) {
|
||||||
|
width: min(100%, 1200px);
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.vue-pdf-embed__page) {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,333 @@
|
|||||||
|
<template>
|
||||||
|
<div class="vehicle-attachment-table">
|
||||||
|
<div class="vehicle-attachment-table__toolbar">
|
||||||
|
<el-button type="primary" :disabled="!rows.length" @click="batchDownload">
|
||||||
|
批量下载
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table :data="rows" border @selection-change="selectedRows = $event">
|
||||||
|
<el-table-column v-if="!readonly" type="selection" width="55" align="center" />
|
||||||
|
<el-table-column type="index" label="序号" width="70" align="center" />
|
||||||
|
<el-table-column label="文件名" min-width="240" show-overflow-tooltip>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<span
|
||||||
|
class="vehicle-attachment-table__file-name"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
@click="previewAttachment(row)"
|
||||||
|
@keydown.enter="previewAttachment(row)"
|
||||||
|
@keydown.space.prevent="previewAttachment(row)"
|
||||||
|
>
|
||||||
|
{{ attachmentName(row) }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="附件描述" min-width="220">
|
||||||
|
<template #default="{ row, $index }">
|
||||||
|
<span v-if="readonly">{{ row.description || '-' }}</span>
|
||||||
|
<el-input
|
||||||
|
v-else
|
||||||
|
:model-value="row.description"
|
||||||
|
maxlength="200"
|
||||||
|
placeholder="请输入"
|
||||||
|
@update:model-value="value => updateDescription($index, value)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="文件大小" width="120" align="center">
|
||||||
|
<template #default="{ row }">{{ formatFileSize(row.size) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="uploadUserName" label="上传人" width="140" align="center" />
|
||||||
|
<el-table-column prop="uploadTime" label="上传时间" width="180" align="center" sortable />
|
||||||
|
<el-table-column v-if="!readonly" label="操作" width="100" align="center" fixed="right">
|
||||||
|
<template #default="{ $index }">
|
||||||
|
<el-link type="danger" @click="removeAttachment($index)">删除</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<div v-if="!readonly" class="vehicle-attachment-table__upload">
|
||||||
|
<vehicle-attachment-upload
|
||||||
|
:model-value="rows"
|
||||||
|
:file-types="attachmentFileTypes"
|
||||||
|
:max-size="500"
|
||||||
|
:show-tip="true"
|
||||||
|
tip="支持pdf、bmp、jpeg、png、jpg、doc、docx、ppt、pptx、xlsx、xls、eml、msg、zip的文件格式,单个文件不超过500M"
|
||||||
|
:show-file-list="false"
|
||||||
|
button-text="上传附件"
|
||||||
|
@update:model-value="handleUploadChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
v-model="documentPreviewVisible"
|
||||||
|
:title="previewFile.name || '附件预览'"
|
||||||
|
append-to-body
|
||||||
|
destroy-on-close
|
||||||
|
width="90%"
|
||||||
|
top="4vh"
|
||||||
|
class="vehicle-attachment-table__viewer-dialog"
|
||||||
|
>
|
||||||
|
<pdf-preview
|
||||||
|
v-if="documentPreviewVisible && previewFile.url && previewFile.isPdf"
|
||||||
|
:source="previewFile.url"
|
||||||
|
@error="handlePreviewError"
|
||||||
|
/>
|
||||||
|
<open-file-viewer
|
||||||
|
v-else-if="documentPreviewVisible && previewFile.url"
|
||||||
|
:file="previewFile.url"
|
||||||
|
:file-name="previewFile.name"
|
||||||
|
:mime-type="previewFile.mimeType"
|
||||||
|
width="100%"
|
||||||
|
height="72vh"
|
||||||
|
fit="contain"
|
||||||
|
theme="auto"
|
||||||
|
locale="zh-CN"
|
||||||
|
:toolbar="viewerToolbar"
|
||||||
|
:plugins="viewerPlugins"
|
||||||
|
@unsupported="handlePreviewUnsupported"
|
||||||
|
@error="handlePreviewError"
|
||||||
|
/>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-image-viewer
|
||||||
|
v-if="imagePreviewVisible"
|
||||||
|
:url-list="imagePreviewUrls"
|
||||||
|
:initial-index="imagePreviewIndex"
|
||||||
|
@close="imagePreviewVisible = false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ElImageViewer } from 'element-plus';
|
||||||
|
import { OpenFileViewer } from '@open-file-viewer/vue';
|
||||||
|
import { fallbackPlugin, imagePlugin, officePlugin, textPlugin } from '@open-file-viewer/core';
|
||||||
|
import '@open-file-viewer/core/style.css';
|
||||||
|
import pdfWorkerSrc from 'pdfjs-dist/build/pdf.worker.mjs?url';
|
||||||
|
import PdfPreview from '@/components/pdf-preview/main.vue';
|
||||||
|
import { downloadFileByUrl } from '@/utils/util';
|
||||||
|
|
||||||
|
const attachmentFileTypes = [
|
||||||
|
'pdf',
|
||||||
|
'bmp',
|
||||||
|
'jpeg',
|
||||||
|
'png',
|
||||||
|
'jpg',
|
||||||
|
'doc',
|
||||||
|
'docx',
|
||||||
|
'ppt',
|
||||||
|
'pptx',
|
||||||
|
'xlsx',
|
||||||
|
'xls',
|
||||||
|
'eml',
|
||||||
|
'msg',
|
||||||
|
'zip',
|
||||||
|
];
|
||||||
|
|
||||||
|
const viewerPlugins = [
|
||||||
|
imagePlugin(),
|
||||||
|
officePlugin({ pdf: { workerSrc: pdfWorkerSrc, useFetchData: true } }),
|
||||||
|
textPlugin(),
|
||||||
|
fallbackPlugin(),
|
||||||
|
];
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'VehicleAttachmentTable',
|
||||||
|
components: {
|
||||||
|
ElImageViewer,
|
||||||
|
OpenFileViewer,
|
||||||
|
PdfPreview,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
modelValue: {
|
||||||
|
type: [Array, String, Object],
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
readonly: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: ['update:modelValue'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
attachmentFileTypes,
|
||||||
|
selectedRows: [],
|
||||||
|
imagePreviewVisible: false,
|
||||||
|
imagePreviewUrls: [],
|
||||||
|
imagePreviewIndex: 0,
|
||||||
|
documentPreviewVisible: false,
|
||||||
|
previewFile: {},
|
||||||
|
viewerPlugins,
|
||||||
|
viewerToolbar: {
|
||||||
|
download: true,
|
||||||
|
fullscreen: true,
|
||||||
|
print: true,
|
||||||
|
rotate: true,
|
||||||
|
zoom: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
rows() {
|
||||||
|
if (Array.isArray(this.modelValue)) return this.modelValue;
|
||||||
|
if (this.modelValue && typeof this.modelValue === 'object') return [this.modelValue];
|
||||||
|
if (!this.modelValue) return [];
|
||||||
|
try {
|
||||||
|
const rows = JSON.parse(this.modelValue);
|
||||||
|
return Array.isArray(rows) ? rows : [];
|
||||||
|
} catch (error) {
|
||||||
|
return String(this.modelValue)
|
||||||
|
.split(',')
|
||||||
|
.map(item => item.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
.map(item => ({ name: item, url: item }));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
attachmentName(row = {}) {
|
||||||
|
return row.originalName || row.name || row.fileName || '附件';
|
||||||
|
},
|
||||||
|
attachmentUrl(row = {}) {
|
||||||
|
return row.url || row.link || row.fileUrl || row.downloadUrl || row.domain || row.src || '';
|
||||||
|
},
|
||||||
|
attachmentExtension(row = {}) {
|
||||||
|
const source = String(this.attachmentName(row) || this.attachmentUrl(row)).split('?')[0];
|
||||||
|
const index = source.lastIndexOf('.');
|
||||||
|
return index > -1 ? source.slice(index + 1).toLowerCase() : '';
|
||||||
|
},
|
||||||
|
isImage(row) {
|
||||||
|
return ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(this.attachmentExtension(row));
|
||||||
|
},
|
||||||
|
isPdf(row) {
|
||||||
|
const mimeType = String(row.mimeType || row.contentType || '').toLowerCase();
|
||||||
|
return mimeType.includes('application/pdf') || this.attachmentExtension(row) === 'pdf';
|
||||||
|
},
|
||||||
|
emitRows(rows) {
|
||||||
|
this.$emit('update:modelValue', rows);
|
||||||
|
},
|
||||||
|
handleUploadChange(rows) {
|
||||||
|
const uploadUserName = this.$store.getters.userInfo?.realName || '';
|
||||||
|
const uploadTime = this.$dayjs().format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
this.emitRows(
|
||||||
|
(rows || []).map(row => ({
|
||||||
|
...row,
|
||||||
|
description: row.description || '',
|
||||||
|
uploadUserName: row.uploadUserName || uploadUserName,
|
||||||
|
uploadTime: row.uploadTime || uploadTime,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
},
|
||||||
|
updateDescription(index, description) {
|
||||||
|
const rows = this.rows.map((row, rowIndex) =>
|
||||||
|
rowIndex === index ? { ...row, description } : row
|
||||||
|
);
|
||||||
|
this.emitRows(rows);
|
||||||
|
},
|
||||||
|
removeAttachment(index) {
|
||||||
|
const rows = [...this.rows];
|
||||||
|
rows.splice(index, 1);
|
||||||
|
this.emitRows(rows);
|
||||||
|
},
|
||||||
|
formatFileSize(size) {
|
||||||
|
if (!size) return '';
|
||||||
|
const value = Number(size);
|
||||||
|
if (!Number.isFinite(value)) return String(size);
|
||||||
|
if (value < 1024) return `${value}B`;
|
||||||
|
if (value < 1024 * 1024) return `${(value / 1024).toFixed(1)}KB`;
|
||||||
|
return `${(value / 1024 / 1024).toFixed(1)}MB`;
|
||||||
|
},
|
||||||
|
downloadAttachment(row) {
|
||||||
|
const url = this.attachmentUrl(row);
|
||||||
|
if (!url) {
|
||||||
|
this.$message.warning('附件地址为空,无法下载');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
downloadFileByUrl(url, this.attachmentName(row));
|
||||||
|
},
|
||||||
|
batchDownload() {
|
||||||
|
const rows = this.selectedRows.length ? this.selectedRows : this.rows;
|
||||||
|
rows.forEach(this.downloadAttachment);
|
||||||
|
},
|
||||||
|
previewAttachment(row) {
|
||||||
|
const url = this.attachmentUrl(row);
|
||||||
|
if (!url) {
|
||||||
|
this.$message.warning('附件地址为空,无法预览');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.isImage(row)) {
|
||||||
|
this.imagePreviewUrls = this.rows
|
||||||
|
.filter(item => this.isImage(item) && this.attachmentUrl(item))
|
||||||
|
.map(item => this.attachmentUrl(item));
|
||||||
|
this.imagePreviewIndex = Math.max(this.imagePreviewUrls.indexOf(url), 0);
|
||||||
|
this.imagePreviewVisible = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const isPdf = this.isPdf(row);
|
||||||
|
this.previewFile = {
|
||||||
|
name: this.attachmentName(row),
|
||||||
|
url,
|
||||||
|
mimeType: isPdf ? 'application/pdf' : row.mimeType || row.contentType || '',
|
||||||
|
isPdf,
|
||||||
|
};
|
||||||
|
this.documentPreviewVisible = true;
|
||||||
|
},
|
||||||
|
handlePreviewUnsupported() {
|
||||||
|
this.$message.warning('当前文件暂不支持在线预览');
|
||||||
|
},
|
||||||
|
handlePreviewError() {
|
||||||
|
this.$message.error('附件预览失败');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.vehicle-attachment-table {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&__toolbar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__file-name {
|
||||||
|
color: #409eff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__file-name:hover,
|
||||||
|
&__file-name:focus-visible {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__upload {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
margin-top: 12px;
|
||||||
|
|
||||||
|
:deep(.vehicle-attachment-upload) {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-table th.el-table__cell) {
|
||||||
|
height: 42px;
|
||||||
|
padding: 8px 0;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-table td.el-table__cell) {
|
||||||
|
height: 52px;
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.vehicle-attachment-table__viewer-dialog .el-dialog__body) {
|
||||||
|
padding: 12px 16px 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -85,6 +85,7 @@ export const option = {
|
|||||||
type: 'number',
|
type: 'number',
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 999,
|
max: 999,
|
||||||
|
formatter: row => (Number(row.defaultFinishDays) === -1 ? '' : row.defaultFinishDays),
|
||||||
span: 12,
|
span: 12,
|
||||||
minWidth: 170,
|
minWidth: 170,
|
||||||
addDisplay: false,
|
addDisplay: false,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export const option = {
|
|||||||
searchMenuPosition: 'right',
|
searchMenuPosition: 'right',
|
||||||
border: true,
|
border: true,
|
||||||
index: true,
|
index: true,
|
||||||
selection: false,
|
selection: true,
|
||||||
addBtn: false,
|
addBtn: false,
|
||||||
editBtn: false,
|
editBtn: false,
|
||||||
delBtn: false,
|
delBtn: false,
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '附件',
|
label: '附件',
|
||||||
prop: 'attachments',
|
prop: 'attachments',
|
||||||
|
hide: true,
|
||||||
span: 24,
|
span: 24,
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
slot: true,
|
slot: true,
|
||||||
|
|||||||
@@ -29,6 +29,12 @@ export const shipInspectionTypeDic = [
|
|||||||
{ label: '其他', value: '其他' },
|
{ label: '其他', value: '其他' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const passengerTypeLevelDic = [
|
||||||
|
{ label: '一级', value: '一级' },
|
||||||
|
{ label: '二级', value: '二级' },
|
||||||
|
{ label: '其他', value: '其他' },
|
||||||
|
];
|
||||||
|
|
||||||
export const option = {
|
export const option = {
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
calcHeight: 32,
|
calcHeight: 32,
|
||||||
@@ -128,10 +134,11 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '客车类型及等级',
|
label: '客车类型及等级',
|
||||||
prop: 'passengerTypeLevel',
|
prop: 'passengerTypeLevel',
|
||||||
|
type: 'select',
|
||||||
|
dicData: passengerTypeLevelDic,
|
||||||
minWidth: 150,
|
minWidth: 150,
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '请输入',
|
placeholder: '请选择',
|
||||||
rules: [{ max: 50, message: '最多 50 个字符', trigger: 'blur' }],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '检测评定单位',
|
label: '检测评定单位',
|
||||||
@@ -177,6 +184,7 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '附件',
|
label: '附件',
|
||||||
prop: 'attachments',
|
prop: 'attachments',
|
||||||
|
hide: true,
|
||||||
span: 24,
|
span: 24,
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
slot: true,
|
slot: true,
|
||||||
|
|||||||
@@ -42,11 +42,12 @@ export const option = {
|
|||||||
prop: 'vehicleType',
|
prop: 'vehicleType',
|
||||||
type: 'radio',
|
type: 'radio',
|
||||||
dicData: vehicleTypeDic,
|
dicData: vehicleTypeDic,
|
||||||
|
formslot: true,
|
||||||
value: '车辆',
|
value: '车辆',
|
||||||
search: true,
|
search: true,
|
||||||
searchOrder: 3,
|
searchOrder: 3,
|
||||||
span: 24,
|
span: 24,
|
||||||
order: 1,
|
order: 11,
|
||||||
minWidth: 110,
|
minWidth: 110,
|
||||||
rules: [{ required: true, message: '请选择车船类型', trigger: 'change' }],
|
rules: [{ required: true, message: '请选择车船类型', trigger: 'change' }],
|
||||||
},
|
},
|
||||||
@@ -58,9 +59,9 @@ export const option = {
|
|||||||
search: true,
|
search: true,
|
||||||
searchOrder: 4,
|
searchOrder: 4,
|
||||||
span: 12,
|
span: 12,
|
||||||
order: 2,
|
order: 10,
|
||||||
minWidth: 140,
|
minWidth: 140,
|
||||||
rules: [{ required: true, message: '请输入车牌号/船号', trigger: 'blur' }],
|
rules: [{ required: true, message: '请选择车牌号/船号', trigger: 'change' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '设备号',
|
label: '设备号',
|
||||||
@@ -69,7 +70,7 @@ export const option = {
|
|||||||
search: true,
|
search: true,
|
||||||
searchOrder: 2,
|
searchOrder: 2,
|
||||||
span: 12,
|
span: 12,
|
||||||
order: 3,
|
order: 9,
|
||||||
minWidth: 150,
|
minWidth: 150,
|
||||||
rules: [{ required: true, message: '设备编号由系统生成', trigger: 'blur' }],
|
rules: [{ required: true, message: '设备编号由系统生成', trigger: 'blur' }],
|
||||||
},
|
},
|
||||||
@@ -77,7 +78,7 @@ export const option = {
|
|||||||
label: '设备名称',
|
label: '设备名称',
|
||||||
prop: 'equipmentName',
|
prop: 'equipmentName',
|
||||||
span: 12,
|
span: 12,
|
||||||
order: 4,
|
order: 8,
|
||||||
minWidth: 150,
|
minWidth: 150,
|
||||||
rules: [
|
rules: [
|
||||||
{ required: true, message: '请输入设备名称', trigger: 'blur' },
|
{ required: true, message: '请输入设备名称', trigger: 'blur' },
|
||||||
@@ -92,14 +93,14 @@ export const option = {
|
|||||||
format: 'YYYY-MM-DD',
|
format: 'YYYY-MM-DD',
|
||||||
valueFormat: 'YYYY-MM-DD',
|
valueFormat: 'YYYY-MM-DD',
|
||||||
span: 12,
|
span: 12,
|
||||||
order: 8,
|
order: 4,
|
||||||
minWidth: 130,
|
minWidth: 130,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '设备品牌',
|
label: '设备品牌',
|
||||||
prop: 'equipmentBrand',
|
prop: 'equipmentBrand',
|
||||||
span: 12,
|
span: 12,
|
||||||
order: 5,
|
order: 7,
|
||||||
minWidth: 130,
|
minWidth: 130,
|
||||||
rules: [{ max: 50, message: '最多 50 个字符', trigger: 'blur' }],
|
rules: [{ max: 50, message: '最多 50 个字符', trigger: 'blur' }],
|
||||||
},
|
},
|
||||||
@@ -117,7 +118,7 @@ export const option = {
|
|||||||
label: '规格型号',
|
label: '规格型号',
|
||||||
prop: 'specificationModel',
|
prop: 'specificationModel',
|
||||||
span: 12,
|
span: 12,
|
||||||
order: 7,
|
order: 5,
|
||||||
minWidth: 150,
|
minWidth: 150,
|
||||||
rules: [{ max: 100, message: '最多 100 个字符', trigger: 'blur' }],
|
rules: [{ max: 100, message: '最多 100 个字符', trigger: 'blur' }],
|
||||||
},
|
},
|
||||||
@@ -127,7 +128,7 @@ export const option = {
|
|||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
minRows: 2,
|
minRows: 2,
|
||||||
span: 24,
|
span: 24,
|
||||||
order: 10,
|
order: 2,
|
||||||
minWidth: 180,
|
minWidth: 180,
|
||||||
overHidden: true,
|
overHidden: true,
|
||||||
rules: [{ max: 200, message: '最多 200 个字符', trigger: 'blur' }],
|
rules: [{ max: 200, message: '最多 200 个字符', trigger: 'blur' }],
|
||||||
@@ -170,7 +171,7 @@ export const option = {
|
|||||||
label: '原厂设备号',
|
label: '原厂设备号',
|
||||||
prop: 'originalEquipmentNo',
|
prop: 'originalEquipmentNo',
|
||||||
span: 12,
|
span: 12,
|
||||||
order: 9,
|
order: 3,
|
||||||
hide: true,
|
hide: true,
|
||||||
rules: [{ max: 100, message: '最多 100 个字符', trigger: 'blur' }],
|
rules: [{ max: 100, message: '最多 100 个字符', trigger: 'blur' }],
|
||||||
},
|
},
|
||||||
@@ -180,7 +181,8 @@ export const option = {
|
|||||||
slot: true,
|
slot: true,
|
||||||
formslot: true,
|
formslot: true,
|
||||||
span: 24,
|
span: 24,
|
||||||
order: 11,
|
order: 1,
|
||||||
|
minWidth: 100,
|
||||||
hide: true,
|
hide: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '附件',
|
label: '附件',
|
||||||
prop: 'attachments',
|
prop: 'attachments',
|
||||||
|
hide: true,
|
||||||
span: 24,
|
span: 24,
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
slot: true,
|
slot: true,
|
||||||
|
|||||||
@@ -12,11 +12,6 @@ const validateNonNegative = (rule, value, callback) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const vehicleTypeDic = [
|
|
||||||
{ label: '车辆', value: '车辆' },
|
|
||||||
{ label: '船舶', value: '船舶' },
|
|
||||||
];
|
|
||||||
|
|
||||||
export const option = {
|
export const option = {
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
calcHeight: 32,
|
calcHeight: 32,
|
||||||
@@ -43,18 +38,7 @@ export const option = {
|
|||||||
menuFixed: 'right',
|
menuFixed: 'right',
|
||||||
column: [
|
column: [
|
||||||
{
|
{
|
||||||
label: '车船类型',
|
label: '车牌号',
|
||||||
prop: 'vehicleType',
|
|
||||||
type: 'radio',
|
|
||||||
dicData: vehicleTypeDic,
|
|
||||||
value: '车辆',
|
|
||||||
search: true,
|
|
||||||
searchSpan: 6,
|
|
||||||
minWidth: 110,
|
|
||||||
rules: [{ required: true, message: '请选择车船类型', trigger: 'change' }],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '车牌号/船号',
|
|
||||||
prop: 'vehicleNo',
|
prop: 'vehicleNo',
|
||||||
slot: true,
|
slot: true,
|
||||||
formslot: true,
|
formslot: true,
|
||||||
@@ -62,7 +46,7 @@ export const option = {
|
|||||||
searchSpan: 6,
|
searchSpan: 6,
|
||||||
minWidth: 130,
|
minWidth: 130,
|
||||||
rules: [
|
rules: [
|
||||||
{ required: true, message: '请输入车牌号/船号', trigger: 'blur' },
|
{ required: true, message: '请输入车牌号', trigger: 'blur' },
|
||||||
{ max: 30, message: '最多 30 个字符', trigger: 'blur' },
|
{ max: 30, message: '最多 30 个字符', trigger: 'blur' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -106,19 +90,6 @@ export const option = {
|
|||||||
slot: true,
|
slot: true,
|
||||||
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: '里程单位',
|
|
||||||
prop: 'mileageUnit',
|
|
||||||
type: 'select',
|
|
||||||
dicData: [
|
|
||||||
{ label: '公里', value: '公里' },
|
|
||||||
{ label: '海里', value: '海里' },
|
|
||||||
],
|
|
||||||
value: '公里',
|
|
||||||
hide: true,
|
|
||||||
display: false,
|
|
||||||
search: false,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: '备注',
|
label: '备注',
|
||||||
prop: 'remark',
|
prop: 'remark',
|
||||||
@@ -132,6 +103,7 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '附件',
|
label: '附件',
|
||||||
prop: 'attachments',
|
prop: 'attachments',
|
||||||
|
hide: true,
|
||||||
span: 24,
|
span: 24,
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
slot: true,
|
slot: true,
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '卡号',
|
label: '卡号',
|
||||||
prop: 'cardNo',
|
prop: 'cardNo',
|
||||||
|
span: 12,
|
||||||
|
order: 1,
|
||||||
minWidth: 150,
|
minWidth: 150,
|
||||||
rules: [{ max: 30, message: '最多 30 个字符', trigger: 'blur' }],
|
rules: [{ max: 30, message: '最多 30 个字符', trigger: 'blur' }],
|
||||||
},
|
},
|
||||||
@@ -56,6 +58,7 @@ export const option = {
|
|||||||
type: 'datetime',
|
type: 'datetime',
|
||||||
format: 'YYYY-MM-DD HH:mm',
|
format: 'YYYY-MM-DD HH:mm',
|
||||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
span: 12,
|
||||||
minWidth: 170,
|
minWidth: 170,
|
||||||
rules: [{ required: true, message: '请选择交易时间', trigger: 'click' }],
|
rules: [{ required: true, message: '请选择交易时间', trigger: 'click' }],
|
||||||
},
|
},
|
||||||
@@ -66,6 +69,8 @@ export const option = {
|
|||||||
dicData: vehicleTypeDic,
|
dicData: vehicleTypeDic,
|
||||||
value: '车辆',
|
value: '车辆',
|
||||||
search: true,
|
search: true,
|
||||||
|
span: 24,
|
||||||
|
order: 2,
|
||||||
minWidth: 110,
|
minWidth: 110,
|
||||||
rules: [{ required: true, message: '请选择车船类型', trigger: 'change' }],
|
rules: [{ required: true, message: '请选择车船类型', trigger: 'change' }],
|
||||||
},
|
},
|
||||||
@@ -166,6 +171,7 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '附件',
|
label: '附件',
|
||||||
prop: 'attachments',
|
prop: 'attachments',
|
||||||
|
hide: true,
|
||||||
span: 24,
|
span: 24,
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
slot: true,
|
slot: true,
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '附件',
|
label: '附件',
|
||||||
prop: 'attachments',
|
prop: 'attachments',
|
||||||
|
hide: true,
|
||||||
span: 24,
|
span: 24,
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
slot: true,
|
slot: true,
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '附件',
|
label: '附件',
|
||||||
prop: 'attachments',
|
prop: 'attachments',
|
||||||
|
hide: true,
|
||||||
span: 24,
|
span: 24,
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
slot: true,
|
slot: true,
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '附件',
|
label: '附件',
|
||||||
prop: 'attachments',
|
prop: 'attachments',
|
||||||
|
hide: true,
|
||||||
span: 24,
|
span: 24,
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
slot: true,
|
slot: true,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export const processStatusDic = [
|
|||||||
export const option = {
|
export const option = {
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
calcHeight: 32,
|
calcHeight: 32,
|
||||||
dialogWidth: 960,
|
dialogWidth: 1200,
|
||||||
labelPosition: 'right',
|
labelPosition: 'right',
|
||||||
labelWidth: 'auto',
|
labelWidth: 'auto',
|
||||||
searchLabelWidth: 88,
|
searchLabelWidth: 88,
|
||||||
@@ -208,6 +208,7 @@ export const option = {
|
|||||||
{
|
{
|
||||||
label: '附件',
|
label: '附件',
|
||||||
prop: 'attachments',
|
prop: 'attachments',
|
||||||
|
hide: true,
|
||||||
span: 24,
|
span: 24,
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
slot: true,
|
slot: true,
|
||||||
|
|||||||
@@ -82,7 +82,7 @@
|
|||||||
filterable
|
filterable
|
||||||
:loading="districtLoading"
|
:loading="districtLoading"
|
||||||
:disabled="!form.cityCode"
|
:disabled="!form.cityCode"
|
||||||
:placeholder="form.cityCode ? '请选择区县' : '请先选择城市'"
|
placeholder="请选择 所属区县"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="handleDistrictChange"
|
@change="handleDistrictChange"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -136,7 +136,7 @@
|
|||||||
filterable
|
filterable
|
||||||
:loading="cityLoading"
|
:loading="cityLoading"
|
||||||
:disabled="isCityDisabled"
|
:disabled="isCityDisabled"
|
||||||
:placeholder="isParentRegionLocked ? '自动带出' : '请先选择国家'"
|
placeholder="请选择"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="handleCityChange"
|
@change="handleCityChange"
|
||||||
>
|
>
|
||||||
@@ -155,9 +155,7 @@
|
|||||||
filterable
|
filterable
|
||||||
:loading="districtLoading"
|
:loading="districtLoading"
|
||||||
:disabled="isDistrictDisabled"
|
:disabled="isDistrictDisabled"
|
||||||
:placeholder="
|
placeholder="请选择"
|
||||||
isParentRegionLocked ? '自动带出' : form.cityCode ? '请选择区县' : '选择城市后再选择区县'
|
|
||||||
"
|
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="handleDistrictChange"
|
@change="handleDistrictChange"
|
||||||
>
|
>
|
||||||
@@ -443,7 +441,7 @@ export default {
|
|||||||
hide: true,
|
hide: true,
|
||||||
span: 12,
|
span: 12,
|
||||||
order: 88,
|
order: 88,
|
||||||
placeholder: '自动带出',
|
placeholder: '请选择',
|
||||||
rules: [{ required: true, message: '请选择所属城市', trigger: 'change' }],
|
rules: [{ required: true, message: '请选择所属城市', trigger: 'change' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -472,7 +470,7 @@ export default {
|
|||||||
},
|
},
|
||||||
dicData: [],
|
dicData: [],
|
||||||
span: 12,
|
span: 12,
|
||||||
placeholder: '选择城市后再选择区县',
|
placeholder: '请选择',
|
||||||
rules: [{ required: true, message: '请选择区县', trigger: 'change' }],
|
rules: [{ required: true, message: '请选择区县', trigger: 'change' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1257,6 +1255,7 @@ export default {
|
|||||||
'港口码头主数据',
|
'港口码头主数据',
|
||||||
() => {
|
() => {
|
||||||
this.loadPortOptions();
|
this.loadPortOptions();
|
||||||
|
this.onLoad(this.page, this.query);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -82,7 +82,7 @@
|
|||||||
filterable
|
filterable
|
||||||
:loading="districtLoading"
|
:loading="districtLoading"
|
||||||
:disabled="!form.cityCode"
|
:disabled="!form.cityCode"
|
||||||
:placeholder="form.cityCode ? '请选择区县' : '请先选择城市'"
|
placeholder="请选择 所属区县"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
@change="handleDistrictChange"
|
@change="handleDistrictChange"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -8651,15 +8651,18 @@ export default {
|
|||||||
handleTaskDriverSelect(target, item = {}) {
|
handleTaskDriverSelect(target, item = {}) {
|
||||||
const value = item.driverName || item.name || '';
|
const value = item.driverName || item.name || '';
|
||||||
const driverPhone = item.mobile || item.phone || item.driverPhone || '';
|
const driverPhone = item.mobile || item.phone || item.driverPhone || '';
|
||||||
|
const drivingVehicle = String(item.drivingVehicle || '').trim();
|
||||||
if (target === 'dispatch') {
|
if (target === 'dispatch') {
|
||||||
this.dispatchItemForm.driverId = item.id || '';
|
this.dispatchItemForm.driverId = item.id || '';
|
||||||
this.dispatchItemForm.driverName = value;
|
this.dispatchItemForm.driverName = value;
|
||||||
if (driverPhone) this.dispatchItemForm.driverPhone = driverPhone;
|
if (driverPhone) this.dispatchItemForm.driverPhone = driverPhone;
|
||||||
|
if (drivingVehicle) this.dispatchItemForm.vehicleNo = drivingVehicle;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.form.driverId = item.id || '';
|
this.form.driverId = item.id || '';
|
||||||
this.form.driverName = value;
|
this.form.driverName = value;
|
||||||
if (driverPhone) this.form.driverPhone = driverPhone;
|
if (driverPhone) this.form.driverPhone = driverPhone;
|
||||||
|
if (drivingVehicle) this.form.vehicleNo = drivingVehicle;
|
||||||
},
|
},
|
||||||
handleTaskDriverChange(value) {
|
handleTaskDriverChange(value) {
|
||||||
const driver = this.taskDriverOptions.find(item =>
|
const driver = this.taskDriverOptions.find(item =>
|
||||||
@@ -8670,6 +8673,9 @@ export default {
|
|||||||
if (driver) {
|
if (driver) {
|
||||||
this.form.driverPhone =
|
this.form.driverPhone =
|
||||||
driver.mobile || driver.phone || driver.driverPhone || this.form.driverPhone || '';
|
driver.mobile || driver.phone || driver.driverPhone || this.form.driverPhone || '';
|
||||||
|
if (String(driver.drivingVehicle || '').trim()) {
|
||||||
|
this.form.vehicleNo = String(driver.drivingVehicle).trim();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getTaskCargoTypeOptionsKey(path = []) {
|
getTaskCargoTypeOptionsKey(path = []) {
|
||||||
@@ -12348,6 +12354,9 @@ export default {
|
|||||||
driver.driverPhone ||
|
driver.driverPhone ||
|
||||||
this.dispatchItemForm.driverPhone ||
|
this.dispatchItemForm.driverPhone ||
|
||||||
'';
|
'';
|
||||||
|
if (String(driver.drivingVehicle || '').trim()) {
|
||||||
|
this.dispatchItemForm.vehicleNo = String(driver.drivingVehicle).trim();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getDispatchCargoRowOptions(row = {}) {
|
getDispatchCargoRowOptions(row = {}) {
|
||||||
|
|||||||
@@ -543,7 +543,12 @@ export default {
|
|||||||
driverOptionKey(item) { return item.id || item.driverId || this.driverOptionLabel(item) || item.mobile; },
|
driverOptionKey(item) { return item.id || item.driverId || this.driverOptionLabel(item) || item.mobile; },
|
||||||
handleDriverChange(route, value) {
|
handleDriverChange(route, value) {
|
||||||
const driver = this.driverOptions.find(item => this.driverOptionLabel(item) === value);
|
const driver = this.driverOptions.find(item => this.driverOptionLabel(item) === value);
|
||||||
if (driver) route.driverPhone = driver.mobile || driver.driverPhone || driver.phone || '';
|
if (driver) {
|
||||||
|
route.driverPhone = driver.mobile || driver.driverPhone || driver.phone || '';
|
||||||
|
if (String(driver.drivingVehicle || '').trim()) {
|
||||||
|
route.vehicleNo = String(driver.drivingVehicle).trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async loadCarrierOptions() {
|
async loadCarrierOptions() {
|
||||||
this.carrierLoading = true;
|
this.carrierLoading = true;
|
||||||
@@ -577,6 +582,8 @@ export default {
|
|||||||
route.driverName = this.driverOptionLabel(item);
|
route.driverName = this.driverOptionLabel(item);
|
||||||
route.driverId = item.id || item.driverId || '';
|
route.driverId = item.id || item.driverId || '';
|
||||||
route.driverPhone = item.mobile || item.driverPhone || item.phone || route.driverPhone || '';
|
route.driverPhone = item.mobile || item.driverPhone || item.phone || route.driverPhone || '';
|
||||||
|
const drivingVehicle = String(item.drivingVehicle || '').trim();
|
||||||
|
if (drivingVehicle) route.vehicleNo = drivingVehicle;
|
||||||
},
|
},
|
||||||
setDriverInput(segmentNo, element) {
|
setDriverInput(segmentNo, element) {
|
||||||
if (element) this.driverInputs[segmentNo] = element;
|
if (element) this.driverInputs[segmentNo] = element;
|
||||||
|
|||||||
@@ -1,26 +1,32 @@
|
|||||||
<template>
|
<template>
|
||||||
<basic-container class="contract-change-page">
|
<basic-container class="contract-change-page">
|
||||||
<el-form ref="formRef" :model="form" :rules="rules" label-position="right" label-width="auto">
|
<el-form ref="formRef" :model="form" :rules="rules" label-position="right" label-width="auto" class="contract-change-form">
|
||||||
<section class="change-section">
|
<section class="change-section contract-basic-section">
|
||||||
<div class="dialog-section-title">基本信息</div>
|
<div class="dialog-section-title">基本信息</div>
|
||||||
<el-row :gutter="28">
|
<div class="contract-basic-section__grid">
|
||||||
<el-col :span="24"><el-form-item label="变更类型"><el-radio-group v-model="form.changeType"><el-radio label="合同信息变更" /><el-radio label="终止合同" /></el-radio-group></el-form-item></el-col>
|
<el-form-item label="变更类型" class="contract-basic-section__change-type"><el-radio-group v-model="form.changeType"><el-radio label="合同信息变更" /><el-radio label="终止合同" /></el-radio-group></el-form-item>
|
||||||
<el-col :span="6"><el-form-item label="合同编号"><el-input v-model="form.contractNo" disabled /></el-form-item></el-col>
|
<el-form-item label="合同编号"><el-input v-model="form.contractNo" disabled /></el-form-item>
|
||||||
<el-col :span="6"><el-form-item label="合同名称" prop="contractName"><el-input v-model="form.contractName" /></el-form-item></el-col>
|
<el-form-item label="合同名称" prop="contractName"><el-input v-model="form.contractName" /></el-form-item>
|
||||||
<el-col :span="6"><el-form-item label="合同类型"><el-select v-model="form.contractCategory" disabled><el-option label="客户合同" value="客户合同" /><el-option label="承运商合同" value="承运商合同" /></el-select></el-form-item></el-col>
|
<el-form-item label="合同类型"><el-select v-model="form.contractCategory" disabled><el-option label="客户合同" value="客户合同" /><el-option label="承运商合同" value="承运商合同" /></el-select></el-form-item>
|
||||||
<el-col :span="6"><el-form-item label="甲方"><el-input v-model="form.partyA" disabled /></el-form-item></el-col>
|
<el-form-item label="甲方"><el-input v-model="form.partyA" disabled /></el-form-item>
|
||||||
<el-col :span="6"><el-form-item label="乙方"><el-input v-model="form.partyB" disabled /></el-form-item></el-col>
|
<el-form-item label="乙方"><el-input v-model="form.partyB" disabled /></el-form-item>
|
||||||
<el-col :span="6"><el-form-item label="所属项目"><el-input v-model="form.projectName" disabled /></el-form-item></el-col>
|
<el-form-item label="所属项目"><el-input v-model="form.projectName" disabled /></el-form-item>
|
||||||
<el-col :span="6"><el-form-item label="合同期限"><el-date-picker v-model="period" type="daterange" value-format="YYYY-MM-DD" range-separator="至" /></el-form-item></el-col>
|
<el-form-item label="合同期限">
|
||||||
<el-col :span="6"><el-form-item label="所属组织"><el-input v-model="form.organizationName" disabled /></el-form-item></el-col>
|
<div class="contract-basic-section__date-range">
|
||||||
<el-col :span="6"><el-form-item label="签订日期"><el-date-picker v-model="form.signDate" type="date" value-format="YYYY-MM-DD" disabled /></el-form-item></el-col>
|
<el-date-picker v-model="period[0]" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" placeholder="YYYY-MM-DD" />
|
||||||
<el-col :span="6"><el-form-item label="合同格式"><el-select v-model="form.contractFormat"><el-option label="电子合同" value="电子合同" /><el-option label="纸质合同" value="纸质合同" /></el-select></el-form-item></el-col>
|
<span>至</span>
|
||||||
<el-col :span="6"><el-form-item label="结算方式"><el-input v-model="form.settlementMode" /></el-form-item></el-col>
|
<el-date-picker v-model="period[1]" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" placeholder="YYYY-MM-DD" />
|
||||||
<el-col :span="6"><el-form-item label="是否需要加盖法人章"><el-select v-model="form.legalSealFlag"><el-option label="是" :value="1" /><el-option label="否" :value="0" /></el-select></el-form-item></el-col>
|
</div>
|
||||||
<el-col :span="6"><el-form-item label="一式(份)"><div class="inline-field"><el-input-number v-model="form.copyCount" :min="1" controls-position="right" /></div></el-form-item></el-col>
|
</el-form-item>
|
||||||
<el-col :span="6"><el-form-item label="回款账期(天)"><el-input-number v-model="form.paymentDays" :min="0" controls-position="right" /></el-form-item></el-col>
|
<el-form-item label="所属组织"><el-input v-model="form.organizationName" disabled /></el-form-item>
|
||||||
<el-col :span="24"><el-form-item label="备注"><el-input v-model="form.remark" type="textarea" maxlength="2000" show-word-limit /></el-form-item></el-col>
|
<el-form-item label="签订日期"><el-date-picker v-model="form.signDate" type="date" value-format="YYYY-MM-DD" disabled /></el-form-item>
|
||||||
</el-row>
|
<el-form-item label="合同格式"><el-select v-model="form.contractFormat"><el-option label="电子合同" value="电子合同" /><el-option label="纸质合同" value="纸质合同" /></el-select></el-form-item>
|
||||||
|
<el-form-item label="结算方式"><el-input v-model="form.settlementMode" /></el-form-item>
|
||||||
|
<el-form-item label="是否需要加盖法人章"><el-select v-model="form.legalSealFlag"><el-option label="是" :value="1" /><el-option label="否" :value="0" /></el-select></el-form-item>
|
||||||
|
<el-form-item label="一式(份)"><el-input v-model="form.copyCount" inputmode="numeric" maxlength="9" placeholder="请输入" @input="value => positiveIntegerInput('copyCount', value)" /></el-form-item>
|
||||||
|
<el-form-item label="回款账期(天)"><el-input v-model="form.paymentDays" inputmode="numeric" maxlength="9" placeholder="请输入" @input="value => positiveIntegerInput('paymentDays', value)" /></el-form-item>
|
||||||
|
</div>
|
||||||
|
<el-form-item label="备注" class="contract-basic-section__remark"><el-input v-model="form.remark" type="textarea" :rows="2" maxlength="2000" show-word-limit placeholder="请输入备注" /></el-form-item>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="change-section">
|
<section class="change-section">
|
||||||
@@ -103,10 +109,10 @@ const viewerPlugins = [
|
|||||||
textPlugin(),
|
textPlugin(),
|
||||||
fallbackPlugin(),
|
fallbackPlugin(),
|
||||||
];
|
];
|
||||||
const normalizeOptionalInteger = value => {
|
const normalizeOptionalPositiveInteger = value => {
|
||||||
if (value === undefined || value === null || value === '' || Number(value) < 0) return null;
|
if (value === undefined || value === null || value === '') return null;
|
||||||
const number = Number(value);
|
const number = Number(value);
|
||||||
return Number.isFinite(number) ? Math.trunc(number) : null;
|
return Number.isInteger(number) && number > 0 ? number : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -116,9 +122,10 @@ export default {
|
|||||||
mounted() { this.load(); },
|
mounted() { this.load(); },
|
||||||
watch: { settlementConfigTab(tab, oldTab) { if (tab === oldTab) return; if (oldTab === 'pre') this.preSettlementConfig = { ...this.settlementRule }; else this.formalSettlementConfig = { ...this.settlementRule }; this.settlementRule = { ...(tab === 'pre' ? this.preSettlementConfig : this.formalSettlementConfig) }; } },
|
watch: { settlementConfigTab(tab, oldTab) { if (tab === oldTab) return; if (oldTab === 'pre') this.preSettlementConfig = { ...this.settlementRule }; else this.formalSettlementConfig = { ...this.settlementRule }; this.settlementRule = { ...(tab === 'pre' ? this.preSettlementConfig : this.formalSettlementConfig) }; } },
|
||||||
methods: {
|
methods: {
|
||||||
async load() { const id = this.$route.query.id; if (!id) return; const res = await api.getDetail(id); const data = res.data?.data || res.data || {}; this.form = { ...data, copyCount: normalizeOptionalInteger(data.copyCount), paymentDays: normalizeOptionalInteger(data.paymentDays), changeType: '合同信息变更' }; this.period = data.startDate && data.endDate ? [data.startDate, data.endDate] : []; this.plans = this.parse(data.billingPlanJson); this.attachments = this.parse(data.attachmentsJson); this.contractFileRows = this.parse(data.contractFileJson); const rules = this.parseObject(data.settlementRuleJson); const pre = this.parseObject(data.preSettlementConfigJson); const formal = this.parseObject(data.formalSettlementConfigJson); const legacy = Object.keys(rules).some(key => !['preSettlementConfig', 'formalSettlementConfig'].includes(key)) ? rules : {}; this.preSettlementConfig = rules.preSettlementConfig || (Object.keys(pre).length ? pre : legacy); this.formalSettlementConfig = rules.formalSettlementConfig || (Object.keys(formal).length ? formal : legacy); this.settlementRule = { ...this.preSettlementConfig }; this.feeGenerationMode = data.feeGenerationMode || (Number(data.billingEnabled) === 0 ? 'manual' : 'system'); this.paymentRatioRows = this.parse(data.paymentRatioJson); },
|
async load() { const id = this.$route.query.id; if (!id) return; const res = await api.getDetail(id); const data = res.data?.data || res.data || {}; this.form = { ...data, copyCount: normalizeOptionalPositiveInteger(data.copyCount), paymentDays: normalizeOptionalPositiveInteger(data.paymentDays), changeType: '合同信息变更' }; this.period = data.startDate && data.endDate ? [data.startDate, data.endDate] : []; this.plans = this.parse(data.billingPlanJson); this.attachments = this.parse(data.attachmentsJson); this.contractFileRows = this.parse(data.contractFileJson); const rules = this.parseObject(data.settlementRuleJson); const pre = this.parseObject(data.preSettlementConfigJson); const formal = this.parseObject(data.formalSettlementConfigJson); const legacy = Object.keys(rules).some(key => !['preSettlementConfig', 'formalSettlementConfig'].includes(key)) ? rules : {}; this.preSettlementConfig = rules.preSettlementConfig || (Object.keys(pre).length ? pre : legacy); this.formalSettlementConfig = rules.formalSettlementConfig || (Object.keys(formal).length ? formal : legacy); this.settlementRule = { ...this.preSettlementConfig }; this.feeGenerationMode = data.feeGenerationMode || (Number(data.billingEnabled) === 0 ? 'manual' : 'system'); this.paymentRatioRows = this.parse(data.paymentRatioJson); },
|
||||||
parse(value) { try { const result = JSON.parse(value || '[]'); return Array.isArray(result) ? result : []; } catch { return []; } },
|
parse(value) { try { const result = JSON.parse(value || '[]'); return Array.isArray(result) ? result : []; } catch { return []; } },
|
||||||
parseObject(value) { try { return { autoGenerate: 1, settlementType: '月结', billCycleType: '固定截单日', billCutoffDay: 25, cycleDays: 15, ...(JSON.parse(value || '{}') || {}) }; } catch { return { autoGenerate: 1, settlementType: '月结', billCycleType: '固定截单日', billCutoffDay: 25, cycleDays: 15 }; } },
|
parseObject(value) { try { return { autoGenerate: 1, settlementType: '月结', billCycleType: '固定截单日', billCutoffDay: 25, cycleDays: 15, ...(JSON.parse(value || '{}') || {}) }; } catch { return { autoGenerate: 1, settlementType: '月结', billCycleType: '固定截单日', billCutoffDay: 25, cycleDays: 15 }; } },
|
||||||
|
positiveIntegerInput(prop, value) { this.form[prop] = String(value ?? '').replace(/\D/g, '').replace(/^0+/, ''); },
|
||||||
addPlan() { this.planEditorIndex = -1; this.planEditor = { planName: `计费方案${this.plans.length + 1}`, defaultPlan: !this.plans.length, remark: '', rules: [{}] }; this.planDialogVisible = true; },
|
addPlan() { this.planEditorIndex = -1; this.planEditor = { planName: `计费方案${this.plans.length + 1}`, defaultPlan: !this.plans.length, remark: '', rules: [{}] }; this.planDialogVisible = true; },
|
||||||
editPlan(row, index) { this.planEditorIndex = index; this.planEditor = JSON.parse(JSON.stringify(row)); this.planDialogVisible = true; },
|
editPlan(row, index) { this.planEditorIndex = index; this.planEditor = JSON.parse(JSON.stringify(row)); this.planDialogVisible = true; },
|
||||||
toggleDefaultPlan(value) { if (value) this.plans.forEach(item => { item.defaultPlan = false; }); },
|
toggleDefaultPlan(value) { if (value) this.plans.forEach(item => { item.defaultPlan = false; }); },
|
||||||
@@ -139,21 +146,36 @@ export default {
|
|||||||
formatFileSize(value) { const size = Number(value || 0); return size > 1024 * 1024 ? `${(size / 1024 / 1024).toFixed(2)}MB` : `${Math.max(1, Math.ceil(size / 1024))}KB`; },
|
formatFileSize(value) { const size = Number(value || 0); return size > 1024 * 1024 ? `${(size / 1024 / 1024).toFixed(2)}MB` : `${Math.max(1, Math.ceil(size / 1024))}KB`; },
|
||||||
handleChangeMaterial(event) { if (event.raw) this.changeMaterials.push(event.raw); },
|
handleChangeMaterial(event) { if (event.raw) this.changeMaterials.push(event.raw); },
|
||||||
addPaymentRatioRow() { this.paymentRatioRows.push({ paymentTerm: `第${this.paymentRatioRows.length + 1}笔`, ratioLimit: '', remark: '' }); },
|
addPaymentRatioRow() { this.paymentRatioRows.push({ paymentTerm: `第${this.paymentRatioRows.length + 1}笔`, ratioLimit: '', remark: '' }); },
|
||||||
async submit() { await this.$refs.formRef.validate(); const total = this.paymentRatioRows.reduce((sum, row) => sum + Number(row.ratioLimit || 0), 0); if (this.paymentRatioRows.length && Math.abs(total - 100) > 0.0001) { this.$message.warning('付款比例上限合计必须等于100%'); return; } const settlementRule = { preSettlementConfig: this.preSettlementConfig, formalSettlementConfig: this.formalSettlementConfig }; await api.submitChange({ ...this.form, copyCount: normalizeOptionalInteger(this.form.copyCount), paymentDays: normalizeOptionalInteger(this.form.paymentDays), startDate: this.period[0], endDate: this.period[1], feeGenerationMode: this.feeGenerationMode, billingEnabled: this.feeGenerationMode === 'system' ? 1 : 0, billingPlanJson: JSON.stringify(this.plans), settlementRuleJson: JSON.stringify(settlementRule), preSettlementConfigJson: JSON.stringify(this.preSettlementConfig), formalSettlementConfigJson: JSON.stringify(this.formalSettlementConfig), paymentRatioJson: JSON.stringify(this.paymentRatioRows), contractFileJson: JSON.stringify(this.contractFileRows), attachmentsJson: JSON.stringify(this.attachments), changeContent: this.form.changeReason, changeReason: this.form.changeReason }); this.$message.success('变更已提交'); this.$router.back(); },
|
async submit() { await this.$refs.formRef.validate(); const total = this.paymentRatioRows.reduce((sum, row) => sum + Number(row.ratioLimit || 0), 0); if (this.paymentRatioRows.length && Math.abs(total - 100) > 0.0001) { this.$message.warning('付款比例上限合计必须等于100%'); return; } const settlementRule = { preSettlementConfig: this.preSettlementConfig, formalSettlementConfig: this.formalSettlementConfig }; await api.submitChange({ ...this.form, copyCount: normalizeOptionalPositiveInteger(this.form.copyCount), paymentDays: normalizeOptionalPositiveInteger(this.form.paymentDays), startDate: this.period[0], endDate: this.period[1], feeGenerationMode: this.feeGenerationMode, billingEnabled: this.feeGenerationMode === 'system' ? 1 : 0, billingPlanJson: JSON.stringify(this.plans), settlementRuleJson: JSON.stringify(settlementRule), preSettlementConfigJson: JSON.stringify(this.preSettlementConfig), formalSettlementConfigJson: JSON.stringify(this.formalSettlementConfig), paymentRatioJson: JSON.stringify(this.paymentRatioRows), contractFileJson: JSON.stringify(this.contractFileRows), attachmentsJson: JSON.stringify(this.attachments), changeContent: this.form.changeReason, changeReason: this.form.changeReason }); this.$message.success('变更已提交'); this.$router.back(); },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.contract-change-page { min-height: 100%; background: #fff; }
|
.contract-change-page { min-height: 100%; background: #f5f6fa; }
|
||||||
.change-section { padding: 20px 24px; border-bottom: 1px solid #eff1f7; }
|
.contract-change-page :deep(.basic-container__card) { border: 0; background: transparent; box-shadow: none; }
|
||||||
|
.contract-change-form { background: #f5f6fa; }
|
||||||
|
.change-section { padding: 20px 24px; background: #fff; border-bottom: 1px solid #eff1f7; }
|
||||||
|
.contract-basic-section { margin-bottom: 12px; padding: 14px 16px 16px; overflow: hidden; background: #fff; border-bottom: 0; border-radius: 6px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); }
|
||||||
|
.contract-basic-section > .dialog-section-title { margin-bottom: 20px; color: #303133; }
|
||||||
|
.contract-basic-section__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 48px; }
|
||||||
|
.contract-basic-section__change-type { grid-column: 1 / -1; }
|
||||||
|
.contract-basic-section__remark { width: 100%; margin-bottom: 0 !important; }
|
||||||
|
.contract-basic-section__date-range { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 8px; width: 360px; max-width: 100%; }
|
||||||
|
.contract-basic-section__date-range span { color: #606266; }
|
||||||
|
.contract-basic-section__date-range :deep(.el-date-editor) { width: auto; min-width: 0; }
|
||||||
|
.contract-basic-section :deep(.el-form-item) { align-items: center; margin-bottom: 16px; }
|
||||||
|
.contract-basic-section :deep(.el-form-item__label) { flex: 0 0 96px !important; width: 96px !important; height: auto; padding-right: 12px; white-space: normal; word-break: break-all; line-height: 18px; }
|
||||||
|
.contract-basic-section :deep(.el-form-item__content) { min-width: 0; }
|
||||||
|
.contract-basic-section :deep(.el-input),
|
||||||
|
.contract-basic-section :deep(.el-select),
|
||||||
|
.contract-basic-section :deep(.el-date-editor) { width: 360px; max-width: 100%; }
|
||||||
.dialog-section-title { margin-bottom: 18px; font-size: 16px; font-weight: 600; }
|
.dialog-section-title { margin-bottom: 18px; font-size: 16px; font-weight: 600; }
|
||||||
.dialog-section-title::before { display: inline-block; width: 4px; height: 16px; margin-right: 8px; vertical-align: -2px; background: #409eff; content: ''; }
|
.dialog-section-title::before { display: inline-block; width: 4px; height: 16px; margin-right: 8px; vertical-align: -2px; background: #409eff; content: ''; }
|
||||||
.section-head { display: flex; align-items: center; justify-content: space-between; }
|
.section-head { display: flex; align-items: center; justify-content: space-between; }
|
||||||
.change-table { margin: 16px 0; }
|
.change-table { margin: 16px 0; }
|
||||||
.ratio-tip { margin-bottom: 8px; color: #f56c6c; }
|
.ratio-tip { margin-bottom: 8px; color: #f56c6c; }
|
||||||
.unit { margin-left: 8px; }
|
.unit { margin-left: 8px; }
|
||||||
.inline-field { display: flex; align-items: center; gap: 8px; }
|
|
||||||
.attachment-head { display: flex; align-items: center; justify-content: flex-end; margin-bottom: 12px; }
|
.attachment-head { display: flex; align-items: center; justify-content: flex-end; margin-bottom: 12px; }
|
||||||
.attachment-upload { display: flex; justify-content: flex-start; margin-top: 12px; }
|
.attachment-upload { display: flex; justify-content: flex-start; margin-top: 12px; }
|
||||||
.attachment-upload .vehicle-attachment-upload { width: auto; }
|
.attachment-upload .vehicle-attachment-upload { width: auto; }
|
||||||
@@ -162,4 +184,6 @@ export default {
|
|||||||
.settlement-form { display: grid; grid-template-columns: repeat(3, minmax(240px, 1fr)); gap: 8px 28px; }
|
.settlement-form { display: grid; grid-template-columns: repeat(3, minmax(240px, 1fr)); gap: 8px 28px; }
|
||||||
.change-reason-section { border: 1px dashed #ff8f9a; margin: 20px 16px; }
|
.change-reason-section { border: 1px dashed #ff8f9a; margin: 20px 16px; }
|
||||||
.page-footer { display: flex; gap: 16px; padding: 20px 40px; border-top: 1px solid #eff1f7; }
|
.page-footer { display: flex; gap: 16px; padding: 20px 40px; border-top: 1px solid #eff1f7; }
|
||||||
|
@media (max-width: 1200px) { .contract-basic-section__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px; } }
|
||||||
|
@media (max-width: 768px) { .contract-basic-section__grid { grid-template-columns: 1fr; } }
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -225,14 +225,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="所属组织" prop="organizationName">
|
<el-form-item label="所属组织" prop="organizationName">
|
||||||
<el-cascader
|
<el-tree-select
|
||||||
v-model="selectedOrganizationId"
|
v-model="selectedOrganizationId"
|
||||||
:options="organizationOptions"
|
:data="organizationOptions"
|
||||||
:props="organizationCascaderProps"
|
:props="organizationTreeSelectProps"
|
||||||
|
node-key="id"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
|
check-strictly
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
:show-all-levels="false"
|
:render-after-expand="false"
|
||||||
@visible-change="visible => visible && loadOrganizationOptions()"
|
@visible-change="visible => visible && loadOrganizationOptions()"
|
||||||
@change="handleOrganizationChange"
|
@change="handleOrganizationChange"
|
||||||
/>
|
/>
|
||||||
@@ -541,8 +543,17 @@
|
|||||||
width="90%"
|
width="90%"
|
||||||
top="4vh"
|
top="4vh"
|
||||||
>
|
>
|
||||||
|
<pdf-preview
|
||||||
|
v-if="
|
||||||
|
attachmentDocumentPreviewVisible &&
|
||||||
|
attachmentPreviewFile.url &&
|
||||||
|
attachmentPreviewFile.isPdf
|
||||||
|
"
|
||||||
|
:source="attachmentPreviewFile.url"
|
||||||
|
@error="handleAttachmentPreviewError"
|
||||||
|
/>
|
||||||
<open-file-viewer
|
<open-file-viewer
|
||||||
v-if="attachmentDocumentPreviewVisible && attachmentPreviewFile.url"
|
v-else-if="attachmentDocumentPreviewVisible && attachmentPreviewFile.url"
|
||||||
:file="attachmentPreviewFile.url"
|
:file="attachmentPreviewFile.url"
|
||||||
:file-name="attachmentPreviewFile.name"
|
:file-name="attachmentPreviewFile.name"
|
||||||
:mime-type="attachmentPreviewFile.mimeType"
|
:mime-type="attachmentPreviewFile.mimeType"
|
||||||
@@ -577,7 +588,7 @@
|
|||||||
<div v-loading="detailLoading" class="contract-manage-form contract-manage-detail">
|
<div v-loading="detailLoading" class="contract-manage-form contract-manage-detail">
|
||||||
<section class="contract-manage-form__section contract-manage-form__section--panel">
|
<section class="contract-manage-form__section contract-manage-form__section--panel">
|
||||||
<div class="dialog-section-title">基本信息</div>
|
<div class="dialog-section-title">基本信息</div>
|
||||||
<el-descriptions :column="4" class="contract-manage-detail__descriptions">
|
<el-descriptions :column="3" class="contract-manage-detail__descriptions">
|
||||||
<el-descriptions-item label="签约类型">{{
|
<el-descriptions-item label="签约类型">{{
|
||||||
detailValue('signType')
|
detailValue('signType')
|
||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
@@ -620,7 +631,7 @@
|
|||||||
<el-descriptions-item label="回款账期">{{
|
<el-descriptions-item label="回款账期">{{
|
||||||
detailUnitValue('paymentDays', '天')
|
detailUnitValue('paymentDays', '天')
|
||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="备注" :span="4">{{
|
<el-descriptions-item label="备注" :span="3">{{
|
||||||
detailValue('remark')
|
detailValue('remark')
|
||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
@@ -635,7 +646,7 @@
|
|||||||
|
|
||||||
<section class="contract-manage-form__section contract-manage-form__section--panel">
|
<section class="contract-manage-form__section contract-manage-form__section--panel">
|
||||||
<div class="dialog-section-title">计费信息</div>
|
<div class="dialog-section-title">计费信息</div>
|
||||||
<el-descriptions :column="4" class="contract-manage-detail__descriptions">
|
<el-descriptions :column="3" class="contract-manage-detail__descriptions">
|
||||||
<el-descriptions-item label="费用生成模式">{{
|
<el-descriptions-item label="费用生成模式">{{
|
||||||
detailFeeGenerationMode
|
detailFeeGenerationMode
|
||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
@@ -664,7 +675,7 @@
|
|||||||
<el-tab-pane label="预结算配置" name="pre" />
|
<el-tab-pane label="预结算配置" name="pre" />
|
||||||
<el-tab-pane label="正式结算配置" name="formal" />
|
<el-tab-pane label="正式结算配置" name="formal" />
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
<el-descriptions :column="4" class="contract-manage-detail__descriptions">
|
<el-descriptions :column="3" class="contract-manage-detail__descriptions">
|
||||||
<el-descriptions-item label="自动生成结算单">{{
|
<el-descriptions-item label="自动生成结算单">{{
|
||||||
Number(detailSettlementRule.autoGenerate) === 1 ? '开启' : '关闭'
|
Number(detailSettlementRule.autoGenerate) === 1 ? '开启' : '关闭'
|
||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
@@ -791,15 +802,10 @@ import { config, option } from '@/option/business/contract-manage';
|
|||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { downloadFileByUrl, downloadXls } from '@/utils/util';
|
import { downloadFileByUrl, downloadXls } from '@/utils/util';
|
||||||
import BillingPlanEditor from './components/billing-plan-editor.vue';
|
import BillingPlanEditor from './components/billing-plan-editor.vue';
|
||||||
|
import PdfPreview from '@/components/pdf-preview/main.vue';
|
||||||
import { ElImageViewer } from 'element-plus';
|
import { ElImageViewer } from 'element-plus';
|
||||||
import { OpenFileViewer } from '@open-file-viewer/vue';
|
import { OpenFileViewer } from '@open-file-viewer/vue';
|
||||||
import {
|
import { fallbackPlugin, imagePlugin, officePlugin, textPlugin } from '@open-file-viewer/core';
|
||||||
fallbackPlugin,
|
|
||||||
imagePlugin,
|
|
||||||
officePlugin,
|
|
||||||
pdfPlugin,
|
|
||||||
textPlugin,
|
|
||||||
} from '@open-file-viewer/core';
|
|
||||||
import '@open-file-viewer/core/style.css';
|
import '@open-file-viewer/core/style.css';
|
||||||
import pdfWorkerSrc from 'pdfjs-dist/build/pdf.worker.mjs?url';
|
import pdfWorkerSrc from 'pdfjs-dist/build/pdf.worker.mjs?url';
|
||||||
|
|
||||||
@@ -879,6 +885,10 @@ const attachmentExtension = row => {
|
|||||||
};
|
};
|
||||||
const isAttachmentImage = row =>
|
const isAttachmentImage = row =>
|
||||||
['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(attachmentExtension(row));
|
['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(attachmentExtension(row));
|
||||||
|
const isAttachmentPdf = row => {
|
||||||
|
const mimeType = String(row.mimeType || row.contentType || '').toLowerCase();
|
||||||
|
return mimeType.includes('application/pdf') || attachmentExtension(row) === 'pdf';
|
||||||
|
};
|
||||||
const attachmentFileTypes = [
|
const attachmentFileTypes = [
|
||||||
'pdf',
|
'pdf',
|
||||||
'bmp',
|
'bmp',
|
||||||
@@ -897,7 +907,6 @@ const attachmentFileTypes = [
|
|||||||
];
|
];
|
||||||
const attachmentViewerPlugins = [
|
const attachmentViewerPlugins = [
|
||||||
imagePlugin(),
|
imagePlugin(),
|
||||||
pdfPlugin({ workerSrc: pdfWorkerSrc, useFetchData: true }),
|
|
||||||
officePlugin({ pdf: { workerSrc: pdfWorkerSrc, useFetchData: true } }),
|
officePlugin({ pdf: { workerSrc: pdfWorkerSrc, useFetchData: true } }),
|
||||||
textPlugin(),
|
textPlugin(),
|
||||||
fallbackPlugin(),
|
fallbackPlugin(),
|
||||||
@@ -1090,7 +1099,7 @@ const AttachmentSection = defineComponent({
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ContractManage',
|
name: 'ContractManage',
|
||||||
components: { AttachmentSection, BillingPlanEditor, ElImageViewer, OpenFileViewer },
|
components: { AttachmentSection, BillingPlanEditor, ElImageViewer, OpenFileViewer, PdfPreview },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
api,
|
api,
|
||||||
@@ -1227,13 +1236,11 @@ export default {
|
|||||||
contractFormatOptions() {
|
contractFormatOptions() {
|
||||||
return this.columnOptions('contractFormat');
|
return this.columnOptions('contractFormat');
|
||||||
},
|
},
|
||||||
organizationCascaderProps() {
|
organizationTreeSelectProps() {
|
||||||
return {
|
return {
|
||||||
label: 'label',
|
label: 'label',
|
||||||
value: 'id',
|
value: 'id',
|
||||||
children: 'children',
|
children: 'children',
|
||||||
checkStrictly: true,
|
|
||||||
emitPath: false,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
settlementRuleEnabled() {
|
settlementRuleEnabled() {
|
||||||
@@ -1681,7 +1688,8 @@ export default {
|
|||||||
this.organizationLoading = true;
|
this.organizationLoading = true;
|
||||||
getDeptTree(this.userInfo?.tenantId)
|
getDeptTree(this.userInfo?.tenantId)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
this.organizationOptions = this.normalizeOrganizationTree(res.data?.data || []);
|
const organizationTree = this.excludeExternalOrganization(res.data?.data || []);
|
||||||
|
this.organizationOptions = this.normalizeOrganizationTree(organizationTree);
|
||||||
this.organizationFlatOptions = this.flattenOrganizationTree(this.organizationOptions);
|
this.organizationFlatOptions = this.flattenOrganizationTree(this.organizationOptions);
|
||||||
const column = this.findColumn(this.tableOption.column, 'organizationName');
|
const column = this.findColumn(this.tableOption.column, 'organizationName');
|
||||||
if (column) column.dicData = this.organizationOptions;
|
if (column) column.dicData = this.organizationOptions;
|
||||||
@@ -1691,6 +1699,17 @@ export default {
|
|||||||
this.organizationLoading = false;
|
this.organizationLoading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
excludeExternalOrganization(tree = []) {
|
||||||
|
return tree.reduce((result, item) => {
|
||||||
|
const organizationName = item.title || item.deptName || item.name || item.label || '';
|
||||||
|
if (String(organizationName).trim() === '外部组织') return result;
|
||||||
|
result.push({
|
||||||
|
...item,
|
||||||
|
children: this.excludeExternalOrganization(item.children || []),
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}, []);
|
||||||
|
},
|
||||||
normalizeOrganizationTree(tree) {
|
normalizeOrganizationTree(tree) {
|
||||||
return (tree || []).map(item => {
|
return (tree || []).map(item => {
|
||||||
const label = item.title || item.deptName || item.name || item.label || '';
|
const label = item.title || item.deptName || item.name || item.label || '';
|
||||||
@@ -1757,10 +1776,12 @@ export default {
|
|||||||
this.attachmentImagePreviewVisible = true;
|
this.attachmentImagePreviewVisible = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const isPdf = isAttachmentPdf(row);
|
||||||
this.attachmentPreviewFile = {
|
this.attachmentPreviewFile = {
|
||||||
name: attachmentName(row),
|
name: attachmentName(row),
|
||||||
url,
|
url,
|
||||||
mimeType: row.mimeType || row.contentType || '',
|
mimeType: isPdf ? 'application/pdf' : row.mimeType || row.contentType || '',
|
||||||
|
isPdf,
|
||||||
};
|
};
|
||||||
this.attachmentDocumentPreviewVisible = true;
|
this.attachmentDocumentPreviewVisible = true;
|
||||||
},
|
},
|
||||||
@@ -2182,9 +2203,8 @@ export default {
|
|||||||
|
|
||||||
&__grid {
|
&__grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
column-gap: 24px;
|
column-gap: 48px;
|
||||||
row-gap: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__remark {
|
&__remark {
|
||||||
@@ -2197,8 +2217,8 @@ export default {
|
|||||||
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
|
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
width: 100%;
|
width: 360px;
|
||||||
max-width: 360px;
|
max-width: 100%;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
color: #606266;
|
color: #606266;
|
||||||
@@ -2271,6 +2291,7 @@ export default {
|
|||||||
:deep(.el-input),
|
:deep(.el-input),
|
||||||
:deep(.el-select),
|
:deep(.el-select),
|
||||||
:deep(.el-cascader),
|
:deep(.el-cascader),
|
||||||
|
:deep(.el-tree-select),
|
||||||
:deep(.el-input-number),
|
:deep(.el-input-number),
|
||||||
:deep(.el-date-editor) {
|
:deep(.el-date-editor) {
|
||||||
width: 360px;
|
width: 360px;
|
||||||
@@ -2344,11 +2365,16 @@ export default {
|
|||||||
&__descriptions {
|
&__descriptions {
|
||||||
:deep(.el-descriptions__label) {
|
:deep(.el-descriptions__label) {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
width: 96px;
|
||||||
min-width: 96px;
|
min-width: 96px;
|
||||||
max-width: 96px;
|
max-width: 96px;
|
||||||
|
box-sizing: border-box;
|
||||||
padding-right: 12px;
|
padding-right: 12px;
|
||||||
color: #606266;
|
color: #606266;
|
||||||
|
line-height: 18px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
white-space: normal;
|
||||||
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-descriptions__content) {
|
:deep(.el-descriptions__content) {
|
||||||
|
|||||||
@@ -2331,6 +2331,9 @@ export default {
|
|||||||
if (driver && !this.dialogForm.driverPhone) {
|
if (driver && !this.dialogForm.driverPhone) {
|
||||||
this.dialogForm.driverPhone = driver.mobile || driver.driverPhone || driver.phone || '';
|
this.dialogForm.driverPhone = driver.mobile || driver.driverPhone || driver.phone || '';
|
||||||
}
|
}
|
||||||
|
if (String(driver?.drivingVehicle || '').trim()) {
|
||||||
|
this.dialogForm.vehicleNo = String(driver.drivingVehicle).trim();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
fetchDriverSuggestions(queryString, callback) {
|
fetchDriverSuggestions(queryString, callback) {
|
||||||
this.loadDriverOptions(String(queryString || '').trim())
|
this.loadDriverOptions(String(queryString || '').trim())
|
||||||
@@ -2350,6 +2353,8 @@ export default {
|
|||||||
this.dialogForm.driverName = value;
|
this.dialogForm.driverName = value;
|
||||||
const phone = item.mobile || item.driverPhone || item.phone || '';
|
const phone = item.mobile || item.driverPhone || item.phone || '';
|
||||||
if (phone) this.dialogForm.driverPhone = phone;
|
if (phone) this.dialogForm.driverPhone = phone;
|
||||||
|
const drivingVehicle = String(item.drivingVehicle || '').trim();
|
||||||
|
if (drivingVehicle) this.dialogForm.vehicleNo = drivingVehicle;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleMileageInput(value) {
|
handleMileageInput(value) {
|
||||||
|
|||||||
@@ -851,9 +851,14 @@ export default {
|
|||||||
submitRow[key] = submitRow[key].trim();
|
submitRow[key] = submitRow[key].trim();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
submitRow.defaultFinishDays = submitRow.defaultFinishDays
|
const defaultFinishDays = submitRow.defaultFinishDays;
|
||||||
? Number(submitRow.defaultFinishDays)
|
submitRow.defaultFinishDays =
|
||||||
: undefined;
|
defaultFinishDays === undefined ||
|
||||||
|
defaultFinishDays === null ||
|
||||||
|
defaultFinishDays === '' ||
|
||||||
|
Number(defaultFinishDays) === -1
|
||||||
|
? ''
|
||||||
|
: Number(defaultFinishDays);
|
||||||
return submitRow;
|
return submitRow;
|
||||||
},
|
},
|
||||||
validateRow(row) {
|
validateRow(row) {
|
||||||
@@ -946,7 +951,12 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
api.getDetail(row.id).then(res => {
|
api.getDetail(row.id).then(res => {
|
||||||
this.form = res.data.data || {};
|
const detail = res.data.data || {};
|
||||||
|
this.form = {
|
||||||
|
...detail,
|
||||||
|
defaultFinishDays:
|
||||||
|
Number(detail.defaultFinishDays) === -1 ? '' : detail.defaultFinishDays ?? '',
|
||||||
|
};
|
||||||
this.selectedProjectId = this.form.projectIds ? String(this.form.projectIds) : '';
|
this.selectedProjectId = this.form.projectIds ? String(this.form.projectIds) : '';
|
||||||
this.ensureSelectedProjectOption();
|
this.ensureSelectedProjectOption();
|
||||||
this.parseNodeConfig(this.form);
|
this.parseNodeConfig(this.form);
|
||||||
|
|||||||
@@ -160,26 +160,28 @@
|
|||||||
<el-tree-select
|
<el-tree-select
|
||||||
v-model="form.businessDeptId"
|
v-model="form.businessDeptId"
|
||||||
:data="businessDeptTreeOptions"
|
:data="businessDeptTreeOptions"
|
||||||
:props="{ label: 'label', value: 'value', children: 'children' }"
|
:props="deptTreeSelectProps"
|
||||||
node-key="value"
|
node-key="value"
|
||||||
|
placeholder="请选择业务部门"
|
||||||
check-strictly
|
check-strictly
|
||||||
filterable
|
filterable
|
||||||
clearable
|
clearable
|
||||||
:render-after-expand="false"
|
:render-after-expand="false"
|
||||||
style="width: 100%"
|
|
||||||
:disabled="isBasicInfoReadonly"
|
:disabled="isBasicInfoReadonly"
|
||||||
@change="handleBusinessDeptChange"
|
@change="handleBusinessDeptChange"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="承办部门" prop="undertakeDeptId">
|
<el-form-item label="承办部门" prop="undertakeDeptId">
|
||||||
<el-cascader
|
<el-tree-select
|
||||||
v-model="form.undertakeDeptId"
|
v-model="form.undertakeDeptId"
|
||||||
style="width: 100%"
|
:data="deptTreeOptions"
|
||||||
|
:props="deptTreeSelectProps"
|
||||||
|
node-key="value"
|
||||||
placeholder="请选择承办部门"
|
placeholder="请选择承办部门"
|
||||||
|
check-strictly
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
:options="deptTreeOptions"
|
:render-after-expand="false"
|
||||||
:props="deptCascaderProps"
|
|
||||||
:disabled="isBasicInfoReadonly"
|
:disabled="isBasicInfoReadonly"
|
||||||
@change="handleUndertakeDeptChange"
|
@change="handleUndertakeDeptChange"
|
||||||
/>
|
/>
|
||||||
@@ -659,8 +661,17 @@
|
|||||||
top="4vh"
|
top="4vh"
|
||||||
class="project-apply-form__attachment-viewer-dialog"
|
class="project-apply-form__attachment-viewer-dialog"
|
||||||
>
|
>
|
||||||
|
<pdf-preview
|
||||||
|
v-if="
|
||||||
|
attachmentDocumentPreviewVisible &&
|
||||||
|
attachmentPreviewFile.url &&
|
||||||
|
attachmentPreviewFile.isPdf
|
||||||
|
"
|
||||||
|
:source="attachmentPreviewFile.url"
|
||||||
|
@error="handleAttachmentPreviewError"
|
||||||
|
/>
|
||||||
<open-file-viewer
|
<open-file-viewer
|
||||||
v-if="attachmentDocumentPreviewVisible && attachmentPreviewFile.url"
|
v-else-if="attachmentDocumentPreviewVisible && attachmentPreviewFile.url"
|
||||||
:file="attachmentPreviewFile.url"
|
:file="attachmentPreviewFile.url"
|
||||||
:file-name="attachmentPreviewFile.name"
|
:file-name="attachmentPreviewFile.name"
|
||||||
:mime-type="attachmentPreviewFile.mimeType"
|
:mime-type="attachmentPreviewFile.mimeType"
|
||||||
@@ -747,11 +758,11 @@ import { getToken } from '@/utils/auth';
|
|||||||
import { downloadFileByUrl, downloadXls } from '@/utils/util';
|
import { downloadFileByUrl, downloadXls } from '@/utils/util';
|
||||||
import { ElImageViewer } from 'element-plus';
|
import { ElImageViewer } from 'element-plus';
|
||||||
import { OpenFileViewer } from '@open-file-viewer/vue';
|
import { OpenFileViewer } from '@open-file-viewer/vue';
|
||||||
|
import PdfPreview from '@/components/pdf-preview/main.vue';
|
||||||
import {
|
import {
|
||||||
fallbackPlugin,
|
fallbackPlugin,
|
||||||
imagePlugin,
|
imagePlugin,
|
||||||
officePlugin,
|
officePlugin,
|
||||||
pdfPlugin,
|
|
||||||
textPlugin,
|
textPlugin,
|
||||||
} from '@open-file-viewer/core';
|
} from '@open-file-viewer/core';
|
||||||
import '@open-file-viewer/core/style.css';
|
import '@open-file-viewer/core/style.css';
|
||||||
@@ -813,6 +824,15 @@ const emptyForm = () => ({
|
|||||||
changeReason: '',
|
changeReason: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const optionalSentinelFields = [
|
||||||
|
'projectScale',
|
||||||
|
'estimatedProfit',
|
||||||
|
'fundDemand',
|
||||||
|
'receivableDays',
|
||||||
|
'paymentDays',
|
||||||
|
'cargoQuantity',
|
||||||
|
];
|
||||||
|
|
||||||
const changeTypeOptions = [
|
const changeTypeOptions = [
|
||||||
{ label: '项目变更', value: '项目变更' },
|
{ label: '项目变更', value: '项目变更' },
|
||||||
{ label: '项目备案调整', value: '项目备案调整' },
|
{ label: '项目备案调整', value: '项目备案调整' },
|
||||||
@@ -820,7 +840,6 @@ const changeTypeOptions = [
|
|||||||
|
|
||||||
const attachmentViewerPlugins = [
|
const attachmentViewerPlugins = [
|
||||||
imagePlugin(),
|
imagePlugin(),
|
||||||
pdfPlugin({ workerSrc: pdfWorkerSrc, useFetchData: true }),
|
|
||||||
officePlugin({ pdf: { workerSrc: pdfWorkerSrc, useFetchData: true } }),
|
officePlugin({ pdf: { workerSrc: pdfWorkerSrc, useFetchData: true } }),
|
||||||
textPlugin(),
|
textPlugin(),
|
||||||
fallbackPlugin(),
|
fallbackPlugin(),
|
||||||
@@ -853,6 +872,7 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
ElImageViewer,
|
ElImageViewer,
|
||||||
OpenFileViewer,
|
OpenFileViewer,
|
||||||
|
PdfPreview,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const validateAmount = (rule, value, callback) => {
|
const validateAmount = (rule, value, callback) => {
|
||||||
@@ -875,7 +895,7 @@ export default {
|
|||||||
};
|
};
|
||||||
const validateDays = (rule, value, callback) => {
|
const validateDays = (rule, value, callback) => {
|
||||||
if (value === '' || value === undefined || value === null) {
|
if (value === '' || value === undefined || value === null) {
|
||||||
callback(new Error(`请输入${rule.label}`));
|
callback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const number = Number(value);
|
const number = Number(value);
|
||||||
@@ -951,10 +971,10 @@ export default {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
receivableDays: [
|
receivableDays: [
|
||||||
{ required: true, label: '应收账款回款期限', validator: validateDays, trigger: 'blur' },
|
{ label: '应收账款回款期限', validator: validateDays, trigger: 'blur' },
|
||||||
],
|
],
|
||||||
paymentDays: [
|
paymentDays: [
|
||||||
{ required: true, label: '回款账期', validator: validateDays, trigger: 'blur' },
|
{ label: '回款账期', validator: validateDays, trigger: 'blur' },
|
||||||
],
|
],
|
||||||
projectScale: [{ label: '项目规模', validator: validateAmount, trigger: 'blur' }],
|
projectScale: [{ label: '项目规模', validator: validateAmount, trigger: 'blur' }],
|
||||||
estimatedProfit: [{ label: '预估利润', validator: validateAmount, trigger: 'blur' }],
|
estimatedProfit: [{ label: '预估利润', validator: validateAmount, trigger: 'blur' }],
|
||||||
@@ -987,14 +1007,12 @@ export default {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
deptOptions: [],
|
deptOptions: [],
|
||||||
deptTreeOptions: [],
|
|
||||||
businessDeptTreeOptions: [],
|
businessDeptTreeOptions: [],
|
||||||
deptCascaderProps: {
|
deptTreeOptions: [],
|
||||||
|
deptTreeSelectProps: {
|
||||||
label: 'label',
|
label: 'label',
|
||||||
value: 'value',
|
value: 'value',
|
||||||
children: 'children',
|
children: 'children',
|
||||||
emitPath: false,
|
|
||||||
checkStrictly: true,
|
|
||||||
},
|
},
|
||||||
cargoTypeOptions: [],
|
cargoTypeOptions: [],
|
||||||
selectedCustomerId: [],
|
selectedCustomerId: [],
|
||||||
@@ -1406,13 +1424,12 @@ export default {
|
|||||||
...row,
|
...row,
|
||||||
fundLimit: this.formatAmount(row.fundLimit),
|
fundLimit: this.formatAmount(row.fundLimit),
|
||||||
receivableLimit: this.formatAmount(row.receivableLimit),
|
receivableLimit: this.formatAmount(row.receivableLimit),
|
||||||
...(this.dialogReadonly
|
projectScale: this.normalizeOptionalSentinel(row.projectScale),
|
||||||
? {
|
estimatedProfit: this.normalizeOptionalSentinel(row.estimatedProfit),
|
||||||
projectScale: this.normalizeReadonlyAmount(row.projectScale),
|
fundDemand: this.normalizeOptionalSentinel(row.fundDemand),
|
||||||
estimatedProfit: this.normalizeReadonlyAmount(row.estimatedProfit),
|
receivableDays: this.normalizeOptionalSentinel(row.receivableDays),
|
||||||
fundDemand: this.normalizeReadonlyAmount(row.fundDemand),
|
paymentDays: this.normalizeOptionalSentinel(row.paymentDays),
|
||||||
}
|
cargoQuantity: this.normalizeOptionalSentinel(row.cargoQuantity),
|
||||||
: {}),
|
|
||||||
};
|
};
|
||||||
const form = {
|
const form = {
|
||||||
...emptyForm(),
|
...emptyForm(),
|
||||||
@@ -1580,6 +1597,9 @@ export default {
|
|||||||
...this.form,
|
...this.form,
|
||||||
fundLimit: this.formatAmount(this.form.fundLimit),
|
fundLimit: this.formatAmount(this.form.fundLimit),
|
||||||
receivableLimit: this.formatAmount(this.form.receivableLimit),
|
receivableLimit: this.formatAmount(this.form.receivableLimit),
|
||||||
|
...Object.fromEntries(
|
||||||
|
optionalSentinelFields.map(key => [key, this.normalizeOptionalSentinel(this.form[key], null)])
|
||||||
|
),
|
||||||
businessStartDate,
|
businessStartDate,
|
||||||
businessEndDate,
|
businessEndDate,
|
||||||
customerJson: JSON.stringify(this.customerRows),
|
customerJson: JSON.stringify(this.customerRows),
|
||||||
@@ -1723,8 +1743,11 @@ export default {
|
|||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
},
|
},
|
||||||
normalizeReadonlyAmount(value) {
|
normalizeReadonlyAmount(value) {
|
||||||
|
return this.normalizeOptionalSentinel(value);
|
||||||
|
},
|
||||||
|
normalizeOptionalSentinel(value, emptyValue = '') {
|
||||||
return value === null || value === undefined || value === '' || Number(value) === -1
|
return value === null || value === undefined || value === '' || Number(value) === -1
|
||||||
? ''
|
? emptyValue
|
||||||
: value;
|
: value;
|
||||||
},
|
},
|
||||||
mergeCustomerOptions(options = [], selectedOptions = []) {
|
mergeCustomerOptions(options = [], selectedOptions = []) {
|
||||||
@@ -1764,9 +1787,8 @@ export default {
|
|||||||
];
|
];
|
||||||
},
|
},
|
||||||
handleBusinessDeptChange(value) {
|
handleBusinessDeptChange(value) {
|
||||||
// el-tree-select 返回的是 node-key 值,从树中查找节点获取名称
|
const dept = this.deptOptions.find(item => item.value === value);
|
||||||
const label = this.findDeptLabel(this.businessDeptTreeOptions, value);
|
this.form.businessDeptName = dept ? dept.rawLabel : '';
|
||||||
this.form.businessDeptName = label;
|
|
||||||
this.$refs.projectForm?.validateField('businessDeptId');
|
this.$refs.projectForm?.validateField('businessDeptId');
|
||||||
},
|
},
|
||||||
handleUndertakeDeptChange(value) {
|
handleUndertakeDeptChange(value) {
|
||||||
@@ -1781,14 +1803,14 @@ export default {
|
|||||||
loadDeptOptions() {
|
loadDeptOptions() {
|
||||||
getDeptTree().then(res => {
|
getDeptTree().then(res => {
|
||||||
const deptTree = res.data.data || [];
|
const deptTree = res.data.data || [];
|
||||||
|
const businessDeptTree = ['add', 'edit'].includes(this.dialogType)
|
||||||
|
? this.excludeExternalOrganization(deptTree)
|
||||||
|
: deptTree;
|
||||||
const undertakeDeptTree =
|
const undertakeDeptTree =
|
||||||
this.dialogType === 'add' ? this.excludeExternalOrganization(deptTree) : deptTree;
|
this.dialogType === 'add' ? this.excludeExternalOrganization(deptTree) : deptTree;
|
||||||
this.deptOptions = this.flattenDept(deptTree);
|
this.deptOptions = this.flattenDept(businessDeptTree);
|
||||||
|
this.businessDeptTreeOptions = this.toDeptCascaderOptions(businessDeptTree);
|
||||||
this.deptTreeOptions = this.toDeptCascaderOptions(undertakeDeptTree);
|
this.deptTreeOptions = this.toDeptCascaderOptions(undertakeDeptTree);
|
||||||
// 业务部门用 el-tree-select,需要树形数据(label/value/children 格式)
|
|
||||||
this.businessDeptTreeOptions = this.toTreeSelectOptions(
|
|
||||||
this.dialogType === 'add' ? this.excludeExternalOrganization(deptTree) : deptTree
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
excludeExternalOrganization(list = []) {
|
excludeExternalOrganization(list = []) {
|
||||||
@@ -1825,25 +1847,6 @@ export default {
|
|||||||
return result;
|
return result;
|
||||||
}, []);
|
}, []);
|
||||||
},
|
},
|
||||||
// 将后端部门树转为 el-tree-select 需要的 {label, value, children} 格式
|
|
||||||
toTreeSelectOptions(list = []) {
|
|
||||||
return (list || []).map(item => ({
|
|
||||||
label: item.title || item.deptName || item.name,
|
|
||||||
value: item.id,
|
|
||||||
children: item.children?.length ? this.toTreeSelectOptions(item.children) : undefined,
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
// 从树形数据中根据 value 查找 label
|
|
||||||
findDeptLabel(tree, value) {
|
|
||||||
for (const node of tree) {
|
|
||||||
if (node.value === value) return node.label;
|
|
||||||
if (node.children?.length) {
|
|
||||||
const found = this.findDeptLabel(node.children, value);
|
|
||||||
if (found) return found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
},
|
|
||||||
loadCargoTypeOptions() {
|
loadCargoTypeOptions() {
|
||||||
getSystemDictionary({ code: 'type_of_goods' }).then(res => {
|
getSystemDictionary({ code: 'type_of_goods' }).then(res => {
|
||||||
this.cargoTypeOptions = (res.data.data || []).map(item => ({
|
this.cargoTypeOptions = (res.data.data || []).map(item => ({
|
||||||
@@ -1867,7 +1870,9 @@ export default {
|
|||||||
getCustomerArchiveList(1, 100, {
|
getCustomerArchiveList(1, 100, {
|
||||||
customerType: type,
|
customerType: type,
|
||||||
status: 1,
|
status: 1,
|
||||||
...(type === '客户' ? { approvalStatus: 'approved' } : {}),
|
...(this.dialogType !== 'add' && type === '客户'
|
||||||
|
? { approvalStatus: 'approved' }
|
||||||
|
: {}),
|
||||||
})
|
})
|
||||||
.then(res => {
|
.then(res => {
|
||||||
const records = (res.data.data && res.data.data.records) || [];
|
const records = (res.data.data && res.data.data.records) || [];
|
||||||
@@ -1949,6 +1954,10 @@ export default {
|
|||||||
return row;
|
return row;
|
||||||
},
|
},
|
||||||
handleNumberInput(prop, value) {
|
handleNumberInput(prop, value) {
|
||||||
|
if (optionalSentinelFields.includes(prop) && Number(value) === -1) {
|
||||||
|
this.form[prop] = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
const text = String(value || '').replace(/[^\d.]/g, '');
|
const text = String(value || '').replace(/[^\d.]/g, '');
|
||||||
const parts = text.split('.');
|
const parts = text.split('.');
|
||||||
this.form[prop] =
|
this.form[prop] =
|
||||||
@@ -1963,6 +1972,10 @@ export default {
|
|||||||
this.form[prop] = this.formatAmount(this.form[prop]);
|
this.form[prop] = this.formatAmount(this.form[prop]);
|
||||||
},
|
},
|
||||||
handleIntegerInput(prop, value) {
|
handleIntegerInput(prop, value) {
|
||||||
|
if (optionalSentinelFields.includes(prop) && Number(value) === -1) {
|
||||||
|
this.form[prop] = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.form[prop] = String(value || '').replace(/[^\d]/g, '');
|
this.form[prop] = String(value || '').replace(/[^\d]/g, '');
|
||||||
},
|
},
|
||||||
handleAttachmentChange(list) {
|
handleAttachmentChange(list) {
|
||||||
@@ -2006,6 +2019,10 @@ export default {
|
|||||||
this.attachmentExtension(row)
|
this.attachmentExtension(row)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
isAttachmentPdf(row) {
|
||||||
|
const mimeType = String(row.mimeType || row.contentType || '').toLowerCase();
|
||||||
|
return mimeType.includes('application/pdf') || this.attachmentExtension(row) === 'pdf';
|
||||||
|
},
|
||||||
previewAttachment(row) {
|
previewAttachment(row) {
|
||||||
const url = this.attachmentUrl(row);
|
const url = this.attachmentUrl(row);
|
||||||
if (!url) {
|
if (!url) {
|
||||||
@@ -2023,10 +2040,12 @@ export default {
|
|||||||
this.attachmentImagePreviewVisible = true;
|
this.attachmentImagePreviewVisible = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const isPdf = this.isAttachmentPdf(row);
|
||||||
this.attachmentPreviewFile = {
|
this.attachmentPreviewFile = {
|
||||||
name: this.attachmentName(row),
|
name: this.attachmentName(row),
|
||||||
url,
|
url,
|
||||||
mimeType: row.mimeType || row.contentType || '',
|
mimeType: isPdf ? 'application/pdf' : row.mimeType || row.contentType || '',
|
||||||
|
isPdf,
|
||||||
};
|
};
|
||||||
this.attachmentDocumentPreviewVisible = true;
|
this.attachmentDocumentPreviewVisible = true;
|
||||||
},
|
},
|
||||||
@@ -2107,6 +2126,7 @@ export default {
|
|||||||
|
|
||||||
:deep(.el-input),
|
:deep(.el-input),
|
||||||
:deep(.el-select),
|
:deep(.el-select),
|
||||||
|
:deep(.el-tree-select),
|
||||||
:deep(.el-date-editor) {
|
:deep(.el-date-editor) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@
|
|||||||
v-if="hasPermission('payment_application_add')"
|
v-if="hasPermission('payment_application_add')"
|
||||||
type="primary"
|
type="primary"
|
||||||
plain
|
plain
|
||||||
@click="openCreate"
|
@click="openProjectAdvance"
|
||||||
>预付申请</el-button
|
>预付申请</el-button
|
||||||
>
|
>
|
||||||
<el-button
|
<el-button
|
||||||
@@ -114,9 +114,12 @@
|
|||||||
<el-link v-if="column.link" type="primary" @click="openView(row)">{{
|
<el-link v-if="column.link" type="primary" @click="openView(row)">{{
|
||||||
row[column.prop]
|
row[column.prop]
|
||||||
}}</el-link>
|
}}</el-link>
|
||||||
<el-tag v-else-if="column.status" :type="statusType(row.approvalStatus)" class="status-text">{{
|
<el-tag
|
||||||
row[column.prop] || '-'
|
v-else-if="column.status"
|
||||||
}}</el-tag>
|
:type="statusType(row.approvalStatus)"
|
||||||
|
class="status-text"
|
||||||
|
>{{ row[column.prop] || '-' }}</el-tag
|
||||||
|
>
|
||||||
<span v-else-if="column.money">{{ formatMoney(row[column.prop]) }}</span>
|
<span v-else-if="column.money">{{ formatMoney(row[column.prop]) }}</span>
|
||||||
<span v-else>{{ displayValue(row[column.prop]) }}</span>
|
<span v-else>{{ displayValue(row[column.prop]) }}</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -307,6 +310,12 @@ export default {
|
|||||||
openCreate() {
|
openCreate() {
|
||||||
this.$router.push({ path: '/payment/payment-application/form', query: { mode: 'add' } });
|
this.$router.push({ path: '/payment/payment-application/form', query: { mode: 'add' } });
|
||||||
},
|
},
|
||||||
|
openProjectAdvance() {
|
||||||
|
this.$router.push({
|
||||||
|
path: '/payment/payment-application/form',
|
||||||
|
query: { mode: 'add', paymentType: 'project_advance' },
|
||||||
|
});
|
||||||
|
},
|
||||||
openEdit(row) {
|
openEdit(row) {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path: '/payment/payment-application/form',
|
path: '/payment/payment-application/form',
|
||||||
@@ -320,7 +329,10 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
openSettlementPayment() {
|
openSettlementPayment() {
|
||||||
this.openCreate();
|
this.$router.push({
|
||||||
|
path: '/payment/payment-application/form',
|
||||||
|
query: { mode: 'add', paymentType: 'settlement_payment' },
|
||||||
|
});
|
||||||
},
|
},
|
||||||
selectedOne(action) {
|
selectedOne(action) {
|
||||||
if (this.selection.length !== 1) {
|
if (this.selection.length !== 1) {
|
||||||
|
|||||||
@@ -4,7 +4,11 @@
|
|||||||
v-bind="editorContainerProps"
|
v-bind="editorContainerProps"
|
||||||
@update:model-value="visible = $event"
|
@update:model-value="visible = $event"
|
||||||
>
|
>
|
||||||
<div v-loading="loading" class="formal-editor">
|
<div
|
||||||
|
v-loading="loading"
|
||||||
|
class="formal-editor"
|
||||||
|
:class="{ 'formal-editor--page': pageMode }"
|
||||||
|
>
|
||||||
<section-card title="结算基本信息">
|
<section-card title="结算基本信息">
|
||||||
<el-form
|
<el-form
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
@@ -319,26 +323,164 @@
|
|||||||
</div>
|
</div>
|
||||||
</section-card>
|
</section-card>
|
||||||
|
|
||||||
<section-card v-if="readonly && payments.length" title="付款信息">
|
<section-card title="发票信息">
|
||||||
<el-table :data="payments" border>
|
<div v-if="editable" class="formal-editor__invoice-claim">
|
||||||
|
<el-form inline label-position="right" label-width="auto" @submit.prevent>
|
||||||
|
<el-form-item label="发票号码">
|
||||||
|
<el-input
|
||||||
|
v-model="invoiceClaimNo"
|
||||||
|
clearable
|
||||||
|
maxlength="32"
|
||||||
|
placeholder="请输入发票号码"
|
||||||
|
@keyup.enter="claimInvoices"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" :loading="invoiceClaimLoading" @click="claimInvoices">
|
||||||
|
认领查询
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<el-table :data="invoices" border>
|
||||||
<el-table-column type="index" label="序号" width="64" align="center" />
|
<el-table-column type="index" label="序号" width="64" align="center" />
|
||||||
|
<el-table-column prop="invoiceNo" label="发票号" min-width="150" align="center" />
|
||||||
|
<el-table-column prop="invoiceDate" label="开票日期" min-width="130" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.invoiceDate) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="invoiceType" label="发票类型" min-width="150" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.invoiceType) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="taxRate" label="税率" min-width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.taxRate === null || row.taxRate === undefined ? '-' : `${row.taxRate}%` }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
v-for="column in paymentTableColumns"
|
prop="invoiceAmount"
|
||||||
:key="column.prop"
|
label="发票金额(含税)"
|
||||||
v-bind="column"
|
min-width="150"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<template #default="{ row }">{{ formatMoney(row.invoiceAmount) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="availableInvoiceAmount"
|
||||||
|
label="可匹配发票金额(含税)"
|
||||||
|
min-width="180"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<template #default="{ row }">{{ formatMoney(row.availableInvoiceAmount) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="matchedAmount"
|
||||||
|
label="匹配结算单金额(含税)"
|
||||||
|
min-width="190"
|
||||||
align="center"
|
align="center"
|
||||||
>
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span v-if="column.money">{{ formatMoney(row[column.prop]) }}</span>
|
<el-input-number
|
||||||
<span v-else-if="column.prop === 'paymentTypeName'">{{
|
v-if="editable"
|
||||||
row.paymentType === 'final' ? '尾款' : displayValue(row.paymentType)
|
v-model="row.matchedAmount"
|
||||||
}}</span>
|
:min="0"
|
||||||
<span v-else-if="column.prop === 'billStatusName'">{{
|
:max="Number(row.availableInvoiceAmount || 0)"
|
||||||
row.billStatus === 'reviewing' ? '审批中' : displayValue(row.billStatus)
|
:precision="2"
|
||||||
}}</span>
|
:controls="false"
|
||||||
<span v-else>{{ displayValue(row[column.prop]) }}</span>
|
/>
|
||||||
|
<span v-else>{{ formatMoney(row.matchedAmount) }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="220" align="center">
|
||||||
|
<template #default="{ row, $index }">
|
||||||
|
<div class="formal-editor__links">
|
||||||
|
<el-link type="primary" @click="viewInvoiceAttachment(row)">查看</el-link>
|
||||||
|
<el-link type="primary" @click="downloadInvoiceAttachment(row)">下载</el-link>
|
||||||
|
<el-link v-if="editable" type="danger" @click="removeInvoice($index)">
|
||||||
|
删除
|
||||||
|
</el-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</section-card>
|
||||||
|
|
||||||
|
<section-card v-if="readonly" title="付款信息">
|
||||||
|
<el-table :data="paymentApplications" border>
|
||||||
|
<el-table-column type="index" label="序号" width="64" align="center" />
|
||||||
|
<el-table-column prop="paymentTypeName" label="付款类型" min-width="120" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.paymentTypeName) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="paymentNo" label="单据号" min-width="160" align="center" />
|
||||||
|
<el-table-column prop="appliedAmount" label="申请付款金额" min-width="145" align="center">
|
||||||
|
<template #default="{ row }">{{ formatMoney(row.appliedAmount) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="paidAmount" label="已付款金额" min-width="130" align="center">
|
||||||
|
<template #default="{ row }">{{ formatMoney(row.paidAmount) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="approvalStatusName" label="单据状态" min-width="120" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.approvalStatusName) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="kingdeeBillNo" label="金蝶单据号" min-width="150" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.kingdeeBillNo) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="createUserName" label="创建人" min-width="120" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.createUserName) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="createTime" label="创建时间" min-width="170" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.createTime) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</section-card>
|
||||||
|
|
||||||
|
<section-card v-if="readonly" title="结算调整单">
|
||||||
|
<el-table :data="adjustments" border>
|
||||||
|
<el-table-column type="index" label="序号" width="64" align="center" />
|
||||||
|
<el-table-column prop="adjustmentNo" label="调整单号" min-width="170" align="center" />
|
||||||
|
<el-table-column prop="adjustmentAmount" label="调整金额" min-width="130" align="center">
|
||||||
|
<template #default="{ row }">{{ formatMoney(row.adjustmentAmount) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="approvalStatusName" label="单据状态" min-width="120" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.approvalStatusName) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="remark" label="备注" min-width="220" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.remark) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="kingdeeBillNo" label="金蝶单据号" min-width="150" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.kingdeeBillNo) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="createUserName" label="创建人" min-width="120" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.createUserName) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="createTime" label="创建时间" min-width="170" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.createTime) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</section-card>
|
||||||
|
|
||||||
|
<section-card v-if="readonly" title="变更记录">
|
||||||
|
<el-table :data="changeRecords" border>
|
||||||
|
<el-table-column type="index" label="序号" width="64" align="center" />
|
||||||
|
<el-table-column prop="changeType" label="变更类型" min-width="150" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.changeType) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="lineNo" label="行号" min-width="90" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.lineNo) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="operationType" label="类型" min-width="110" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.operationType) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="changeContent" label="变更内容" min-width="360" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.changeContent) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="changeReason" label="变更原因" min-width="220" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.changeReason) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="operatorName" label="操作人" min-width="120" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.operatorName) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="changeTime" label="变更时间" min-width="170" align="center">
|
||||||
|
<template #default="{ row }">{{ displayValue(row.changeTime) }}</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</section-card>
|
</section-card>
|
||||||
</div>
|
</div>
|
||||||
@@ -568,12 +710,12 @@ import {
|
|||||||
candidateColumns,
|
candidateColumns,
|
||||||
candidateDetailColumns,
|
candidateDetailColumns,
|
||||||
detailColumns,
|
detailColumns,
|
||||||
paymentColumns,
|
|
||||||
sourceColumns,
|
sourceColumns,
|
||||||
summaryColumns,
|
summaryColumns,
|
||||||
} from '@/option/settlement/formalSettlementTable';
|
} from '@/option/settlement/formalSettlementTable';
|
||||||
import { getDictionary } from '@/api/system/dictbiz';
|
import { getDictionary } from '@/api/system/dictbiz';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
|
import { downloadFileByUrl } from '@/utils/util';
|
||||||
import * as XLSX from 'xlsx';
|
import * as XLSX from 'xlsx';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -597,8 +739,13 @@ export default {
|
|||||||
sources: [],
|
sources: [],
|
||||||
details: [],
|
details: [],
|
||||||
summaryFees: [],
|
summaryFees: [],
|
||||||
payments: [],
|
paymentApplications: [],
|
||||||
|
adjustments: [],
|
||||||
|
changeRecords: [],
|
||||||
attachments: [],
|
attachments: [],
|
||||||
|
invoices: [],
|
||||||
|
invoiceClaimNo: '',
|
||||||
|
invoiceClaimLoading: false,
|
||||||
attachmentUploadFiles: [],
|
attachmentUploadFiles: [],
|
||||||
attachmentTypeOptions: [],
|
attachmentTypeOptions: [],
|
||||||
attachmentFileTypes: [
|
attachmentFileTypes: [
|
||||||
@@ -627,7 +774,6 @@ export default {
|
|||||||
sourceTableColumns: sourceColumns,
|
sourceTableColumns: sourceColumns,
|
||||||
summaryTableColumns: summaryColumns,
|
summaryTableColumns: summaryColumns,
|
||||||
detailTableColumns: detailColumns,
|
detailTableColumns: detailColumns,
|
||||||
paymentTableColumns: paymentColumns,
|
|
||||||
candidateTableColumns: candidateColumns,
|
candidateTableColumns: candidateColumns,
|
||||||
candidateDetailTableColumns: candidateDetailColumns,
|
candidateDetailTableColumns: candidateDetailColumns,
|
||||||
rules: {
|
rules: {
|
||||||
@@ -750,8 +896,12 @@ export default {
|
|||||||
this.sources = [];
|
this.sources = [];
|
||||||
this.details = [];
|
this.details = [];
|
||||||
this.summaryFees = [];
|
this.summaryFees = [];
|
||||||
this.payments = [];
|
this.paymentApplications = [];
|
||||||
|
this.adjustments = [];
|
||||||
|
this.changeRecords = [];
|
||||||
this.attachments = [];
|
this.attachments = [];
|
||||||
|
this.invoices = [];
|
||||||
|
this.invoiceClaimNo = '';
|
||||||
this.attachmentUploadFiles = [];
|
this.attachmentUploadFiles = [];
|
||||||
this.detailCollapsed = false;
|
this.detailCollapsed = false;
|
||||||
this.resetDetailQuery(false);
|
this.resetDetailQuery(false);
|
||||||
@@ -782,8 +932,11 @@ export default {
|
|||||||
this.sources = data.sources || [];
|
this.sources = data.sources || [];
|
||||||
this.details = data.details || [];
|
this.details = data.details || [];
|
||||||
this.summaryFees = data.summaryFees || [];
|
this.summaryFees = data.summaryFees || [];
|
||||||
this.payments = data.payments || [];
|
this.paymentApplications = data.paymentApplications || [];
|
||||||
|
this.adjustments = data.adjustments || [];
|
||||||
|
this.changeRecords = data.changeRecords || [];
|
||||||
this.attachments = this.parseAttachments(data.attachmentsJson);
|
this.attachments = this.parseAttachments(data.attachmentsJson);
|
||||||
|
this.invoices = data.invoices || [];
|
||||||
this.sortAttachments();
|
this.sortAttachments();
|
||||||
this.contracts = this.allContracts.filter(
|
this.contracts = this.allContracts.filter(
|
||||||
item => String(item.projectId) === String(this.form.projectId)
|
item => String(item.projectId) === String(this.form.projectId)
|
||||||
@@ -1279,6 +1432,130 @@ export default {
|
|||||||
this.adjust.saving = false;
|
this.adjust.saving = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
claimInvoices() {
|
||||||
|
this.invoiceClaimLoading = true;
|
||||||
|
try {
|
||||||
|
const keyword = String(this.invoiceClaimNo || '').trim();
|
||||||
|
const defaultNo = `MOCK${this.$dayjs().format('YYYYMMDD')}`;
|
||||||
|
const baseNo = (keyword || defaultNo).slice(0, 29);
|
||||||
|
const numbers = [baseNo, `${baseNo}-02`, `${baseNo}-03`];
|
||||||
|
const invoiceAmounts = [1000, 2000, 3000];
|
||||||
|
const availableAmounts = [1000, 1000, 3000];
|
||||||
|
const preferredMatchedAmounts = [1000, 1000, 2000];
|
||||||
|
let remainingAmount = Math.max(
|
||||||
|
Number(this.form.settlementAmount || this.summaryTotal || 0) -
|
||||||
|
this.invoices.reduce((total, item) => total + Number(item.matchedAmount || 0), 0),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
const existingNumbers = new Set(this.invoices.map(item => String(item.invoiceNo)));
|
||||||
|
const mockRows = numbers
|
||||||
|
.map((invoiceNo, index) => {
|
||||||
|
const matchedAmount = Math.min(
|
||||||
|
preferredMatchedAmounts[index],
|
||||||
|
availableAmounts[index],
|
||||||
|
remainingAmount
|
||||||
|
);
|
||||||
|
remainingAmount = Number((remainingAmount - matchedAmount).toFixed(2));
|
||||||
|
return {
|
||||||
|
invoiceNo,
|
||||||
|
invoiceDate: this.$dayjs()
|
||||||
|
.subtract(index, 'day')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
invoiceType: index === 1 ? '增值税普通发票' : '增值税专用发票',
|
||||||
|
taxRate: [3, 6, 9][index],
|
||||||
|
invoiceAmount: invoiceAmounts[index],
|
||||||
|
availableInvoiceAmount: availableAmounts[index],
|
||||||
|
matchedAmount,
|
||||||
|
attachmentJson: '',
|
||||||
|
mockData: true,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.filter(item => !existingNumbers.has(item.invoiceNo));
|
||||||
|
if (!mockRows.length) {
|
||||||
|
this.$message.warning('当前发票号码的Mock数据已认领');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.invoices = [...this.invoices, ...mockRows];
|
||||||
|
this.$message.success(`已生成${mockRows.length}条Mock发票数据`);
|
||||||
|
} finally {
|
||||||
|
this.invoiceClaimLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
validateInvoices() {
|
||||||
|
const invoiceNumbers = new Set();
|
||||||
|
let matchedTotal = 0;
|
||||||
|
for (const row of this.invoices) {
|
||||||
|
const invoiceNo = String(row.invoiceNo || '').trim();
|
||||||
|
const invoiceAmount = Number(row.invoiceAmount || 0);
|
||||||
|
const availableAmount = Number(row.availableInvoiceAmount || 0);
|
||||||
|
const matchedAmount = Number(row.matchedAmount || 0);
|
||||||
|
const taxRate = Number(row.taxRate || 0);
|
||||||
|
if (!invoiceNo) {
|
||||||
|
this.$message.warning('发票号不能为空');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (invoiceNumbers.has(invoiceNo)) {
|
||||||
|
this.$message.warning(`发票号${invoiceNo}重复`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
invoiceNumbers.add(invoiceNo);
|
||||||
|
if ([invoiceAmount, availableAmount, matchedAmount].some(value => value < 0)) {
|
||||||
|
this.$message.warning(`发票${invoiceNo}的金额不能小于0`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (availableAmount > invoiceAmount) {
|
||||||
|
this.$message.warning(`发票${invoiceNo}的可匹配金额不能超过发票金额`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (matchedAmount > availableAmount) {
|
||||||
|
this.$message.warning(`发票${invoiceNo}的匹配金额不能超过可匹配金额`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (taxRate < 0 || taxRate > 100) {
|
||||||
|
this.$message.warning(`发票${invoiceNo}的税率必须在0-100之间`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
matchedTotal += matchedAmount;
|
||||||
|
}
|
||||||
|
if (matchedTotal > Number(this.form.settlementAmount || 0)) {
|
||||||
|
this.$message.warning('发票匹配结算单金额合计不能超过结算金额');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
removeInvoice(index) {
|
||||||
|
this.invoices.splice(index, 1);
|
||||||
|
},
|
||||||
|
invoiceAttachment(row = {}) {
|
||||||
|
if (!row.attachmentJson) return {};
|
||||||
|
if (typeof row.attachmentJson === 'object') {
|
||||||
|
return Array.isArray(row.attachmentJson) ? row.attachmentJson[0] || {} : row.attachmentJson;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(row.attachmentJson);
|
||||||
|
return Array.isArray(parsed) ? parsed[0] || {} : parsed || {};
|
||||||
|
} catch {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
invoiceAttachmentUrl(row) {
|
||||||
|
const attachment = this.invoiceAttachment(row);
|
||||||
|
return attachment.url || attachment.link || attachment.fileUrl || '';
|
||||||
|
},
|
||||||
|
invoiceAttachmentName(row) {
|
||||||
|
const attachment = this.invoiceAttachment(row);
|
||||||
|
return attachment.originalName || attachment.name || `${row.invoiceNo || '发票'}.pdf`;
|
||||||
|
},
|
||||||
|
viewInvoiceAttachment(row) {
|
||||||
|
const url = this.invoiceAttachmentUrl(row);
|
||||||
|
if (!url) return this.$message.warning('当前Mock发票暂无可查看附件');
|
||||||
|
window.open(url, '_blank');
|
||||||
|
},
|
||||||
|
downloadInvoiceAttachment(row) {
|
||||||
|
const url = this.invoiceAttachmentUrl(row);
|
||||||
|
if (!url) return this.$message.warning('当前Mock发票暂无可下载附件');
|
||||||
|
downloadFileByUrl(url, this.invoiceAttachmentName(row));
|
||||||
|
},
|
||||||
async handleSave() {
|
async handleSave() {
|
||||||
await this.$refs.formRef.validate();
|
await this.$refs.formRef.validate();
|
||||||
if (!this.form.sourcePreSettlementIds.length && !this.form.sourceDetailIds.length) {
|
if (!this.form.sourcePreSettlementIds.length && !this.form.sourceDetailIds.length) {
|
||||||
@@ -1292,6 +1569,7 @@ export default {
|
|||||||
if (invalidManualFee) {
|
if (invalidManualFee) {
|
||||||
return this.$message.warning('请完善手工费用的费用类型和费用项');
|
return this.$message.warning('请完善手工费用的费用类型和费用项');
|
||||||
}
|
}
|
||||||
|
if (!this.validateInvoices()) return;
|
||||||
if (!this.validateAttachments()) return;
|
if (!this.validateAttachments()) return;
|
||||||
this.saving = true;
|
this.saving = true;
|
||||||
try {
|
try {
|
||||||
@@ -1320,6 +1598,16 @@ export default {
|
|||||||
manualFlag: row.manualFlag || 0,
|
manualFlag: row.manualFlag || 0,
|
||||||
})),
|
})),
|
||||||
attachmentsJson: this.stringifyAttachments(this.attachments),
|
attachmentsJson: this.stringifyAttachments(this.attachments),
|
||||||
|
invoices: this.invoices.map(row => ({
|
||||||
|
invoiceNo: String(row.invoiceNo || '').trim(),
|
||||||
|
invoiceDate: row.invoiceDate || null,
|
||||||
|
invoiceType: row.invoiceType || '',
|
||||||
|
taxRate: Number(row.taxRate || 0),
|
||||||
|
invoiceAmount: Number(row.invoiceAmount || 0),
|
||||||
|
availableInvoiceAmount: Number(row.availableInvoiceAmount || 0),
|
||||||
|
matchedAmount: Number(row.matchedAmount || 0),
|
||||||
|
attachmentJson: row.attachmentJson || '',
|
||||||
|
})),
|
||||||
remark: this.form.remark,
|
remark: this.form.remark,
|
||||||
});
|
});
|
||||||
this.$message.success('保存成功');
|
this.$message.success('保存成功');
|
||||||
@@ -1525,6 +1813,9 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.formal-editor--page {
|
||||||
|
padding-bottom: 72px;
|
||||||
|
}
|
||||||
.formal-editor__actions {
|
.formal-editor__actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -1598,6 +1889,23 @@ export default {
|
|||||||
.formal-editor__attachment-upload {
|
.formal-editor__attachment-upload {
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
}
|
}
|
||||||
|
.formal-editor__invoice-claim {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-end;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
.formal-editor__invoice-claim-hint {
|
||||||
|
color: var(--el-color-danger);
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.formal-editor__invoice-claim :deep(.el-form-item) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.formal-editor__invoice-claim :deep(.el-input) {
|
||||||
|
width: 360px;
|
||||||
|
}
|
||||||
.formal-editor__negative-amount {
|
.formal-editor__negative-amount {
|
||||||
color: var(--el-color-danger);
|
color: var(--el-color-danger);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,14 @@
|
|||||||
<section-card title="证书附件" class="ship-ledger__section">
|
<section-card title="证书附件" class="ship-ledger__section">
|
||||||
<div class="ship-ledger__images">
|
<div class="ship-ledger__images">
|
||||||
<div v-for="item in imageFields" :key="item.prop" class="ship-ledger__image-item">
|
<div v-for="item in imageFields" :key="item.prop" class="ship-ledger__image-item">
|
||||||
<el-image v-if="shipDetail[item.prop]" :src="shipDetail[item.prop]" :preview-src-list="imageUrls" preview-teleported fit="cover" />
|
<el-image
|
||||||
|
v-if="shipDetail[item.prop]"
|
||||||
|
:src="shipDetail[item.prop]"
|
||||||
|
:preview-src-list="imageUrls"
|
||||||
|
:initial-index="item.previewIndex"
|
||||||
|
preview-teleported
|
||||||
|
fit="cover"
|
||||||
|
/>
|
||||||
<el-empty v-else :image-size="36" description="暂无附件" />
|
<el-empty v-else :image-size="36" description="暂无附件" />
|
||||||
<span>{{ item.label }}</span>
|
<span>{{ item.label }}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -68,7 +75,21 @@ export default {
|
|||||||
data() { return { detailLoading: false, tableLoading: false, shipDetail: {}, activeTab: 'insurance', records: [], page: { current: 1, size: 10, total: 0 } }; },
|
data() { return { detailLoading: false, tableLoading: false, shipDetail: {}, activeTab: 'insurance', records: [], page: { current: 1, size: 10, total: 0 } }; },
|
||||||
computed: {
|
computed: {
|
||||||
tabs() { return tabConfigs; }, activeConfig() { return tabConfigs.find(item => item.name === this.activeTab) || tabConfigs[0]; }, activeColumns() { return this.activeConfig.columns; },
|
tabs() { return tabConfigs; }, activeConfig() { return tabConfigs.find(item => item.name === this.activeTab) || tabConfigs[0]; }, activeColumns() { return this.activeConfig.columns; },
|
||||||
imageFields() { return [['船舶所有权证书', 'ownershipCertImage'], ['内河船舶安全与环保证书', 'safetyCertImage'], ['船舶国籍证书', 'nationalityCertImage'], ['最低安全配员证书', 'safeManningCertImage'], ['船舶营业运输证', 'businessTransportCertImage'], ['光船租赁登记证书', 'leaseContractImage']].map(([label, prop]) => ({ label, prop })); },
|
imageFields() {
|
||||||
|
let previewIndex = 0;
|
||||||
|
return [
|
||||||
|
['船舶所有权证书', 'ownershipCertImage'],
|
||||||
|
['内河船舶安全与环保证书', 'safetyCertImage'],
|
||||||
|
['船舶国籍证书', 'nationalityCertImage'],
|
||||||
|
['最低安全配员证书', 'safeManningCertImage'],
|
||||||
|
['船舶营业运输证', 'businessTransportCertImage'],
|
||||||
|
['光船租赁登记证书', 'leaseContractImage'],
|
||||||
|
].map(([label, prop]) => {
|
||||||
|
const item = { label, prop, previewIndex };
|
||||||
|
if (this.shipDetail[prop]) previewIndex += 1;
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
},
|
||||||
imageUrls() { return this.imageFields.map(item => this.shipDetail[item.prop]).filter(Boolean); },
|
imageUrls() { return this.imageFields.map(item => this.shipDetail[item.prop]).filter(Boolean); },
|
||||||
sections() { const s = this.shipDetail; return [
|
sections() { const s = this.shipDetail; return [
|
||||||
{ title: '船舶基本信息', items: [['船舶所属组织', 'organizationName'], ['船名', 'shipName'], ['安放龙骨日期/建造完工日期', 'constructionDate'], ['总长(m)', 'totalLength'], ['船宽(m)', 'shipWidth'], ['型深(m)', 'moldedDepth'], ['最大船高(m)', 'maxShipHeight'], ['空载吃水(t)', 'lightDraft'], ['满载吃水(t)', 'fullLoadDraft'], ['航区', 'navigationArea']] },
|
{ title: '船舶基本信息', items: [['船舶所属组织', 'organizationName'], ['船名', 'shipName'], ['安放龙骨日期/建造完工日期', 'constructionDate'], ['总长(m)', 'totalLength'], ['船宽(m)', 'shipWidth'], ['型深(m)', 'moldedDepth'], ['最大船高(m)', 'maxShipHeight'], ['空载吃水(t)', 'lightDraft'], ['满载吃水(t)', 'fullLoadDraft'], ['航区', 'navigationArea']] },
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
v-if="vehicleDetail[item.prop]"
|
v-if="vehicleDetail[item.prop]"
|
||||||
:src="vehicleDetail[item.prop]"
|
:src="vehicleDetail[item.prop]"
|
||||||
:preview-src-list="imageUrls"
|
:preview-src-list="imageUrls"
|
||||||
|
:initial-index="item.previewIndex"
|
||||||
preview-teleported
|
preview-teleported
|
||||||
fit="cover"
|
fit="cover"
|
||||||
/>
|
/>
|
||||||
@@ -312,13 +313,18 @@ export default {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
imageFields() {
|
imageFields() {
|
||||||
|
let previewIndex = 0;
|
||||||
return [
|
return [
|
||||||
['行驶证主页面', 'drivingLicenseImage'],
|
['行驶证主页面', 'drivingLicenseImage'],
|
||||||
['行驶证主页反页', 'drivingLicenseMainBack'],
|
['行驶证主页反页', 'drivingLicenseMainBack'],
|
||||||
['行驶证副页正页', 'drivingLicenseViceFront'],
|
['行驶证副页正页', 'drivingLicenseViceFront'],
|
||||||
['行驶证副页反页', 'drivingLicenseViceBack'],
|
['行驶证副页反页', 'drivingLicenseViceBack'],
|
||||||
['道路运输证', 'roadTransportCertImage'],
|
['道路运输证', 'roadTransportCertImage'],
|
||||||
].map(([label, prop]) => ({ label, prop }));
|
].map(([label, prop]) => {
|
||||||
|
const item = { label, prop, previewIndex };
|
||||||
|
if (this.vehicleDetail[prop]) previewIndex += 1;
|
||||||
|
return item;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
imageUrls() {
|
imageUrls() {
|
||||||
return this.imageFields.map(item => this.vehicleDetail[item.prop]).filter(Boolean);
|
return this.imageFields.map(item => this.vehicleDetail[item.prop]).filter(Boolean);
|
||||||
|
|||||||
@@ -204,6 +204,29 @@
|
|||||||
<el-input v-model="driverForm.address" maxlength="200" show-word-limit />
|
<el-input v-model="driverForm.address" maxlength="200" show-word-limit />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="18">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="驾驶车辆" prop="drivingVehicle">
|
||||||
|
<el-input
|
||||||
|
v-model="driverForm.drivingVehicle"
|
||||||
|
maxlength="30"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入或选择车辆"
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<el-tooltip content="选择车辆" placement="top">
|
||||||
|
<el-button
|
||||||
|
:icon="List"
|
||||||
|
:disabled="readonly"
|
||||||
|
aria-label="选择车辆"
|
||||||
|
@click="openVehicleSelector"
|
||||||
|
/>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="岗位" prop="postList">
|
<el-form-item label="岗位" prop="postList">
|
||||||
<el-checkbox-group v-model="driverForm.postList">
|
<el-checkbox-group v-model="driverForm.postList">
|
||||||
@@ -487,6 +510,64 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
v-model="vehicleSelectorVisible"
|
||||||
|
title="选择车辆"
|
||||||
|
append-to-body
|
||||||
|
width="92%"
|
||||||
|
top="4vh"
|
||||||
|
class="vehicle-selector-dialog"
|
||||||
|
@closed="resetVehicleSelector"
|
||||||
|
>
|
||||||
|
<avue-crud
|
||||||
|
v-if="vehicleSelectorVisible"
|
||||||
|
ref="vehicleSelectorCrud"
|
||||||
|
v-model="vehicleSelectorForm"
|
||||||
|
v-model:page="vehicleSelectorPage"
|
||||||
|
:option="vehicleSelectorOption"
|
||||||
|
:table-loading="vehicleSelectorLoading"
|
||||||
|
:data="vehicleSelectorData"
|
||||||
|
@search-change="vehicleSelectorSearchChange"
|
||||||
|
@search-reset="vehicleSelectorSearchReset"
|
||||||
|
@current-change="vehicleSelectorCurrentChange"
|
||||||
|
@size-change="vehicleSelectorSizeChange"
|
||||||
|
@refresh-change="vehicleSelectorRefreshChange"
|
||||||
|
@on-load="loadVehicleSelector"
|
||||||
|
>
|
||||||
|
<template #plateNo="{ row }">
|
||||||
|
<span>{{ row.plateNo || '-' }}</span>
|
||||||
|
</template>
|
||||||
|
<template #organizationName="{ row }">
|
||||||
|
{{ String(row.organizationName || '').replace(/^[\s\u3000]+/, '') }}
|
||||||
|
</template>
|
||||||
|
<template #boundDriver>
|
||||||
|
<span>-</span>
|
||||||
|
</template>
|
||||||
|
<template #certificationStatus="{ row }">
|
||||||
|
<el-tag :type="getVehicleCertificationStatus(row).type" class="status-text">
|
||||||
|
{{ getVehicleCertificationStatus(row).label }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
<template #status="{ row }">
|
||||||
|
<el-tag :type="row.status === 1 ? 'primary' : 'info'" class="status-text">
|
||||||
|
{{ row.status === 1 ? '启用' : '停用' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
<template #drivingLicenseEndDate="{ row }">
|
||||||
|
{{ formatEndDate(row.drivingLicenseEndDate, row.drivingLicenseLongTerm) }}
|
||||||
|
</template>
|
||||||
|
<template #roadTransportCertEndDate="{ row }">
|
||||||
|
{{ formatEndDate(row.roadTransportCertEndDate, row.roadTransportCertLongTerm) }}
|
||||||
|
</template>
|
||||||
|
<template #annualReviewEndDate="{ row }">
|
||||||
|
{{ formatEndDate(row.annualReviewEndDate, row.annualReviewLongTerm) }}
|
||||||
|
</template>
|
||||||
|
<template #menu="{ row }">
|
||||||
|
<el-link type="primary" @click="selectDrivingVehicle(row)">选择</el-link>
|
||||||
|
</template>
|
||||||
|
</avue-crud>
|
||||||
|
</el-dialog>
|
||||||
</basic-container>
|
</basic-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -494,7 +575,9 @@
|
|||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import { ElLoading } from 'element-plus';
|
import { ElLoading } from 'element-plus';
|
||||||
|
import { List } from '@element-plus/icons-vue';
|
||||||
import { option } from '@/option/transportCapacity/driver';
|
import { option } from '@/option/transportCapacity/driver';
|
||||||
|
import { option as transportVehicleOption } from '@/option/transportCapacity/transport-vehicle';
|
||||||
import {
|
import {
|
||||||
getList,
|
getList,
|
||||||
getDetail,
|
getDetail,
|
||||||
@@ -506,6 +589,7 @@ import {
|
|||||||
recognitionTransportCertificates,
|
recognitionTransportCertificates,
|
||||||
recognizeBaiduOcr,
|
recognizeBaiduOcr,
|
||||||
} from '@/api/transportCapacity/driver';
|
} from '@/api/transportCapacity/driver';
|
||||||
|
import { getList as getVehicleList } from '@/api/transportCapacity/transport-vehicle';
|
||||||
import { getDeptTree } from '@/api/system/dept';
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
import { getDictionary } from '@/api/system/dictbiz';
|
import { getDictionary } from '@/api/system/dictbiz';
|
||||||
import { getLazyTree } from '@/api/base/region';
|
import { getLazyTree } from '@/api/base/region';
|
||||||
@@ -515,6 +599,25 @@ import { getUploadHeaders } from '@/utils/upload';
|
|||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import ImageUploadField from '@/components/image-upload-field/main.vue';
|
import ImageUploadField from '@/components/image-upload-field/main.vue';
|
||||||
|
|
||||||
|
const vehicleSelectorOption = {
|
||||||
|
...transportVehicleOption,
|
||||||
|
height: 430,
|
||||||
|
selection: false,
|
||||||
|
addBtn: false,
|
||||||
|
editBtn: false,
|
||||||
|
delBtn: false,
|
||||||
|
viewBtn: false,
|
||||||
|
columnBtn: false,
|
||||||
|
menuWidth: 90,
|
||||||
|
menuFixed: 'right',
|
||||||
|
column: transportVehicleOption.column.map(column => ({
|
||||||
|
...column,
|
||||||
|
dicData: Array.isArray(column.dicData)
|
||||||
|
? column.dicData.map(item => ({ ...item }))
|
||||||
|
: column.dicData,
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
|
||||||
const emptyForm = () => ({
|
const emptyForm = () => ({
|
||||||
id: '',
|
id: '',
|
||||||
driverName: '',
|
driverName: '',
|
||||||
@@ -526,6 +629,7 @@ const emptyForm = () => ({
|
|||||||
addressRegionPath: [],
|
addressRegionPath: [],
|
||||||
addressRegion: '',
|
addressRegion: '',
|
||||||
address: '',
|
address: '',
|
||||||
|
drivingVehicle: '',
|
||||||
postList: ['司机'],
|
postList: ['司机'],
|
||||||
posts: '',
|
posts: '',
|
||||||
idCardFront: '',
|
idCardFront: '',
|
||||||
@@ -560,6 +664,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
option,
|
option,
|
||||||
|
List,
|
||||||
form: {},
|
form: {},
|
||||||
query: {
|
query: {
|
||||||
expireStatus: '',
|
expireStatus: '',
|
||||||
@@ -581,6 +686,17 @@ export default {
|
|||||||
expired: 0,
|
expired: 0,
|
||||||
},
|
},
|
||||||
driverBox: false,
|
driverBox: false,
|
||||||
|
vehicleSelectorVisible: false,
|
||||||
|
vehicleSelectorLoading: false,
|
||||||
|
vehicleSelectorOption,
|
||||||
|
vehicleSelectorForm: {},
|
||||||
|
vehicleSelectorData: [],
|
||||||
|
vehicleSelectorSearchForm: {},
|
||||||
|
vehicleSelectorPage: {
|
||||||
|
pageSize: 10,
|
||||||
|
currentPage: 1,
|
||||||
|
total: 0,
|
||||||
|
},
|
||||||
readonly: false,
|
readonly: false,
|
||||||
driverForm: emptyForm(),
|
driverForm: emptyForm(),
|
||||||
drivingLicenseUploads: {},
|
drivingLicenseUploads: {},
|
||||||
@@ -745,6 +861,11 @@ export default {
|
|||||||
this.organizationOptions = this.formatDeptOptions(res.data.data || []);
|
this.organizationOptions = this.formatDeptOptions(res.data.data || []);
|
||||||
const column = this.findColumn(this.option.column, 'organizationName');
|
const column = this.findColumn(this.option.column, 'organizationName');
|
||||||
column.dicData = this.organizationOptions;
|
column.dicData = this.organizationOptions;
|
||||||
|
const vehicleColumn = this.findColumn(
|
||||||
|
this.vehicleSelectorOption.column,
|
||||||
|
'organizationName'
|
||||||
|
);
|
||||||
|
vehicleColumn.dicData = this.organizationOptions;
|
||||||
if (this.driverBox && !this.driverForm.id && !this.driverForm.organizationName) {
|
if (this.driverBox && !this.driverForm.id && !this.driverForm.organizationName) {
|
||||||
this.driverForm.organizationName = this.getCurrentOrganizationName();
|
this.driverForm.organizationName = this.getCurrentOrganizationName();
|
||||||
}
|
}
|
||||||
@@ -952,6 +1073,75 @@ export default {
|
|||||||
this.submitLoading = false;
|
this.submitLoading = false;
|
||||||
this.$refs.driverForm?.clearValidate();
|
this.$refs.driverForm?.clearValidate();
|
||||||
},
|
},
|
||||||
|
openVehicleSelector() {
|
||||||
|
if (this.readonly) return;
|
||||||
|
this.vehicleSelectorPage.currentPage = 1;
|
||||||
|
this.vehicleSelectorVisible = true;
|
||||||
|
},
|
||||||
|
resetVehicleSelector() {
|
||||||
|
this.vehicleSelectorForm = {};
|
||||||
|
this.vehicleSelectorData = [];
|
||||||
|
this.vehicleSelectorSearchForm = {};
|
||||||
|
this.vehicleSelectorPage = {
|
||||||
|
pageSize: 10,
|
||||||
|
currentPage: 1,
|
||||||
|
total: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
normalizeVehicleSelectorQuery(params = {}) {
|
||||||
|
const query = {
|
||||||
|
...this.vehicleSelectorSearchForm,
|
||||||
|
...params,
|
||||||
|
};
|
||||||
|
if (Array.isArray(query.organizationName)) {
|
||||||
|
query.organizationName = query.organizationName[query.organizationName.length - 1] || '';
|
||||||
|
}
|
||||||
|
return query;
|
||||||
|
},
|
||||||
|
loadVehicleSelector(page = this.vehicleSelectorPage, params = {}) {
|
||||||
|
this.vehicleSelectorLoading = true;
|
||||||
|
getVehicleList(page.currentPage, page.pageSize, this.normalizeVehicleSelectorQuery(params))
|
||||||
|
.then(res => {
|
||||||
|
const data = res.data.data || {};
|
||||||
|
this.vehicleSelectorData = data.records || [];
|
||||||
|
this.vehicleSelectorPage.total = data.total || 0;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.vehicleSelectorLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
vehicleSelectorSearchChange(params, done) {
|
||||||
|
this.vehicleSelectorSearchForm = params;
|
||||||
|
this.vehicleSelectorPage.currentPage = 1;
|
||||||
|
this.loadVehicleSelector(this.vehicleSelectorPage, params);
|
||||||
|
done();
|
||||||
|
},
|
||||||
|
vehicleSelectorSearchReset() {
|
||||||
|
this.vehicleSelectorSearchForm = {};
|
||||||
|
this.vehicleSelectorPage.currentPage = 1;
|
||||||
|
this.loadVehicleSelector();
|
||||||
|
},
|
||||||
|
vehicleSelectorCurrentChange(currentPage) {
|
||||||
|
this.vehicleSelectorPage.currentPage = currentPage;
|
||||||
|
},
|
||||||
|
vehicleSelectorSizeChange(pageSize) {
|
||||||
|
this.vehicleSelectorPage.pageSize = pageSize;
|
||||||
|
},
|
||||||
|
vehicleSelectorRefreshChange() {
|
||||||
|
this.loadVehicleSelector();
|
||||||
|
},
|
||||||
|
selectDrivingVehicle(row) {
|
||||||
|
this.driverForm.drivingVehicle = row.plateNo || '';
|
||||||
|
this.vehicleSelectorVisible = false;
|
||||||
|
},
|
||||||
|
getVehicleCertificationStatus(row) {
|
||||||
|
const statusMap = {
|
||||||
|
0: { label: '认证中', type: 'warning' },
|
||||||
|
1: { label: '已认证', type: 'success' },
|
||||||
|
2: { label: '已驳回', type: 'danger' },
|
||||||
|
};
|
||||||
|
return statusMap[row.certificationStatus] || { label: '-', type: 'info' };
|
||||||
|
},
|
||||||
setImage(prop, url) {
|
setImage(prop, url) {
|
||||||
this.driverForm[prop] = url;
|
this.driverForm[prop] = url;
|
||||||
this.$refs.driverForm?.validateField(prop);
|
this.$refs.driverForm?.validateField(prop);
|
||||||
|
|||||||
@@ -96,22 +96,10 @@
|
|||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #attachmentsForm>
|
<template #attachmentsForm>
|
||||||
<vehicle-attachment-upload
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
v-model="form.attachments"
|
|
||||||
:readonly="boxType === 'view'"
|
|
||||||
button-text="新增"
|
|
||||||
button-icon="el-icon-plus"
|
|
||||||
:show-tip="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<template #attachments-form>
|
<template #attachments-form>
|
||||||
<vehicle-attachment-upload
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
v-model="form.attachments"
|
|
||||||
:readonly="boxType === 'view'"
|
|
||||||
button-text="新增"
|
|
||||||
button-icon="el-icon-plus"
|
|
||||||
:show-tip="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
<empty-pagination
|
<empty-pagination
|
||||||
@@ -142,6 +130,7 @@ import { downloadXls } from '@/utils/util';
|
|||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/accident-record';
|
import { excelOption, option } from '@/option/vehicle/accident-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
@@ -152,6 +141,9 @@ const createTimeRangeMap = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
VehicleAttachmentTable,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {},
|
form: {},
|
||||||
|
|||||||
@@ -83,22 +83,10 @@
|
|||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #attachmentsForm>
|
<template #attachmentsForm>
|
||||||
<vehicle-attachment-upload
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
v-model="form.attachments"
|
|
||||||
:readonly="boxType === 'view'"
|
|
||||||
button-text="新增"
|
|
||||||
button-icon="el-icon-plus"
|
|
||||||
:show-tip="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<template #attachments-form>
|
<template #attachments-form>
|
||||||
<vehicle-attachment-upload
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
v-model="form.attachments"
|
|
||||||
:readonly="boxType === 'view'"
|
|
||||||
button-text="新增"
|
|
||||||
button-icon="el-icon-plus"
|
|
||||||
:show-tip="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
<empty-pagination
|
<empty-pagination
|
||||||
@@ -128,12 +116,16 @@ import { exportBlob } from '@/api/common';
|
|||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/annual-inspection-record';
|
import { excelOption, option } from '@/option/vehicle/annual-inspection-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
VehicleAttachmentTable,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {},
|
form: {},
|
||||||
|
|||||||
@@ -146,9 +146,11 @@
|
|||||||
<el-table-column label="序号" type="index" width="90" align="center" />
|
<el-table-column label="序号" type="index" width="90" align="center" />
|
||||||
<el-table-column label="信用等级" prop="creditLevel" width="120" align="center" />
|
<el-table-column label="信用等级" prop="creditLevel" width="120" align="center" />
|
||||||
<el-table-column label="标准说明" prop="standardDescription" min-width="320" />
|
<el-table-column label="标准说明" prop="standardDescription" min-width="320" />
|
||||||
<el-table-column v-if="!readonly" label="操作" width="160" align="center">
|
<el-table-column label="操作" width="160" align="center">
|
||||||
<template #default="{ row, $index }">
|
<template #default="{ row, $index }">
|
||||||
<el-link type="primary" @click="openStandard(row, $index)">编辑</el-link>
|
<el-link type="primary" @click="openStandard(row, $index)">
|
||||||
|
{{ readonly ? '查看' : '编辑' }}
|
||||||
|
</el-link>
|
||||||
<el-link type="danger" v-if="!readonly" @click="removeStandard($index)"
|
<el-link type="danger" v-if="!readonly" @click="removeStandard($index)"
|
||||||
>删除</el-link
|
>删除</el-link
|
||||||
>
|
>
|
||||||
@@ -450,7 +452,7 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</section-card>
|
</section-card>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="standardBox = false">取消</el-button>
|
<el-button @click="standardBox = false">{{ readonly ? '关闭' : '取消' }}</el-button>
|
||||||
<el-button type="primary" v-if="!readonly" @click="saveStandard">保存</el-button>
|
<el-button type="primary" v-if="!readonly" @click="saveStandard">保存</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|||||||
@@ -701,8 +701,17 @@
|
|||||||
width="90%"
|
width="90%"
|
||||||
top="4vh"
|
top="4vh"
|
||||||
>
|
>
|
||||||
|
<pdf-preview
|
||||||
|
v-if="
|
||||||
|
qualificationDocumentPreviewVisible &&
|
||||||
|
qualificationPreviewFile.url &&
|
||||||
|
qualificationPreviewFile.isPdf
|
||||||
|
"
|
||||||
|
:source="qualificationPreviewFile.url"
|
||||||
|
@error="handleQualificationPreviewError"
|
||||||
|
/>
|
||||||
<open-file-viewer
|
<open-file-viewer
|
||||||
v-if="qualificationDocumentPreviewVisible && qualificationPreviewFile.url"
|
v-else-if="qualificationDocumentPreviewVisible && qualificationPreviewFile.url"
|
||||||
:file="qualificationPreviewFile.url"
|
:file="qualificationPreviewFile.url"
|
||||||
:file-name="qualificationPreviewFile.name"
|
:file-name="qualificationPreviewFile.name"
|
||||||
:mime-type="qualificationPreviewFile.mimeType"
|
:mime-type="qualificationPreviewFile.mimeType"
|
||||||
@@ -1385,7 +1394,7 @@ import { getDictionary } from '@/api/system/dictbiz';
|
|||||||
import { getDeptTree } from '@/api/system/dept';
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
import { getLazyTree } from '@/api/base/region';
|
import { getLazyTree } from '@/api/base/region';
|
||||||
import { exportBlob } from '@/api/common';
|
import { exportBlob } from '@/api/common';
|
||||||
import { downloadXls } from '@/utils/util';
|
import { downloadFileByUrl, downloadXls } from '@/utils/util';
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { getUploadHeaders } from '@/utils/upload';
|
import { getUploadHeaders } from '@/utils/upload';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
@@ -1396,7 +1405,6 @@ import {
|
|||||||
fallbackPlugin,
|
fallbackPlugin,
|
||||||
imagePlugin,
|
imagePlugin,
|
||||||
officePlugin,
|
officePlugin,
|
||||||
pdfPlugin,
|
|
||||||
textPlugin,
|
textPlugin,
|
||||||
} from '@open-file-viewer/core';
|
} from '@open-file-viewer/core';
|
||||||
import '@open-file-viewer/core/style.css';
|
import '@open-file-viewer/core/style.css';
|
||||||
@@ -1405,6 +1413,7 @@ import { mapGetters } from 'vuex';
|
|||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
import SectionCard from '@/components/section-card/main.vue';
|
import SectionCard from '@/components/section-card/main.vue';
|
||||||
|
import PdfPreview from '@/components/pdf-preview/main.vue';
|
||||||
|
|
||||||
const createTimeRangeMap = {
|
const createTimeRangeMap = {
|
||||||
createTimeRange: ['createTimeStart', 'createTimeEnd'],
|
createTimeRange: ['createTimeStart', 'createTimeEnd'],
|
||||||
@@ -1415,7 +1424,6 @@ const AMAP_SECURITY_CODE = '5aab65c632e48ebae0d0e28f5b28e21a';
|
|||||||
let amapLoader;
|
let amapLoader;
|
||||||
const qualificationViewerPlugins = [
|
const qualificationViewerPlugins = [
|
||||||
imagePlugin(),
|
imagePlugin(),
|
||||||
pdfPlugin({ workerSrc: pdfWorkerSrc, useFetchData: true }),
|
|
||||||
officePlugin({ pdf: { workerSrc: pdfWorkerSrc, useFetchData: true } }),
|
officePlugin({ pdf: { workerSrc: pdfWorkerSrc, useFetchData: true } }),
|
||||||
textPlugin(),
|
textPlugin(),
|
||||||
fallbackPlugin(),
|
fallbackPlugin(),
|
||||||
@@ -1428,6 +1436,7 @@ export default {
|
|||||||
Location,
|
Location,
|
||||||
ElImageViewer,
|
ElImageViewer,
|
||||||
OpenFileViewer,
|
OpenFileViewer,
|
||||||
|
PdfPreview,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const nonNegativeLabelMap = {
|
const nonNegativeLabelMap = {
|
||||||
@@ -2424,8 +2433,10 @@ export default {
|
|||||||
initDeptTree() {
|
initDeptTree() {
|
||||||
getDeptTree(this.userInfo.tenantId)
|
getDeptTree(this.userInfo.tenantId)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
this.deptTree = this.normalizeDeptTree(res.data.data || []);
|
const deptTree = this.excludeExternalOrganization(res.data.data || []);
|
||||||
|
this.deptTree = this.normalizeDeptTree(deptTree);
|
||||||
this.deptOptions = this.flattenDept(this.deptTree);
|
this.deptOptions = this.flattenDept(this.deptTree);
|
||||||
|
this.setDefaultTopLevelDept();
|
||||||
const deptColumn = this.findColumn(this.option.column, 'deptName');
|
const deptColumn = this.findColumn(this.option.column, 'deptName');
|
||||||
deptColumn.renderSearch = scope => this.renderDeptSearch(scope);
|
deptColumn.renderSearch = scope => this.renderDeptSearch(scope);
|
||||||
})
|
})
|
||||||
@@ -2602,6 +2613,17 @@ export default {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
excludeExternalOrganization(tree = []) {
|
||||||
|
return tree.reduce((result, item) => {
|
||||||
|
const deptName = item.label || item.title || item.deptName || item.name || '';
|
||||||
|
if (String(deptName).trim() === '外部组织') return result;
|
||||||
|
result.push({
|
||||||
|
...item,
|
||||||
|
children: this.excludeExternalOrganization(item.children || []),
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}, []);
|
||||||
|
},
|
||||||
flattenDept(tree, level = 0) {
|
flattenDept(tree, level = 0) {
|
||||||
const result = [];
|
const result = [];
|
||||||
tree.forEach(item => {
|
tree.forEach(item => {
|
||||||
@@ -2616,6 +2638,18 @@ export default {
|
|||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
setDefaultTopLevelDept() {
|
||||||
|
const deptIds = Array.isArray(this.archiveForm.deptId)
|
||||||
|
? this.archiveForm.deptId
|
||||||
|
: this.archiveForm.deptId
|
||||||
|
? [this.archiveForm.deptId]
|
||||||
|
: [];
|
||||||
|
const firstTopLevelDept = this.deptTree[0];
|
||||||
|
if (!this.isArchivePage || this.$route.query.id || deptIds.length || !firstTopLevelDept) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.onDeptChange([firstTopLevelDept.value]);
|
||||||
|
},
|
||||||
onDeptChange(value) {
|
onDeptChange(value) {
|
||||||
const deptIds = Array.isArray(value) ? value : value ? [value] : [];
|
const deptIds = Array.isArray(value) ? value : value ? [value] : [];
|
||||||
const deptNames = deptIds
|
const deptNames = deptIds
|
||||||
@@ -3403,6 +3437,12 @@ export default {
|
|||||||
this.getQualificationFileExtension(file)
|
this.getQualificationFileExtension(file)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
isQualificationPdf(file) {
|
||||||
|
const mimeType = String(file.mimeType || file.contentType || '').toLowerCase();
|
||||||
|
return (
|
||||||
|
mimeType.includes('application/pdf') || this.getQualificationFileExtension(file) === 'pdf'
|
||||||
|
);
|
||||||
|
},
|
||||||
previewQualificationFile(file) {
|
previewQualificationFile(file) {
|
||||||
const url = this.getQualificationFileUrl(file);
|
const url = this.getQualificationFileUrl(file);
|
||||||
if (!url) {
|
if (!url) {
|
||||||
@@ -3420,10 +3460,12 @@ export default {
|
|||||||
this.qualificationImagePreviewVisible = true;
|
this.qualificationImagePreviewVisible = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const isPdf = this.isQualificationPdf(file);
|
||||||
this.qualificationPreviewFile = {
|
this.qualificationPreviewFile = {
|
||||||
name: file.originalName || file.name || '附件',
|
name: file.originalName || file.name || '附件',
|
||||||
url,
|
url,
|
||||||
mimeType: file.mimeType || file.contentType || '',
|
mimeType: isPdf ? 'application/pdf' : file.mimeType || file.contentType || '',
|
||||||
|
isPdf,
|
||||||
};
|
};
|
||||||
this.qualificationDocumentPreviewVisible = true;
|
this.qualificationDocumentPreviewVisible = true;
|
||||||
},
|
},
|
||||||
@@ -3473,20 +3515,46 @@ export default {
|
|||||||
})
|
})
|
||||||
.map(item => item.file);
|
.map(item => item.file);
|
||||||
},
|
},
|
||||||
getMissingQualificationTypes(files = this.qualificationFiles) {
|
getRequiredQualificationTypes(customerType = this.archiveForm.customerType) {
|
||||||
|
const customerTypes = Array.isArray(customerType)
|
||||||
|
? customerType
|
||||||
|
: this.splitValue(customerType);
|
||||||
|
const requiredTypes = ['营业执照', '法人身份证'];
|
||||||
|
const includesCarrier = customerTypes.some(item =>
|
||||||
|
['承运商', 'carrier'].includes(String(item || '').trim().toLowerCase())
|
||||||
|
);
|
||||||
|
if (includesCarrier) requiredTypes.push('运输许可证');
|
||||||
|
return requiredTypes;
|
||||||
|
},
|
||||||
|
isUploadedQualificationType(uploadedType, requiredType) {
|
||||||
|
const uploaded = String(uploadedType || '')
|
||||||
|
.replace(/\s/g, '')
|
||||||
|
.trim();
|
||||||
|
if (uploaded === requiredType || uploaded.includes(requiredType)) return true;
|
||||||
|
return requiredType === '运输许可证' && /运输.*许可证/.test(uploaded);
|
||||||
|
},
|
||||||
|
getMissingQualificationTypes(
|
||||||
|
files = this.qualificationFiles,
|
||||||
|
customerType = this.archiveForm.customerType
|
||||||
|
) {
|
||||||
const uploadedTypes = new Set(
|
const uploadedTypes = new Set(
|
||||||
(files || [])
|
(files || [])
|
||||||
.filter(item => item.url)
|
.filter(item => item.url)
|
||||||
.map(item => String(item.type || '').trim())
|
.map(item => String(item.type || '').trim())
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
);
|
);
|
||||||
return this.qualificationTypeOptions
|
return this.getRequiredQualificationTypes(customerType).filter(
|
||||||
.filter(item => String(item.label || item.value || '').trim() !== '其他附件')
|
requiredType =>
|
||||||
.filter(item => !uploadedTypes.has(String(item.value || item.label || '').trim()))
|
![...uploadedTypes].some(uploadedType =>
|
||||||
.map(item => item.label || item.value);
|
this.isUploadedQualificationType(uploadedType, requiredType)
|
||||||
|
)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
validateQualificationMaterials(files = this.qualificationFiles) {
|
validateQualificationMaterials(
|
||||||
const missing = this.getMissingQualificationTypes(files);
|
files = this.qualificationFiles,
|
||||||
|
customerType = this.archiveForm.customerType
|
||||||
|
) {
|
||||||
|
const missing = this.getMissingQualificationTypes(files, customerType);
|
||||||
if (!missing.length) return true;
|
if (!missing.length) return true;
|
||||||
this.$message.warning(`请先上传客商材料:${missing.join('、')}`);
|
this.$message.warning(`请先上传客商材料:${missing.join('、')}`);
|
||||||
return false;
|
return false;
|
||||||
@@ -3502,7 +3570,14 @@ export default {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
files.forEach(item => window.open(item.url, '_blank'));
|
files.forEach((item, index) => {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
downloadFileByUrl(
|
||||||
|
item.url,
|
||||||
|
item.originalName || item.name || `客商材料${index + 1}`
|
||||||
|
);
|
||||||
|
}, index * 300);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
handleQualificationSelectionChange(rows) {
|
handleQualificationSelectionChange(rows) {
|
||||||
this.selectedQualificationFiles = rows || [];
|
this.selectedQualificationFiles = rows || [];
|
||||||
@@ -3706,7 +3781,8 @@ export default {
|
|||||||
validateFormalForApproval(archive) {
|
validateFormalForApproval(archive) {
|
||||||
if (
|
if (
|
||||||
!this.validateQualificationMaterials(
|
!this.validateQualificationMaterials(
|
||||||
this.parseAttachments(archive.qualificationAttachments)
|
this.parseAttachments(archive.qualificationAttachments),
|
||||||
|
archive.customerType
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
@@ -4100,11 +4176,13 @@ export default {
|
|||||||
)}分`
|
)}分`
|
||||||
);
|
);
|
||||||
this.calculateScore(this.currentScore);
|
this.calculateScore(this.currentScore);
|
||||||
|
if (prop === 'reviewScore') this.logReviewScoreSummary();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
detail[prop] = normalized;
|
detail[prop] = normalized;
|
||||||
this.calculateScore(this.currentScore);
|
this.calculateScore(this.currentScore);
|
||||||
|
if (prop === 'reviewScore') this.logReviewScoreSummary();
|
||||||
},
|
},
|
||||||
handleScoreDecimalInput(prop, value) {
|
handleScoreDecimalInput(prop, value) {
|
||||||
const normalized = String(value || '')
|
const normalized = String(value || '')
|
||||||
@@ -4157,6 +4235,15 @@ export default {
|
|||||||
return sum + this.getScoreItemFullScore(item);
|
return sum + this.getScoreItemFullScore(item);
|
||||||
}, 0);
|
}, 0);
|
||||||
},
|
},
|
||||||
|
logReviewScoreSummary() {
|
||||||
|
const details = this.currentScore.details || [];
|
||||||
|
console.log('[评分详情] 复评评分结果', {
|
||||||
|
复评总分: this.currentScore.reviewScore,
|
||||||
|
总分: this.getScoreFullMark(details),
|
||||||
|
得分率: `${this.currentScore.scoreRate}%`,
|
||||||
|
匹配到的信用等级: this.currentScore.creditLevel || '',
|
||||||
|
});
|
||||||
|
},
|
||||||
matchCreditStandard(score, scoreRate) {
|
matchCreditStandard(score, scoreRate) {
|
||||||
const standards = (score.standards || [])
|
const standards = (score.standards || [])
|
||||||
.filter(item => item && item.creditLevel)
|
.filter(item => item && item.creditLevel)
|
||||||
|
|||||||
@@ -51,15 +51,33 @@
|
|||||||
row.vehicleNo
|
row.vehicleNo
|
||||||
}}</el-link>
|
}}</el-link>
|
||||||
</template>
|
</template>
|
||||||
|
<template #vehicleTypeForm>
|
||||||
|
<span v-if="boxType === 'view'">{{ form.vehicleType || '' }}</span>
|
||||||
|
<el-radio-group v-else v-model="form.vehicleType" @change="handleVehicleTypeChange">
|
||||||
|
<el-radio value="车辆">车辆</el-radio>
|
||||||
|
<el-radio value="船舶">船舶</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</template>
|
||||||
<template #vehicleNoForm>
|
<template #vehicleNoForm>
|
||||||
<el-autocomplete
|
<el-select
|
||||||
v-model="form.vehicleNo"
|
v-model="form.vehicleNo"
|
||||||
:disabled="boxType === 'view'"
|
:disabled="boxType === 'view'"
|
||||||
:fetch-suggestions="fetchVehicleOptions"
|
:loading="vehicleOptionsLoading"
|
||||||
:placeholder="vehicleNoPlaceholder"
|
:placeholder="vehicleNoPlaceholder"
|
||||||
clearable
|
clearable
|
||||||
value-key="value"
|
filterable
|
||||||
/>
|
remote
|
||||||
|
:remote-method="loadVehicleOptions"
|
||||||
|
class="equipment-ledger-page__vehicle-select"
|
||||||
|
@visible-change="handleVehicleSelectVisible"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in vehicleOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
<template #equipmentCodeForm>
|
<template #equipmentCodeForm>
|
||||||
<el-input v-model="form.equipmentCode" disabled />
|
<el-input v-model="form.equipmentCode" disabled />
|
||||||
@@ -68,10 +86,10 @@
|
|||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #attachmentsForm>
|
<template #attachmentsForm>
|
||||||
<vehicle-attachment-upload v-model="form.attachments" :readonly="boxType === 'view'" />
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
</template>
|
</template>
|
||||||
<template #attachments-form>
|
<template #attachments-form>
|
||||||
<vehicle-attachment-upload v-model="form.attachments" :readonly="boxType === 'view'" />
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
<empty-pagination
|
<empty-pagination
|
||||||
@@ -107,12 +125,16 @@ import { getDictionary } from '@/api/system/dictbiz';
|
|||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/equipment-ledger';
|
import { excelOption, option } from '@/option/vehicle/equipment-ledger';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
VehicleAttachmentTable,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {},
|
form: {},
|
||||||
@@ -121,6 +143,9 @@ export default {
|
|||||||
excelBox: false,
|
excelBox: false,
|
||||||
excelForm: {},
|
excelForm: {},
|
||||||
boxType: '',
|
boxType: '',
|
||||||
|
vehicleOptions: [],
|
||||||
|
vehicleOptionsLoading: false,
|
||||||
|
vehicleOptionsRequestId: 0,
|
||||||
option,
|
option,
|
||||||
excelOption,
|
excelOption,
|
||||||
data: [],
|
data: [],
|
||||||
@@ -171,19 +196,34 @@ export default {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
fetchVehicleOptions(queryString, callback) {
|
handleVehicleTypeChange() {
|
||||||
|
this.form.vehicleNo = '';
|
||||||
|
this.vehicleOptions = [];
|
||||||
|
this.loadVehicleOptions('');
|
||||||
|
},
|
||||||
|
handleVehicleSelectVisible(visible) {
|
||||||
|
if (visible && !this.vehicleOptions.length) this.loadVehicleOptions('');
|
||||||
|
},
|
||||||
|
loadVehicleOptions(queryString = '') {
|
||||||
const isShip = this.form.vehicleType === '船舶';
|
const isShip = this.form.vehicleType === '船舶';
|
||||||
const request = isShip ? getShipList : getVehicleList;
|
const request = isShip ? getShipList : getVehicleList;
|
||||||
const params = isShip ? { shipIdentifierNo: queryString } : { plateNo: queryString };
|
const params = isShip ? { shipIdentifierNo: queryString } : { plateNo: queryString };
|
||||||
|
const requestId = ++this.vehicleOptionsRequestId;
|
||||||
|
this.vehicleOptionsLoading = true;
|
||||||
request(1, 20, params)
|
request(1, 20, params)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
callback(
|
if (requestId !== this.vehicleOptionsRequestId) return;
|
||||||
(res.data.data.records || []).map(item => ({
|
const values = (res.data.data.records || [])
|
||||||
value: isShip ? item.shipIdentifierNo || item.shipName : item.plateNo,
|
.map(item => (isShip ? item.shipIdentifierNo : item.plateNo))
|
||||||
}))
|
.filter(Boolean);
|
||||||
);
|
this.vehicleOptions = [...new Set(values)].map(value => ({ label: value, value }));
|
||||||
})
|
})
|
||||||
.catch(() => callback([]));
|
.catch(() => {
|
||||||
|
if (requestId === this.vehicleOptionsRequestId) this.vehicleOptions = [];
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
if (requestId === this.vehicleOptionsRequestId) this.vehicleOptionsLoading = false;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
formatAttachments(value) {
|
formatAttachments(value) {
|
||||||
if (!value) return '';
|
if (!value) return '';
|
||||||
@@ -254,6 +294,8 @@ export default {
|
|||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
getNextEquipmentCode().then(res => {
|
getNextEquipmentCode().then(res => {
|
||||||
this.form = { vehicleType: '车辆', equipmentCode: res.data.data };
|
this.form = { vehicleType: '车辆', equipmentCode: res.data.data };
|
||||||
|
this.vehicleOptions = [];
|
||||||
|
this.loadVehicleOptions('');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@@ -264,6 +306,8 @@ export default {
|
|||||||
...res.data.data,
|
...res.data.data,
|
||||||
attachments: this.parseAttachments(res.data.data.attachments),
|
attachments: this.parseAttachments(res.data.data.attachments),
|
||||||
};
|
};
|
||||||
|
this.vehicleOptions = [];
|
||||||
|
this.loadVehicleOptions(this.form.vehicleNo || '');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@@ -335,6 +379,10 @@ export default {
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.equipment-ledger-page {
|
.equipment-ledger-page {
|
||||||
|
&__vehicle-select {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.el-table th .cell),
|
:deep(.el-table th .cell),
|
||||||
:deep(.el-table td .cell) {
|
:deep(.el-table td .cell) {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|||||||
@@ -85,10 +85,10 @@
|
|||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #attachmentsForm>
|
<template #attachmentsForm>
|
||||||
<vehicle-attachment-upload v-model="form.attachments" :readonly="boxType === 'view'" />
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
</template>
|
</template>
|
||||||
<template #attachments-form>
|
<template #attachments-form>
|
||||||
<vehicle-attachment-upload v-model="form.attachments" :readonly="boxType === 'view'" />
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
<el-dialog title="ETC记录数据导入" append-to-body v-model="excelBox" width="555px">
|
<el-dialog title="ETC记录数据导入" append-to-body v-model="excelBox" width="555px">
|
||||||
@@ -111,12 +111,16 @@ import { exportBlob } from '@/api/common';
|
|||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/etc-record';
|
import { excelOption, option } from '@/option/vehicle/etc-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
VehicleAttachmentTable,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {},
|
form: {},
|
||||||
|
|||||||
@@ -59,6 +59,13 @@
|
|||||||
{{ row.vehicleNo }}
|
{{ row.vehicleNo }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
<template #vehicleTypeForm>
|
||||||
|
<span v-if="boxType === 'view'">{{ form.vehicleType || '' }}</span>
|
||||||
|
<el-radio-group v-else v-model="form.vehicleType" @change="handleVehicleTypeChange">
|
||||||
|
<el-radio value="车辆">车辆</el-radio>
|
||||||
|
<el-radio value="船舶">船舶</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</template>
|
||||||
<template #vehicleNoForm>
|
<template #vehicleNoForm>
|
||||||
<el-autocomplete
|
<el-autocomplete
|
||||||
v-model="form.vehicleNo"
|
v-model="form.vehicleNo"
|
||||||
@@ -102,7 +109,11 @@
|
|||||||
</el-input>
|
</el-input>
|
||||||
</template>
|
</template>
|
||||||
<template #nextMaintenanceMileageForm>
|
<template #nextMaintenanceMileageForm>
|
||||||
|
<span
|
||||||
|
v-if="boxType === 'view' && isUnsetNextMaintenanceMileage(form.nextMaintenanceMileage)"
|
||||||
|
></span>
|
||||||
<el-input
|
<el-input
|
||||||
|
v-else
|
||||||
v-model="form.nextMaintenanceMileage"
|
v-model="form.nextMaintenanceMileage"
|
||||||
:disabled="boxType === 'view'"
|
:disabled="boxType === 'view'"
|
||||||
inputmode="decimal"
|
inputmode="decimal"
|
||||||
@@ -116,28 +127,16 @@
|
|||||||
<span>{{ formatMileage(row.mileage, row.mileageUnit) }}</span>
|
<span>{{ formatMileage(row.mileage, row.mileageUnit) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #nextMaintenanceMileage="{ row }">
|
<template #nextMaintenanceMileage="{ row }">
|
||||||
<span>{{ formatMileage(row.nextMaintenanceMileage, row.mileageUnit) }}</span>
|
<span>{{ formatNextMaintenanceMileage(row.nextMaintenanceMileage, row.mileageUnit) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #attachments="{ row }">
|
<template #attachments="{ row }">
|
||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #attachmentsForm>
|
<template #attachmentsForm>
|
||||||
<vehicle-attachment-upload
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
v-model="form.attachments"
|
|
||||||
:readonly="boxType === 'view'"
|
|
||||||
button-text="新增"
|
|
||||||
button-icon="el-icon-plus"
|
|
||||||
:show-tip="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<template #attachments-form>
|
<template #attachments-form>
|
||||||
<vehicle-attachment-upload
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
v-model="form.attachments"
|
|
||||||
:readonly="boxType === 'view'"
|
|
||||||
button-text="新增"
|
|
||||||
button-icon="el-icon-plus"
|
|
||||||
:show-tip="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
<el-dialog title="保养记录数据导入" append-to-body v-model="excelBox" width="555px">
|
<el-dialog title="保养记录数据导入" append-to-body v-model="excelBox" width="555px">
|
||||||
@@ -169,6 +168,7 @@ import { formatUpdateUserName } from '@/utils/audit';
|
|||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
||||||
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
@@ -180,6 +180,7 @@ const createTimeRangeMap = {
|
|||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
AddressMapPicker,
|
AddressMapPicker,
|
||||||
|
VehicleAttachmentTable,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const validateNonNegative = (rule, value, callback) => {
|
const validateNonNegative = (rule, value, callback) => {
|
||||||
@@ -237,6 +238,7 @@ export default {
|
|||||||
{ label: '车辆', value: '车辆' },
|
{ label: '车辆', value: '车辆' },
|
||||||
{ label: '船舶', value: '船舶' },
|
{ label: '船舶', value: '船舶' },
|
||||||
],
|
],
|
||||||
|
formslot: true,
|
||||||
value: '车辆',
|
value: '车辆',
|
||||||
search: true,
|
search: true,
|
||||||
span: 24,
|
span: 24,
|
||||||
@@ -377,6 +379,7 @@ export default {
|
|||||||
{
|
{
|
||||||
label: '附件',
|
label: '附件',
|
||||||
prop: 'attachments',
|
prop: 'attachments',
|
||||||
|
hide: true,
|
||||||
span: 24,
|
span: 24,
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
slot: true,
|
slot: true,
|
||||||
@@ -555,6 +558,13 @@ export default {
|
|||||||
if (value === undefined || value === null || value === '') return '';
|
if (value === undefined || value === null || value === '') return '';
|
||||||
return `${Math.max(Number(value), 0)} ${unit || '公里'}`;
|
return `${Math.max(Number(value), 0)} ${unit || '公里'}`;
|
||||||
},
|
},
|
||||||
|
isUnsetNextMaintenanceMileage(value) {
|
||||||
|
return Number(value) === -1;
|
||||||
|
},
|
||||||
|
formatNextMaintenanceMileage(value, unit) {
|
||||||
|
if (this.isUnsetNextMaintenanceMileage(value)) return '';
|
||||||
|
return this.formatMileage(value, unit);
|
||||||
|
},
|
||||||
formatAttachments(value) {
|
formatAttachments(value) {
|
||||||
if (!value) return '';
|
if (!value) return '';
|
||||||
if (Array.isArray(value)) return `${value.length} 个`;
|
if (Array.isArray(value)) return `${value.length} 个`;
|
||||||
|
|||||||
@@ -106,22 +106,10 @@
|
|||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #attachmentsForm>
|
<template #attachmentsForm>
|
||||||
<vehicle-attachment-upload
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
v-model="form.attachments"
|
|
||||||
:readonly="boxType === 'view'"
|
|
||||||
button-text="新增"
|
|
||||||
button-icon="el-icon-plus"
|
|
||||||
:show-tip="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<template #attachments-form>
|
<template #attachments-form>
|
||||||
<vehicle-attachment-upload
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
v-model="form.attachments"
|
|
||||||
:readonly="boxType === 'view'"
|
|
||||||
button-text="新增"
|
|
||||||
button-icon="el-icon-plus"
|
|
||||||
:show-tip="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
<el-dialog title="维修记录数据导入" append-to-body v-model="excelBox" width="555px">
|
<el-dialog title="维修记录数据导入" append-to-body v-model="excelBox" width="555px">
|
||||||
@@ -153,6 +141,7 @@ import { formatUpdateUserName } from '@/utils/audit';
|
|||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
||||||
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
@@ -164,6 +153,7 @@ const createTimeRangeMap = {
|
|||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
AddressMapPicker,
|
AddressMapPicker,
|
||||||
|
VehicleAttachmentTable,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const validateNonNegative = (rule, value, callback) => {
|
const validateNonNegative = (rule, value, callback) => {
|
||||||
@@ -362,6 +352,7 @@ export default {
|
|||||||
{
|
{
|
||||||
label: '附件',
|
label: '附件',
|
||||||
prop: 'attachments',
|
prop: 'attachments',
|
||||||
|
hide: true,
|
||||||
span: 24,
|
span: 24,
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
slot: true,
|
slot: true,
|
||||||
@@ -542,9 +533,14 @@ export default {
|
|||||||
.catch(() => callback([]));
|
.catch(() => callback([]));
|
||||||
},
|
},
|
||||||
formatMileage(value, unit) {
|
formatMileage(value, unit) {
|
||||||
if (value === undefined || value === null || value === '') return '';
|
if (this.normalizeMileageValue(value) === null) return '';
|
||||||
return `${Math.max(Number(value), 0)} ${unit || '公里'}`;
|
return `${Math.max(Number(value), 0)} ${unit || '公里'}`;
|
||||||
},
|
},
|
||||||
|
normalizeMileageValue(value) {
|
||||||
|
if (value === undefined || value === null || value === '' || Number(value) === -1)
|
||||||
|
return null;
|
||||||
|
return value;
|
||||||
|
},
|
||||||
formatAttachments(value) {
|
formatAttachments(value) {
|
||||||
if (!value) return '';
|
if (!value) return '';
|
||||||
if (Array.isArray(value)) return `${value.length} 个`;
|
if (Array.isArray(value)) return `${value.length} 个`;
|
||||||
@@ -595,6 +591,7 @@ export default {
|
|||||||
const values = { ...row };
|
const values = { ...row };
|
||||||
values.vehicleType = values.vehicleType || '车辆';
|
values.vehicleType = values.vehicleType || '车辆';
|
||||||
values.mileageUnit = values.vehicleType === '船舶' ? '海里' : '公里';
|
values.mileageUnit = values.vehicleType === '船舶' ? '海里' : '公里';
|
||||||
|
values.mileage = this.normalizeMileageValue(values.mileage);
|
||||||
if (values.vehicleNo) {
|
if (values.vehicleNo) {
|
||||||
values.vehicleNo =
|
values.vehicleNo =
|
||||||
values.vehicleType === '船舶'
|
values.vehicleType === '船舶'
|
||||||
@@ -676,6 +673,7 @@ export default {
|
|||||||
detail.attachments = this.parseAttachments(detail.attachments);
|
detail.attachments = this.parseAttachments(detail.attachments);
|
||||||
detail.vehicleType = detail.vehicleType || '车辆';
|
detail.vehicleType = detail.vehicleType || '车辆';
|
||||||
detail.mileageUnit = detail.vehicleType === '船舶' ? '海里' : '公里';
|
detail.mileageUnit = detail.vehicleType === '船舶' ? '海里' : '公里';
|
||||||
|
detail.mileage = this.normalizeMileageValue(detail.mileage);
|
||||||
this.form = detail;
|
this.form = detail;
|
||||||
this.updateVehicleType(detail.vehicleType);
|
this.updateVehicleType(detail.vehicleType);
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -60,16 +60,16 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<template #previousMonthMileage="{ row }">
|
<template #previousMonthMileage="{ row }">
|
||||||
<span>{{ formatMileage(row.previousMonthMileage, row.mileageUnit) }}</span>
|
<span>{{ formatMileage(row.previousMonthMileage) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #currentMonthMileage="{ row }">
|
<template #currentMonthMileage="{ row }">
|
||||||
<span>{{ formatMileage(row.currentMonthMileage, row.mileageUnit) }}</span>
|
<span>{{ formatMileage(row.currentMonthMileage) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #monthlyMileage="{ row }">
|
<template #monthlyMileage="{ row }">
|
||||||
<span>{{ formatMileage(row.monthlyMileage, row.mileageUnit) }}</span>
|
<span>{{ formatMileage(row.monthlyMileage) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #totalMileage="{ row }">
|
<template #totalMileage="{ row }">
|
||||||
<span>{{ formatMileage(row.totalMileage, row.mileageUnit) }}</span>
|
<span>{{ formatMileage(row.totalMileage) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #vehicleNoForm>
|
<template #vehicleNoForm>
|
||||||
<el-autocomplete
|
<el-autocomplete
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
:fetch-suggestions="fetchVehicleOptions"
|
:fetch-suggestions="fetchVehicleOptions"
|
||||||
:disabled="Boolean(form.id)"
|
:disabled="Boolean(form.id)"
|
||||||
clearable
|
clearable
|
||||||
:placeholder="vehicleNoPlaceholder"
|
placeholder="输入车牌号模糊查询选择"
|
||||||
value-key="value"
|
value-key="value"
|
||||||
class="mileage-record-page__input"
|
class="mileage-record-page__input"
|
||||||
/>
|
/>
|
||||||
@@ -149,10 +149,10 @@
|
|||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #attachmentsForm>
|
<template #attachmentsForm>
|
||||||
<vehicle-attachment-upload v-model="form.attachments" :readonly="boxType === 'view'" />
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
</template>
|
</template>
|
||||||
<template #attachments-form>
|
<template #attachments-form>
|
||||||
<vehicle-attachment-upload v-model="form.attachments" :readonly="boxType === 'view'" />
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
<empty-pagination
|
<empty-pagination
|
||||||
@@ -176,13 +176,13 @@
|
|||||||
<script>
|
<script>
|
||||||
import { add, getDetail, getList, remove, update } from '@/api/vehicle/mileage-record';
|
import { add, getDetail, getList, remove, update } from '@/api/vehicle/mileage-record';
|
||||||
import { getList as getVehicleList } from '@/api/transportCapacity/transport-vehicle';
|
import { getList as getVehicleList } from '@/api/transportCapacity/transport-vehicle';
|
||||||
import { getList as getShipList } from '@/api/transportCapacity/transport-ship';
|
|
||||||
import { getDeptTree } from '@/api/system/dept';
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
import { exportBlob } from '@/api/common';
|
import { exportBlob } from '@/api/common';
|
||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/mileage-record';
|
import { excelOption, option } from '@/option/vehicle/mileage-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
@@ -193,6 +193,9 @@ const createTimeRangeMap = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
VehicleAttachmentTable,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {},
|
form: {},
|
||||||
@@ -230,9 +233,6 @@ export default {
|
|||||||
editBtn: this.hasPermission('mileage_record_edit'),
|
editBtn: this.hasPermission('mileage_record_edit'),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
vehicleNoPlaceholder() {
|
|
||||||
return this.form.vehicleType === '船舶' ? '输入船号模糊查询选择' : '输入车牌号模糊查询选择';
|
|
||||||
},
|
|
||||||
ids() {
|
ids() {
|
||||||
const ids = [];
|
const ids = [];
|
||||||
this.selectionList.forEach(ele => {
|
this.selectionList.forEach(ele => {
|
||||||
@@ -241,42 +241,10 @@ export default {
|
|||||||
return ids.join(',');
|
return ids.join(',');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
'form.vehicleType': {
|
|
||||||
handler(value) {
|
|
||||||
this.updateVehicleTypeDisplays(value || '车辆');
|
|
||||||
},
|
|
||||||
immediate: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
hasPermission(code) {
|
hasPermission(code) {
|
||||||
return this.isAdmin || this.validData(this.permission[code], false);
|
return this.isAdmin || this.validData(this.permission[code], false);
|
||||||
},
|
},
|
||||||
updateVehicleTypeDisplays(vehicleType) {
|
|
||||||
const isShip = vehicleType === '船舶';
|
|
||||||
const unit = isShip ? '海里' : '公里';
|
|
||||||
const vehicleTypeColumn = this.findColumn(this.option.column, 'vehicleType');
|
|
||||||
const labelMap = {
|
|
||||||
previousMonthMileage: isShip ? '上月统计航程数' : '上月统计里程数',
|
|
||||||
currentMonthMileage: isShip ? '本月统计航程数' : '本月统计里程数',
|
|
||||||
monthlyMileage: isShip ? '本月航行航程数' : '本月行驶里程数',
|
|
||||||
totalMileage: isShip ? '累计航程数' : '累计行驶里程数',
|
|
||||||
totalMileageStart: isShip ? '累计航程' : '累计行驶里程',
|
|
||||||
totalMileageEnd: isShip ? '累计航程数结束值' : '累计行驶里程数结束值',
|
|
||||||
};
|
|
||||||
Object.keys(labelMap).forEach(prop => {
|
|
||||||
const column = this.findColumn(this.option.column, prop);
|
|
||||||
column.label = labelMap[prop];
|
|
||||||
});
|
|
||||||
vehicleTypeColumn.disabled = Boolean(this.form.id);
|
|
||||||
const unitColumn = this.findColumn(this.option.column, 'mileageUnit');
|
|
||||||
unitColumn.value = unit;
|
|
||||||
this.form.mileageUnit = unit;
|
|
||||||
if (!this.form.id && this.form.vehicleNo) {
|
|
||||||
this.form.vehicleNo = '';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
initDeptTree() {
|
initDeptTree() {
|
||||||
getDeptTree(this.userInfo.tenantId).then(res => {
|
getDeptTree(this.userInfo.tenantId).then(res => {
|
||||||
const column = this.findColumn(this.option.column, 'createDept');
|
const column = this.findColumn(this.option.column, 'createDept');
|
||||||
@@ -284,26 +252,18 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
fetchVehicleOptions(queryString, callback) {
|
fetchVehicleOptions(queryString, callback) {
|
||||||
const vehicleType = this.form.vehicleType || '车辆';
|
getVehicleList(1, 20, { plateNo: queryString })
|
||||||
const request = vehicleType === '船舶' ? getShipList : getVehicleList;
|
|
||||||
const params =
|
|
||||||
vehicleType === '船舶' ? { shipIdentifierNo: queryString } : { plateNo: queryString };
|
|
||||||
request(1, 20, params)
|
|
||||||
.then(res => {
|
.then(res => {
|
||||||
const records = res.data.data.records || [];
|
const records = res.data.data.records || [];
|
||||||
callback(
|
callback(records.map(item => ({ value: item.plateNo })));
|
||||||
records.map(item => ({
|
|
||||||
value: vehicleType === '船舶' ? item.shipIdentifierNo || item.shipName : item.plateNo,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
.catch(() => callback([]));
|
.catch(() => callback([]));
|
||||||
},
|
},
|
||||||
formatMileage(value, unit) {
|
formatMileage(value) {
|
||||||
if (this.isEmpty(value)) {
|
if (this.isEmpty(value)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
return `${value} ${unit || '公里'}`;
|
return `${value} 公里`;
|
||||||
},
|
},
|
||||||
formatAttachments(value) {
|
formatAttachments(value) {
|
||||||
if (!value) return '';
|
if (!value) return '';
|
||||||
@@ -352,13 +312,10 @@ export default {
|
|||||||
},
|
},
|
||||||
normalizeRow(row) {
|
normalizeRow(row) {
|
||||||
const values = { ...row };
|
const values = { ...row };
|
||||||
values.vehicleType = values.vehicleType || '车辆';
|
values.vehicleType = '车辆';
|
||||||
values.mileageUnit = values.vehicleType === '船舶' ? '海里' : '公里';
|
values.mileageUnit = '公里';
|
||||||
if (values.vehicleNo) {
|
if (values.vehicleNo) {
|
||||||
values.vehicleNo =
|
values.vehicleNo = values.vehicleNo.trim().toUpperCase();
|
||||||
values.vehicleType === '船舶'
|
|
||||||
? values.vehicleNo.trim()
|
|
||||||
: values.vehicleNo.trim().toUpperCase();
|
|
||||||
}
|
}
|
||||||
const previousMonthMileage = this.toNumber(values.previousMonthMileage);
|
const previousMonthMileage = this.toNumber(values.previousMonthMileage);
|
||||||
const currentMonthMileage = this.toNumber(values.currentMonthMileage);
|
const currentMonthMileage = this.toNumber(values.currentMonthMileage);
|
||||||
@@ -387,12 +344,11 @@ export default {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
validateRow(row) {
|
validateRow(row) {
|
||||||
const isShip = row.vehicleType === '船舶';
|
|
||||||
const mileageFields = [
|
const mileageFields = [
|
||||||
['previousMonthMileage', isShip ? '上月统计航程数' : '上月统计里程数'],
|
['previousMonthMileage', '上月统计里程数'],
|
||||||
['currentMonthMileage', isShip ? '本月统计航程数' : '本月统计里程数'],
|
['currentMonthMileage', '本月统计里程数'],
|
||||||
['monthlyMileage', isShip ? '本月航行航程数' : '本月行驶里程数'],
|
['monthlyMileage', '本月行驶里程数'],
|
||||||
['totalMileage', isShip ? '累计航程数' : '累计行驶里程数'],
|
['totalMileage', '累计行驶里程数'],
|
||||||
];
|
];
|
||||||
if (!mileageFields.every(([prop, label]) => this.validateMileage(row[prop], label))) {
|
if (!mileageFields.every(([prop, label]) => this.validateMileage(row[prop], label))) {
|
||||||
return false;
|
return false;
|
||||||
@@ -407,11 +363,7 @@ export default {
|
|||||||
monthlyMileage !== null &&
|
monthlyMileage !== null &&
|
||||||
this.toMoney(currentMonthMileage - previousMonthMileage) !== this.toMoney(monthlyMileage)
|
this.toMoney(currentMonthMileage - previousMonthMileage) !== this.toMoney(monthlyMileage)
|
||||||
) {
|
) {
|
||||||
this.$message.warning(
|
this.$message.warning('本月行驶里程数应等于本月统计里程数减去上月统计里程数');
|
||||||
isShip
|
|
||||||
? '本月航行航程数应等于本月统计航程数减去上月统计航程数'
|
|
||||||
: '本月行驶里程数应等于本月统计里程数减去上月统计里程数'
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
@@ -419,9 +371,7 @@ export default {
|
|||||||
currentMonthMileage !== null &&
|
currentMonthMileage !== null &&
|
||||||
totalMileage < currentMonthMileage
|
totalMileage < currentMonthMileage
|
||||||
) {
|
) {
|
||||||
this.$message.warning(
|
this.$message.warning('累计行驶里程数应大于等于本月统计里程数');
|
||||||
isShip ? '累计航程数应大于等于本月统计航程数' : '累计行驶里程数应大于等于本月统计里程数'
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -498,16 +448,14 @@ export default {
|
|||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
this.form.vehicleType = '车辆';
|
this.form.vehicleType = '车辆';
|
||||||
this.form.mileageUnit = '公里';
|
this.form.mileageUnit = '公里';
|
||||||
this.updateVehicleTypeDisplays(this.form.vehicleType);
|
|
||||||
}
|
}
|
||||||
if (['edit', 'view'].includes(type)) {
|
if (['edit', 'view'].includes(type)) {
|
||||||
getDetail(this.form.id).then(res => {
|
getDetail(this.form.id).then(res => {
|
||||||
const detail = res.data.data;
|
const detail = res.data.data;
|
||||||
detail.attachments = this.parseAttachments(detail.attachments);
|
detail.attachments = this.parseAttachments(detail.attachments);
|
||||||
detail.vehicleType = detail.vehicleType || this.form.vehicleType || '车辆';
|
detail.vehicleType = '车辆';
|
||||||
detail.mileageUnit = detail.vehicleType === '船舶' ? '海里' : '公里';
|
detail.mileageUnit = '公里';
|
||||||
this.form = detail;
|
this.form = detail;
|
||||||
this.updateVehicleTypeDisplays(detail.vehicleType);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
done();
|
done();
|
||||||
@@ -587,7 +535,10 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
buildQuery(params = {}) {
|
buildQuery(params = {}) {
|
||||||
return normalizeSearchRangeParams({ ...params, ...this.query }, createTimeRangeMap);
|
return normalizeSearchRangeParams(
|
||||||
|
{ ...params, ...this.query, vehicleType: '车辆' },
|
||||||
|
createTimeRangeMap
|
||||||
|
);
|
||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
|
|||||||
@@ -116,10 +116,10 @@
|
|||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #attachmentsForm>
|
<template #attachmentsForm>
|
||||||
<vehicle-attachment-upload v-model="form.attachments" :readonly="boxType === 'view'" />
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
</template>
|
</template>
|
||||||
<template #attachments-form>
|
<template #attachments-form>
|
||||||
<vehicle-attachment-upload v-model="form.attachments" :readonly="boxType === 'view'" />
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
<el-dialog title="油电记录数据导入" append-to-body v-model="excelBox" width="555px">
|
<el-dialog title="油电记录数据导入" append-to-body v-model="excelBox" width="555px">
|
||||||
@@ -143,12 +143,16 @@ import { exportBlob } from '@/api/common';
|
|||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/oil-electric-record';
|
import { excelOption, option } from '@/option/vehicle/oil-electric-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
VehicleAttachmentTable,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {},
|
form: {},
|
||||||
|
|||||||
@@ -85,10 +85,10 @@
|
|||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #attachmentsForm>
|
<template #attachmentsForm>
|
||||||
<vehicle-attachment-upload v-model="form.attachments" :readonly="boxType === 'view'" />
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
</template>
|
</template>
|
||||||
<template #attachments-form>
|
<template #attachments-form>
|
||||||
<vehicle-attachment-upload v-model="form.attachments" :readonly="boxType === 'view'" />
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
<el-dialog title="其他费用记录数据导入" append-to-body v-model="excelBox" width="555px">
|
<el-dialog title="其他费用记录数据导入" append-to-body v-model="excelBox" width="555px">
|
||||||
@@ -112,12 +112,16 @@ import { exportBlob } from '@/api/common';
|
|||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/other-expense-record';
|
import { excelOption, option } from '@/option/vehicle/other-expense-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
VehicleAttachmentTable,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {},
|
form: {},
|
||||||
|
|||||||
@@ -94,22 +94,10 @@
|
|||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #attachmentsForm>
|
<template #attachmentsForm>
|
||||||
<vehicle-attachment-upload
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
v-model="form.attachments"
|
|
||||||
:readonly="boxType === 'view'"
|
|
||||||
button-text="新增"
|
|
||||||
button-icon="el-icon-plus"
|
|
||||||
:show-tip="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<template #attachments-form>
|
<template #attachments-form>
|
||||||
<vehicle-attachment-upload
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
v-model="form.attachments"
|
|
||||||
:readonly="boxType === 'view'"
|
|
||||||
button-text="新增"
|
|
||||||
button-icon="el-icon-plus"
|
|
||||||
:show-tip="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
<empty-pagination
|
<empty-pagination
|
||||||
@@ -139,6 +127,7 @@ import { downloadXls } from '@/utils/util';
|
|||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/tire-replacement-record';
|
import { excelOption, option } from '@/option/vehicle/tire-replacement-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
@@ -149,6 +138,9 @@ const createTimeRangeMap = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
VehicleAttachmentTable,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {},
|
form: {},
|
||||||
|
|||||||
@@ -74,10 +74,10 @@
|
|||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #attachmentsForm>
|
<template #attachmentsForm>
|
||||||
<vehicle-attachment-upload v-model="form.attachments" :readonly="boxType === 'view'" />
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
</template>
|
</template>
|
||||||
<template #attachments-form>
|
<template #attachments-form>
|
||||||
<vehicle-attachment-upload v-model="form.attachments" :readonly="boxType === 'view'" />
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
<el-dialog title="变更记录数据导入" append-to-body v-model="excelBox" width="555px">
|
<el-dialog title="变更记录数据导入" append-to-body v-model="excelBox" width="555px">
|
||||||
@@ -102,6 +102,7 @@ import { downloadXls } from '@/utils/util';
|
|||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/transport-change-record';
|
import { excelOption, option } from '@/option/vehicle/transport-change-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
@@ -112,6 +113,9 @@ const createTimeRangeMap = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
VehicleAttachmentTable,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {},
|
form: {},
|
||||||
|
|||||||
@@ -128,22 +128,10 @@
|
|||||||
<span>{{ formatAttachments(row.attachments) }}</span>
|
<span>{{ formatAttachments(row.attachments) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #attachmentsForm>
|
<template #attachmentsForm>
|
||||||
<vehicle-attachment-upload
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
v-model="form.attachments"
|
|
||||||
:readonly="boxType === 'view'"
|
|
||||||
button-text="新增"
|
|
||||||
button-icon="el-icon-plus"
|
|
||||||
:show-tip="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<template #attachments-form>
|
<template #attachments-form>
|
||||||
<vehicle-attachment-upload
|
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||||||
v-model="form.attachments"
|
|
||||||
:readonly="boxType === 'view'"
|
|
||||||
button-text="新增"
|
|
||||||
button-icon="el-icon-plus"
|
|
||||||
:show-tip="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
<empty-pagination
|
<empty-pagination
|
||||||
@@ -182,6 +170,7 @@ import { openImportDialog } from '@/utils/import-excel';
|
|||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
||||||
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, option } from '@/option/vehicle/violation-record';
|
import { excelOption, option } from '@/option/vehicle/violation-record';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
@@ -194,6 +183,7 @@ const createTimeRangeMap = {
|
|||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
AddressMapPicker,
|
AddressMapPicker,
|
||||||
|
VehicleAttachmentTable,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -519,6 +509,7 @@ export default {
|
|||||||
this.form = {
|
this.form = {
|
||||||
vehicleType: '车辆',
|
vehicleType: '车辆',
|
||||||
processStatus: '未处理',
|
processStatus: '未处理',
|
||||||
|
attachments: [],
|
||||||
};
|
};
|
||||||
this.updateVehicleTypeDisplays('车辆');
|
this.updateVehicleTypeDisplays('车辆');
|
||||||
this.updateProcessResultDisplay('未处理');
|
this.updateProcessResultDisplay('未处理');
|
||||||
|
|||||||
@@ -1,177 +1,177 @@
|
|||||||
<template>
|
<template>
|
||||||
<basic-container>
|
<basic-container>
|
||||||
<div class="wel">
|
<!-- <div class="wel">-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-platform-eleme"
|
<!-- icon="el-icon-platform-eleme"-->
|
||||||
text="开始菜单1"
|
<!-- text="开始菜单1"-->
|
||||||
time="1"
|
<!-- time="1"-->
|
||||||
background="/img/bg/bg3.jpg"
|
<!-- background="/img/bg/bg3.jpg"-->
|
||||||
color="#d56259"
|
<!-- color="#d56259"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-eleme"
|
<!-- icon="el-icon-eleme"-->
|
||||||
text="开始菜单2"
|
<!-- text="开始菜单2"-->
|
||||||
time="2"
|
<!-- time="2"-->
|
||||||
background="/img/bg/bg2.jpg"
|
<!-- background="/img/bg/bg2.jpg"-->
|
||||||
color="#419ce7"
|
<!-- color="#419ce7"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-delete-solid"
|
<!-- icon="el-icon-delete-solid"-->
|
||||||
text="开始菜单3"
|
<!-- text="开始菜单3"-->
|
||||||
time="3"
|
<!-- time="3"-->
|
||||||
color="#56b69b"
|
<!-- color="#56b69b"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-delete"
|
<!-- icon="el-icon-delete"-->
|
||||||
text="开始菜单4"
|
<!-- text="开始菜单4"-->
|
||||||
time="4"
|
<!-- time="4"-->
|
||||||
color="#d44858"
|
<!-- color="#d44858"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-s-tools"
|
<!-- icon="el-icon-s-tools"-->
|
||||||
text="开始菜单5"
|
<!-- text="开始菜单5"-->
|
||||||
time="5"
|
<!-- time="5"-->
|
||||||
color="#3a1f7e"
|
<!-- color="#3a1f7e"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="410"
|
<!-- :width="410"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-setting"
|
<!-- icon="el-icon-setting"-->
|
||||||
text="开始菜单6"
|
<!-- text="开始菜单6"-->
|
||||||
time="6"
|
<!-- time="6"-->
|
||||||
background="/img/bg/bg1.jpg"
|
<!-- background="/img/bg/bg1.jpg"-->
|
||||||
dept="这是一段很长的很长很长很长的描述这是一段很长的很长很长很长的描述"
|
<!-- dept="这是一段很长的很长很长很长的描述这是一段很长的很长很长很长的描述"-->
|
||||||
color="#422829"
|
<!-- color="#422829"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-user-solid"
|
<!-- icon="el-icon-user-solid"-->
|
||||||
text="开始菜单7"
|
<!-- text="开始菜单7"-->
|
||||||
time="7"
|
<!-- time="7"-->
|
||||||
color="#613cbd"
|
<!-- color="#613cbd"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-star-off"
|
<!-- icon="el-icon-star-off"-->
|
||||||
text="开始菜单8"
|
<!-- text="开始菜单8"-->
|
||||||
time="8"
|
<!-- time="8"-->
|
||||||
color="#da542e"
|
<!-- color="#da542e"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-goods"
|
<!-- icon="el-icon-goods"-->
|
||||||
text="开始菜单9"
|
<!-- text="开始菜单9"-->
|
||||||
time="9"
|
<!-- time="9"-->
|
||||||
color="#2e8aef"
|
<!-- color="#2e8aef"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-circle-check"
|
<!-- icon="el-icon-circle-check"-->
|
||||||
text="开始菜单10"
|
<!-- text="开始菜单10"-->
|
||||||
time="10"
|
<!-- time="10"-->
|
||||||
color="#3d17b8"
|
<!-- color="#3d17b8"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-s-platform"
|
<!-- icon="el-icon-s-platform"-->
|
||||||
text="开始菜单11"
|
<!-- text="开始菜单11"-->
|
||||||
time="11"
|
<!-- time="11"-->
|
||||||
color="#e31462"
|
<!-- color="#e31462"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-s-fold"
|
<!-- icon="el-icon-s-fold"-->
|
||||||
text="开始菜单12"
|
<!-- text="开始菜单12"-->
|
||||||
time="12"
|
<!-- time="12"-->
|
||||||
color="#d9532d"
|
<!-- color="#d9532d"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="410"
|
<!-- :width="410"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-s-open"
|
<!-- icon="el-icon-s-open"-->
|
||||||
text="开始菜单13"
|
<!-- text="开始菜单13"-->
|
||||||
time="13"
|
<!-- time="13"-->
|
||||||
dept="这是一段很长的很长很长很长的描述这是一段很长的很长很长很长的描述"
|
<!-- dept="这是一段很长的很长很长很长的描述这是一段很长的很长很长很长的描述"-->
|
||||||
color="#b72147"
|
<!-- color="#b72147"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-s-flag"
|
<!-- icon="el-icon-s-flag"-->
|
||||||
text="开始菜单14"
|
<!-- text="开始菜单14"-->
|
||||||
time="14"
|
<!-- time="14"-->
|
||||||
color="#01a100"
|
<!-- color="#01a100"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-s-data"
|
<!-- icon="el-icon-s-data"-->
|
||||||
text="开始菜单15"
|
<!-- text="开始菜单15"-->
|
||||||
time="15"
|
<!-- time="15"-->
|
||||||
color="#0c56bf"
|
<!-- color="#0c56bf"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-s-grid"
|
<!-- icon="el-icon-s-grid"-->
|
||||||
text="开始菜单16"
|
<!-- text="开始菜单16"-->
|
||||||
time="16"
|
<!-- time="16"-->
|
||||||
color="#0098a9"
|
<!-- color="#0098a9"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-s-release"
|
<!-- icon="el-icon-s-release"-->
|
||||||
text="开始菜单17"
|
<!-- text="开始菜单17"-->
|
||||||
time="17"
|
<!-- time="17"-->
|
||||||
background="/img/bg/bg2.jpg"
|
<!-- background="/img/bg/bg2.jpg"-->
|
||||||
color="#209bdf"
|
<!-- color="#209bdf"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="width"
|
<!-- :width="width"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-s-home"
|
<!-- icon="el-icon-s-home"-->
|
||||||
text="开始菜单18"
|
<!-- text="开始菜单18"-->
|
||||||
time="18"
|
<!-- time="18"-->
|
||||||
background="/img/bg/bg3.jpg"
|
<!-- background="/img/bg/bg3.jpg"-->
|
||||||
color="#603bbc"
|
<!-- color="#603bbc"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="515"
|
<!-- :width="515"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-s-promotion"
|
<!-- icon="el-icon-s-promotion"-->
|
||||||
text="开始菜单19"
|
<!-- text="开始菜单19"-->
|
||||||
time="19"
|
<!-- time="19"-->
|
||||||
dept="这是一段很长的很长很长很长的描述这是一段很长的很长很长很长的描述"
|
<!-- dept="这是一段很长的很长很长很长的描述这是一段很长的很长很长很长的描述"-->
|
||||||
color="#009bad"
|
<!-- color="#009bad"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
<basic-block
|
<!-- <basic-block-->
|
||||||
:width="515"
|
<!-- :width="515"-->
|
||||||
:height="height"
|
<!-- :height="height"-->
|
||||||
icon="el-icon-s-custom"
|
<!-- icon="el-icon-s-custom"-->
|
||||||
text="开始菜单20"
|
<!-- text="开始菜单20"-->
|
||||||
time="20"
|
<!-- time="20"-->
|
||||||
background="/img/bg/bg4.jpg"
|
<!-- background="/img/bg/bg4.jpg"-->
|
||||||
dept="这是一段很长的很长很长很长的描述这是一段很长的很长很长很长的描述"
|
<!-- dept="这是一段很长的很长很长很长的描述这是一段很长的很长很长很长的描述"-->
|
||||||
color="#d74e2a"
|
<!-- color="#d74e2a"-->
|
||||||
></basic-block>
|
<!-- ></basic-block>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</basic-container>
|
</basic-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,26 +1,27 @@
|
|||||||
import {
|
import { defineConfig, loadEnv } from 'vite';
|
||||||
defineConfig,
|
import { resolve } from 'path';
|
||||||
loadEnv
|
|
||||||
} from 'vite';
|
|
||||||
import { resolve } from 'path'
|
|
||||||
import createVitePlugins from './vite/plugins';
|
import createVitePlugins from './vite/plugins';
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default ({
|
export default ({ mode, command }) => {
|
||||||
mode,
|
const env = loadEnv(mode, process.cwd());
|
||||||
command
|
const { VITE_APP_ENV, VITE_APP_BASE } = env;
|
||||||
}) => {
|
|
||||||
const env = loadEnv(mode, process.cwd())
|
|
||||||
const {
|
|
||||||
VITE_APP_ENV,
|
|
||||||
VITE_APP_BASE
|
|
||||||
} = env
|
|
||||||
// 判断是打生产环境包
|
// 判断是打生产环境包
|
||||||
const isProd = VITE_APP_ENV === 'production'
|
const isProd = VITE_APP_ENV === 'production';
|
||||||
|
|
||||||
|
const assetFileNames = assetInfo => {
|
||||||
|
const fileName = assetInfo.names?.[0] || assetInfo.name || '';
|
||||||
|
return fileName.endsWith('.mjs') ? 'assets/[name]-[hash].js' : 'assets/[name]-[hash][extname]';
|
||||||
|
};
|
||||||
|
|
||||||
// 根据是否生产环境,动态设置压缩配置
|
// 根据是否生产环境,动态设置压缩配置
|
||||||
const buildConfig = {
|
const buildConfig = {
|
||||||
target: 'esnext',
|
target: 'esnext',
|
||||||
minify: isProd ? 'terser' : 'esbuild', // 根据环境选择压缩工具
|
minify: isProd ? 'terser' : 'esbuild', // 根据环境选择压缩工具
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
assetFileNames,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// 如果是生产环境,添加Terser的配置
|
// 如果是生产环境,添加Terser的配置
|
||||||
@@ -31,17 +32,13 @@ export default ({
|
|||||||
drop_debugger: true, // 删除 debugger
|
drop_debugger: true, // 删除 debugger
|
||||||
},
|
},
|
||||||
format: {
|
format: {
|
||||||
comments: false // 删除所有注释
|
comments: false, // 删除所有注释
|
||||||
}
|
},
|
||||||
|
};
|
||||||
|
buildConfig.rollupOptions.output.manualChunks = {
|
||||||
|
'element-plus': ['element-plus'],
|
||||||
|
'@smallwei/avue': ['@smallwei/avue'],
|
||||||
};
|
};
|
||||||
buildConfig.rollupOptions = {
|
|
||||||
output: {
|
|
||||||
manualChunks: {
|
|
||||||
'element-plus': ['element-plus'],
|
|
||||||
'@smallwei/avue': ['@smallwei/avue']
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return defineConfig({
|
return defineConfig({
|
||||||
base: VITE_APP_BASE,
|
base: VITE_APP_BASE,
|
||||||
@@ -50,26 +47,26 @@ export default ({
|
|||||||
__VUE_I18N_LEGACY_API__: true,
|
__VUE_I18N_LEGACY_API__: true,
|
||||||
__INTLIFY_PROD_DEVTOOLS__: false,
|
__INTLIFY_PROD_DEVTOOLS__: false,
|
||||||
},
|
},
|
||||||
// server: {
|
|
||||||
// port: 2888,
|
|
||||||
// proxy: {
|
|
||||||
// '/api': {
|
|
||||||
// target: 'http://localhost',
|
|
||||||
// //target: 'https://saber3.bladex.cn/api',
|
|
||||||
// changeOrigin: true,
|
|
||||||
// rewrite: path => path.replace(/^\/api/, ''),
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
server: {
|
server: {
|
||||||
port: 2889,
|
port: 2888,
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'http://172.16.203.228:8000',
|
target: 'http://localhost',
|
||||||
|
//target: 'https://saber3.bladex.cn/api',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
|
rewrite: path => path.replace(/^\/api/, ''),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// server: {
|
||||||
|
// port: 2889,
|
||||||
|
// proxy: {
|
||||||
|
// '/api': {
|
||||||
|
// target: 'http://172.16.203.228:8000',
|
||||||
|
// changeOrigin: true,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'~': resolve(__dirname, './'),
|
'~': resolve(__dirname, './'),
|
||||||
|
|||||||