73bfd6a8 by lihua

数字合约功能迁移

1 parent 9324c603
...@@ -100,6 +100,9 @@ VITE_APP_DATA_DELIVERY = https://daop-jgjf-test.zgsjzc.com/ ...@@ -100,6 +100,9 @@ VITE_APP_DATA_DELIVERY = https://daop-jgjf-test.zgsjzc.com/
100 #数据服务接口地址 100 #数据服务接口地址
101 VITE_APP_SERVICE_BASEURL = ms-daop-trust-api-service 101 VITE_APP_SERVICE_BASEURL = ms-daop-trust-api-service
102 102
103 #数字合约接口
104 VITE_APP_DIGITAL_CONTRACT_URL = ms-daop-trust-data-space-service
105
103 # 本地访问地址 106 # 本地访问地址
104 # VITE_API_CIRCULATION_URL = http://localhost:9000/circulation 107 # VITE_API_CIRCULATION_URL = http://localhost:9000/circulation
105 108
......
...@@ -86,6 +86,9 @@ VITE_APP_PERSONAL_URL = ms-daop-personel-service ...@@ -86,6 +86,9 @@ VITE_APP_PERSONAL_URL = ms-daop-personel-service
86 #数据服务接口地址 86 #数据服务接口地址
87 VITE_APP_SERVICE_BASEURL = ms-daop-trust-api-service 87 VITE_APP_SERVICE_BASEURL = ms-daop-trust-api-service
88 88
89 #数字合约接口
90 VITE_APP_DIGITAL_CONTRACT_URL = ms-daop-trust-data-space-service
91
89 #流通平台接口地址 92 #流通平台接口地址
90 VITE_APP_CIRCULATION = https://sz-lt.zgsjzc.com/ 93 VITE_APP_CIRCULATION = https://sz-lt.zgsjzc.com/
91 #数据加工交付 94 #数据加工交付
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
35 "file-saver": "^2.0.5", 35 "file-saver": "^2.0.5",
36 "hotkeys-js": "^3.10.2", 36 "hotkeys-js": "^3.10.2",
37 "html2canvas": "^1.4.1", 37 "html2canvas": "^1.4.1",
38 "html2pdf.js": "^0.12.1",
38 "insert-css": "^2.0.0", 39 "insert-css": "^2.0.0",
39 "jquery": "^3.7.1", 40 "jquery": "^3.7.1",
40 "jsencrypt": "^3.3.2", 41 "jsencrypt": "^3.3.2",
......
...@@ -65,6 +65,9 @@ dependencies: ...@@ -65,6 +65,9 @@ dependencies:
65 html2canvas: 65 html2canvas:
66 specifier: ^1.4.1 66 specifier: ^1.4.1
67 version: 1.4.1 67 version: 1.4.1
68 html2pdf.js:
69 specifier: ^0.12.1
70 version: 0.12.1
68 insert-css: 71 insert-css:
69 specifier: ^2.0.0 72 specifier: ^2.0.0
70 version: 2.0.0 73 version: 2.0.0
...@@ -966,6 +969,11 @@ packages: ...@@ -966,6 +969,11 @@ packages:
966 regenerator-runtime: 0.14.1 969 regenerator-runtime: 0.14.1
967 dev: false 970 dev: false
968 971
972 /@babel/runtime@7.28.4:
973 resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==}
974 engines: {node: '>=6.9.0'}
975 dev: false
976
969 /@babel/template@7.25.9: 977 /@babel/template@7.25.9:
970 resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} 978 resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==}
971 engines: {node: '>=6.9.0'} 979 engines: {node: '>=6.9.0'}
...@@ -1710,6 +1718,10 @@ packages: ...@@ -1710,6 +1718,10 @@ packages:
1710 resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==} 1718 resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==}
1711 dev: true 1719 dev: true
1712 1720
1721 /@types/pako@2.0.4:
1722 resolution: {integrity: sha512-VWDCbrLeVXJM9fihYodcLiIv0ku+AlOa/TQ1SvYOaBuyrSKgEcro95LJyIsJ4vSo6BXIxOKxiJAat04CmST9Fw==}
1723 dev: false
1724
1713 /@types/path-browserify@1.0.3: 1725 /@types/path-browserify@1.0.3:
1714 resolution: {integrity: sha512-ZmHivEbNCBtAfcrFeBCiTjdIc2dey0l7oCGNGpSuRTy8jP6UVND7oUowlvDujBy8r2Hoa8bfFUOCiPWfmtkfxw==} 1726 resolution: {integrity: sha512-ZmHivEbNCBtAfcrFeBCiTjdIc2dey0l7oCGNGpSuRTy8jP6UVND7oUowlvDujBy8r2Hoa8bfFUOCiPWfmtkfxw==}
1715 dev: true 1727 dev: true
...@@ -1718,6 +1730,12 @@ packages: ...@@ -1718,6 +1730,12 @@ packages:
1718 resolution: {integrity: sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==} 1730 resolution: {integrity: sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==}
1719 dev: true 1731 dev: true
1720 1732
1733 /@types/raf@3.4.3:
1734 resolution: {integrity: sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==}
1735 requiresBuild: true
1736 dev: false
1737 optional: true
1738
1721 /@types/semver@7.5.8: 1739 /@types/semver@7.5.8:
1722 resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} 1740 resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
1723 dev: true 1741 dev: true
...@@ -1734,6 +1752,12 @@ packages: ...@@ -1734,6 +1752,12 @@ packages:
1734 '@types/node': 22.9.3 1752 '@types/node': 22.9.3
1735 dev: true 1753 dev: true
1736 1754
1755 /@types/trusted-types@2.0.7:
1756 resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
1757 requiresBuild: true
1758 dev: false
1759 optional: true
1760
1737 /@types/unist@2.0.11: 1761 /@types/unist@2.0.11:
1738 resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} 1762 resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
1739 dev: true 1763 dev: true
...@@ -2988,6 +3012,22 @@ packages: ...@@ -2988,6 +3012,22 @@ packages:
2988 resolution: {integrity: sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==} 3012 resolution: {integrity: sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==}
2989 dev: true 3013 dev: true
2990 3014
3015 /canvg@3.0.11:
3016 resolution: {integrity: sha512-5ON+q7jCTgMp9cjpu4Jo6XbvfYwSB2Ow3kzHKfIyJfaCAOHLbdKPQqGKgfED/R5B+3TFFfe8pegYA+b423SRyA==}
3017 engines: {node: '>=10.0.0'}
3018 requiresBuild: true
3019 dependencies:
3020 '@babel/runtime': 7.28.4
3021 '@types/raf': 3.4.3
3022 core-js: 3.39.0
3023 raf: 3.4.1
3024 regenerator-runtime: 0.13.11
3025 rgbcolor: 1.0.1
3026 stackblur-canvas: 2.7.0
3027 svg-pathdata: 6.0.3
3028 dev: false
3029 optional: true
3030
2991 /capital-case@1.0.4: 3031 /capital-case@1.0.4:
2992 resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} 3032 resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==}
2993 dependencies: 3033 dependencies:
...@@ -3959,6 +3999,14 @@ packages: ...@@ -3959,6 +3999,14 @@ packages:
3959 resolution: {integrity: sha512-m4yreHcUWHBncGVV7U+yQzc12vIlq0jMrtHZ5mW6dQMiL/7skSYNVX9wqKwOtyO9SGCgevrAFEgOCAHmamHTUA==} 3999 resolution: {integrity: sha512-m4yreHcUWHBncGVV7U+yQzc12vIlq0jMrtHZ5mW6dQMiL/7skSYNVX9wqKwOtyO9SGCgevrAFEgOCAHmamHTUA==}
3960 dev: false 4000 dev: false
3961 4001
4002 /dompurify@3.3.0:
4003 resolution: {integrity: sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ==}
4004 requiresBuild: true
4005 optionalDependencies:
4006 '@types/trusted-types': 2.0.7
4007 dev: false
4008 optional: true
4009
3962 /domutils@1.7.0: 4010 /domutils@1.7.0:
3963 resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} 4011 resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==}
3964 dependencies: 4012 dependencies:
...@@ -5108,6 +5156,14 @@ packages: ...@@ -5108,6 +5156,14 @@ packages:
5108 resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} 5156 resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
5109 dev: true 5157 dev: true
5110 5158
5159 /fast-png@6.4.0:
5160 resolution: {integrity: sha512-kAqZq1TlgBjZcLr5mcN6NP5Rv4V2f22z00c3g8vRrwkcqjerx7BEhPbOnWCPqaHUl2XWQBJQvOT/FQhdMT7X/Q==}
5161 dependencies:
5162 '@types/pako': 2.0.4
5163 iobuffer: 5.4.0
5164 pako: 2.1.0
5165 dev: false
5166
5111 /fast-uri@3.0.3: 5167 /fast-uri@3.0.3:
5112 resolution: {integrity: sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==} 5168 resolution: {integrity: sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==}
5113 dev: true 5169 dev: true
...@@ -5131,6 +5187,10 @@ packages: ...@@ -5131,6 +5187,10 @@ packages:
5131 resolution: {integrity: sha512-Rr5QlUeGN1mbOHlaqcSYMKVpPbgLy0AWT/W0EHxA6NGI12yO1jpoui2zBBvU2G824ltM6Ut8BFgfHSBGfkmS0A==} 5187 resolution: {integrity: sha512-Rr5QlUeGN1mbOHlaqcSYMKVpPbgLy0AWT/W0EHxA6NGI12yO1jpoui2zBBvU2G824ltM6Ut8BFgfHSBGfkmS0A==}
5132 dev: false 5188 dev: false
5133 5189
5190 /fflate@0.8.2:
5191 resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==}
5192 dev: false
5193
5134 /figures@3.2.0: 5194 /figures@3.2.0:
5135 resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} 5195 resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==}
5136 engines: {node: '>=8'} 5196 engines: {node: '>=8'}
...@@ -5780,6 +5840,13 @@ packages: ...@@ -5780,6 +5840,13 @@ packages:
5780 text-segmentation: 1.0.3 5840 text-segmentation: 1.0.3
5781 dev: false 5841 dev: false
5782 5842
5843 /html2pdf.js@0.12.1:
5844 resolution: {integrity: sha512-3rBWQ96H5oOU9jtoz3MnE/epGi27ig9h8aonBk4JTpvUERM3lMRxhIRckhJZEi4wE0YfRINoYOIDY0hLY0CHgQ==}
5845 dependencies:
5846 html2canvas: 1.4.1
5847 jspdf: 3.0.4
5848 dev: false
5849
5783 /htmlparser2@3.10.1: 5850 /htmlparser2@3.10.1:
5784 resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==} 5851 resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==}
5785 dependencies: 5852 dependencies:
...@@ -5981,6 +6048,10 @@ packages: ...@@ -5981,6 +6048,10 @@ packages:
5981 engines: {node: '>= 0.10'} 6048 engines: {node: '>= 0.10'}
5982 dev: true 6049 dev: true
5983 6050
6051 /iobuffer@5.4.0:
6052 resolution: {integrity: sha512-DRebOWuqDvxunfkNJAlc3IzWIPD5xVxwUNbHr7xKB8E6aLJxIPfNX3CoMJghcFjpv6RWQsrcJbghtEwSPoJqMA==}
6053 dev: false
6054
5984 /iota-array@1.0.0: 6055 /iota-array@1.0.0:
5985 resolution: {integrity: sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==} 6056 resolution: {integrity: sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==}
5986 dev: true 6057 dev: true
...@@ -6512,6 +6583,19 @@ packages: ...@@ -6512,6 +6583,19 @@ packages:
6512 graceful-fs: 4.2.11 6583 graceful-fs: 4.2.11
6513 dev: true 6584 dev: true
6514 6585
6586 /jspdf@3.0.4:
6587 resolution: {integrity: sha512-dc6oQ8y37rRcHn316s4ngz/nOjayLF/FFxBF4V9zamQKRqXxyiH1zagkCdktdWhtoQId5K20xt1lB90XzkB+hQ==}
6588 dependencies:
6589 '@babel/runtime': 7.28.4
6590 fast-png: 6.4.0
6591 fflate: 0.8.2
6592 optionalDependencies:
6593 canvg: 3.0.11
6594 core-js: 3.39.0
6595 dompurify: 3.3.0
6596 html2canvas: 1.4.1
6597 dev: false
6598
6515 /jsprim@1.4.2: 6599 /jsprim@1.4.2:
6516 resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} 6600 resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==}
6517 engines: {node: '>=0.6.0'} 6601 engines: {node: '>=0.6.0'}
...@@ -7595,6 +7679,10 @@ packages: ...@@ -7595,6 +7679,10 @@ packages:
7595 engines: {node: '>=6'} 7679 engines: {node: '>=6'}
7596 dev: true 7680 dev: true
7597 7681
7682 /pako@2.1.0:
7683 resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==}
7684 dev: false
7685
7598 /param-case@3.0.4: 7686 /param-case@3.0.4:
7599 resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} 7687 resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
7600 dependencies: 7688 dependencies:
...@@ -7760,7 +7848,6 @@ packages: ...@@ -7760,7 +7848,6 @@ packages:
7760 7848
7761 /performance-now@2.1.0: 7849 /performance-now@2.1.0:
7762 resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} 7850 resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
7763 dev: true
7764 7851
7765 /picocolors@1.1.1: 7852 /picocolors@1.1.1:
7766 resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 7853 resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
...@@ -8087,6 +8174,14 @@ packages: ...@@ -8087,6 +8174,14 @@ packages:
8087 engines: {node: '>=10'} 8174 engines: {node: '>=10'}
8088 dev: true 8175 dev: true
8089 8176
8177 /raf@3.4.1:
8178 resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==}
8179 requiresBuild: true
8180 dependencies:
8181 performance-now: 2.1.0
8182 dev: false
8183 optional: true
8184
8090 /read-pkg-up@7.0.1: 8185 /read-pkg-up@7.0.1:
8091 resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} 8186 resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
8092 engines: {node: '>=8'} 8187 engines: {node: '>=8'}
...@@ -8224,6 +8319,12 @@ packages: ...@@ -8224,6 +8319,12 @@ packages:
8224 which-builtin-type: 1.2.0 8319 which-builtin-type: 1.2.0
8225 dev: true 8320 dev: true
8226 8321
8322 /regenerator-runtime@0.13.11:
8323 resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
8324 requiresBuild: true
8325 dev: false
8326 optional: true
8327
8227 /regenerator-runtime@0.14.1: 8328 /regenerator-runtime@0.14.1:
8228 resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} 8329 resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
8229 dev: false 8330 dev: false
...@@ -8388,6 +8489,13 @@ packages: ...@@ -8388,6 +8489,13 @@ packages:
8388 resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} 8489 resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
8389 dev: true 8490 dev: true
8390 8491
8492 /rgbcolor@1.0.1:
8493 resolution: {integrity: sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==}
8494 engines: {node: '>= 0.8.15'}
8495 requiresBuild: true
8496 dev: false
8497 optional: true
8498
8391 /rimraf@3.0.2: 8499 /rimraf@3.0.2:
8392 resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} 8500 resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
8393 deprecated: Rimraf versions prior to v4 are no longer supported 8501 deprecated: Rimraf versions prior to v4 are no longer supported
...@@ -8844,6 +8952,13 @@ packages: ...@@ -8844,6 +8952,13 @@ packages:
8844 deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' 8952 deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
8845 dev: true 8953 dev: true
8846 8954
8955 /stackblur-canvas@2.7.0:
8956 resolution: {integrity: sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ==}
8957 engines: {node: '>=0.1.14'}
8958 requiresBuild: true
8959 dev: false
8960 optional: true
8961
8847 /static-extend@0.1.2: 8962 /static-extend@0.1.2:
8848 resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} 8963 resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==}
8849 engines: {node: '>=0.10.0'} 8964 engines: {node: '>=0.10.0'}
...@@ -9271,6 +9386,13 @@ packages: ...@@ -9271,6 +9386,13 @@ packages:
9271 - supports-color 9386 - supports-color
9272 dev: true 9387 dev: true
9273 9388
9389 /svg-pathdata@6.0.3:
9390 resolution: {integrity: sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==}
9391 engines: {node: '>=12.0.0'}
9392 requiresBuild: true
9393 dev: false
9394 optional: true
9395
9274 /svg-tags@1.0.0: 9396 /svg-tags@1.0.0:
9275 resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} 9397 resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
9276 dev: true 9398 dev: true
......
1 import request from "@/utils/request";
2
3 /** 企业注册认证和连接器 */
4
5 /** 企业认证 **/
6 // 企业认证分页
7 export const getEnterpriseList = (params) => request({
8 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/page-list`,
9 method: 'post',
10 data: params
11 })
12
13 // 企业认证详情
14 export const getEnterpriseDetail = (params) => request({
15 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/detail`,
16 method: 'get',
17 params
18 })
19
20 // 企业认证新增
21 export const enterpriseSave = (params) => request({
22 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/save`,
23 method: 'post',
24 data: params
25 })
26
27 // 企业认证修改
28 export const enterpriseUpdate = (params) => request({
29 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/update`,
30 method: 'put',
31 data: params
32 })
33
34 // 企业认证删除
35 export const enterpriseDelete = (params) => request({
36 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/delete`,
37 method: 'delete',
38 data: params
39 })
40
41 // 企业认证变更删除
42 export const enterpriseChangeDelete = (params) => request({
43 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/change/delete`,
44 method: 'delete',
45 data: params
46 })
47
48 // 企业认证最后一级审批
49 export const enterpriseApprove = (params) => request({
50 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/last-approve`,
51 method: 'post',
52 data: params
53 })
54
55 // 企业认证进度列表
56 export const getTaskGressList = (params) => request({
57 url: `${import.meta.env.VITE_APP_PERSONAL_URL}/pending-task/page-list`,
58 method: 'post',
59 data: params
60 })
61
62 // 企业认证重新发起
63 export const getTaskRestart = (params) => request({
64 url: `${import.meta.env.VITE_APP_PERSONAL_URL}/pending-task/restart`,
65 method: 'get',
66 params
67 })
68
69 // 企业认证执行日志
70 export const getTaskExecutionLog = (params) => request({
71 url: `${import.meta.env.VITE_APP_PERSONAL_URL}/pending-task/task-info`,
72 method: 'get',
73 params
74 })
75
76 // 获取企业认证流程列表
77 export const getFlowEnterpriseList = (params) => request({
78 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/flow/page-list`,
79 method: 'post',
80 data: params
81 })
82
83 // 获取企业信息
84 export const getUserTenant = () => request({
85 // url: `http://localhost:9000/master/ms-daop-personel-service/tenant/get-current-user-tenant-from-cache`,
86 url: `https://sz-lt.zgsjzc.com/master/api/ms-daop-personel-service/tenant/get-current-user-tenant-from-cache`,
87 method: 'get'
88 })
89
90 // 获取企业信息
91 export const getEnterpriseData = (params) => request({
92 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/detail-by-logonUser`,
93 method: 'get',
94 params
95 })
96
97 // 修改需求上架状态
98 export const updateDemandGrounding = (params) => request({
99 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/demand/update-grounding-pick`,
100 method: 'post',
101 data: params
102 })
1 /** 数字合约管理 */
2
3 import request from "@/utils/request";
4
5 export const contractStatusList = [{
6 value: '01',
7 label: '发起'
8 }, {
9 value: '02',
10 label: '协商'
11 }, {
12 value: '03',
13 label: '签订'
14 }, {
15 value: '0302',
16 label: '签订失败'
17 }, {
18 value: '05',
19 label: '履行中'
20 }, {
21 value: '06',
22 label: '终止'
23 }, {
24 value: '00',
25 label: '已撤回'
26 }];
27
28 /** 获取策略模板的列表 */
29 export const getPageList = (params) => request({
30 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/policy-template/page-list`,
31 method: 'post',
32 data: params
33 })
34
35 /** 新增策略模板 */
36 export const savePolicyTemplate = (params) => request({
37 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/policy-template/save`,
38 method: 'post',
39 data: params
40 });
41
42 /** 修改策略模板 */
43 export const updatePolicyTemplate = (params) => request({
44 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/policy-template/update`,
45 method: 'put',
46 data: params
47 });
48
49 /** 删除策略模板 */
50 export const deletePolicyTemplate = (params) => request({
51 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/policy-template/delete`,
52 method: 'delete',
53 data: params
54 });
55
56 /** 更新策略模板状态 */
57 export const updateTemplateState = (params) => request({
58 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/policy-template/update-status`,
59 method: 'put',
60 params
61 });
62
63 /** --------------------------- 合约模板管理 -------------------------- */
64 /** 获取策略模板的列表 */
65 export const getContractTemplatePageList = (params) => request({
66 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/page-list`,
67 method: 'post',
68 data: params
69 })
70
71 /** 新增合约模板状态 */
72 export const saveContractTemplate = (params) => request({
73 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/save`,
74 method: 'post',
75 data: params
76 });
77
78 /** 更新合约模板状态 */
79 export const updateContractTemplate = (params) => request({
80 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/update`,
81 method: 'put',
82 data: params
83 });
84
85 /** 更新合约模板状态 */
86 export const updateContractTemplateState = (params) => request({
87 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/update-status`,
88 method: 'put',
89 params
90 });
91
92 /** 删除策略模板 */
93 export const deleteContractTemplate = (params) => request({
94 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/delete`,
95 method: 'delete',
96 data: params
97 });
98
99 /** 获取策略模板详情 */
100 export const getContractTemplateDetail = (params) => request({
101 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/detail`,
102 method: 'get',
103 params
104 });
105
106 /** 复制合约模板 */
107 export const copyContractTemplate = (params) => request({
108 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/copy`,
109 method: 'get',
110 params
111 });
112
113 /** 获取操作行为下拉列表 */
114 export const getActionPolicyList = () => request({
115 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/policy-template/list-by-policy-type?policyType=CZ`,
116 method: 'get'
117 });
118
119 /** 获取约束条件下拉列表 */
120 export const getConstraintPolicyList = () => request({
121 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/policy-template/list-by-policy-type?policyType=YS`,
122 method: 'get'
123 });
124
125 /** 根据状态获取可用的数字合约模板 */
126 export const getValidContractTemplateList = () => request({
127 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/list-by-biz-status`,
128 method: 'get'
129 });
130
131 /** --------------------- 合约管理 ----------------------- */
132 export const getContractPageList = (params) => request({
133 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/page-list`,
134 method: 'post',
135 data: params
136 })
137
138 /** 合约备案列表 */
139 export const getContractOverviewPageList = (params) => request({
140 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/overview-page-list`,
141 method: 'post',
142 data: params
143 })
144
145 /** 获取合约备案的发起主体下拉列表 */
146 export const getContractOverviewTenantList = () => request({
147 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/tenant-list`,
148 method: 'get',
149 });
150
151 /** 获取下拉数据产品列表 */
152 export const getContractDataProduct = () => request({
153 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/get-data-product`,
154 method: 'post'
155 })
156
157 /** 创建合约 */
158 export const saveContract = (params) => request({
159 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/save`,
160 method: 'post',
161 data: params
162 })
163
164 /** 更新合约 */
165 export const updateContract = (params) => request({
166 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/update`,
167 method: 'put',
168 data: params
169 })
170
171 export const deleteContract = (params) => request({
172 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/delete`,
173 method: 'delete',
174 data: params
175 });
176
177 export const getContractDetail = (guid) => request({
178 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/detail?guid=${guid}`,
179 method: 'get',
180 });
181
182 /** 查询协商信息详情 */
183 export const getContractNegotiate = (guid) => request({
184 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/get-negotiate?guid=${guid}`,
185 method: 'post',
186 });
187
188 /** 根据版本获取协商信息 */
189 export const getContractNegoPlicyByVersion = (params) => request({
190 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/get-policy-by-version?contractGuid=${params.guid}&version=${params.version}`,
191 method: 'get'
192 });
193
194 /** 拒绝本次合约 */
195 export const rejectContract = (guid) => request({
196 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/reject?guid=${guid}`,
197 method: 'post',
198 });
199
200 /** 确认本次合约 */
201 export const confirmContract = (guid) => request({
202 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/confirm?guid=${guid}`,
203 method: 'post',
204 });
205
206 /** 继续本地合约协商 */
207 export const continueContractNegotiate = (params) => request({
208 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/continue-negotiate`,
209 method: 'post',
210 data: params
211 });
212
213 /** 获取可选的企业下拉列表,认证过之后带标识的 */
214 export const getContractTenantList = () => request({
215 url: `${import.meta.env.VITE_APP_PERSONAL_URL}/tenant/get-social-credit-code-tenant`,
216 method: 'post'
217 })
218
219 /** 撤回合约 */
220 export const cancelContract = (guid) => request({
221 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/canal?guid=${guid}`,
222 method: 'post',
223 });
224
225 /** 签署合约 */
226 export const signContract = (params) => request({
227 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-signature/save`,
228 method: 'post',
229 data: params
230 });
231
232 /** 获取签署合约详情 */
233 export const getSignListInfo = (guid) => request({
234 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-signature/list-by-contract-guid?contractGuid=${guid}`,
235 method: 'post',
236 });
237
238 /** ----------------- 合约履约信息 ----------------- */
239 export const getContractProof = (guid) => request({
240 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/proof-execution/proof-by-contract-guid?contractGuid=${guid}`,
241 method: 'get'
242 });
243
244 /** 获取履约签名 */
245 export const getContractExecList = (params) => request({
246 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/proof-execution/execution-list-by-contract-guid`,
247 method: 'post',
248 data: params
249 });
250
251 /** 解除合同 */
252 export const terminateContract = (params) => request({
253 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-terminate/save`,
254 method: 'post',
255 data: params
256 });
257
258 /** 获取终止合约信息 */
259 export const getTerminateDetailInfo = (guid) => request({
260 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-terminate/detail?contractGuid=${guid}`,
261 method: 'get'
262 });
263
264 /** 日志管理-操作记录 */
265 export const getContractOperationLog = (params) => request({
266 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-operation-log/page-list`,
267 method: 'post',
268 data: params
269 })
270
271 /** 操作记录详情 */
272 export const getContractOperationLogDetail = (guid) => request({
273 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-operation-log/detail?guid=${guid}`,
274 method: 'get'
275 })
276
277 /** 日志管理-过程记录 */
278 export const getContractProcessLog = (params) => request({
279 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-process-log/page-list`,
280 method: 'post',
281 data: params
282 })
283
284 export const getContractProcessLogDetail = (guid) => request({
285 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-process-log/detail?guid=${guid}`,
286 method: 'get'
287 })
288
289 /** ------------ 合约统计记录 -------------- */
290
291 /** 获取备案统计 */
292 export const getContractStatis = () => request({
293 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/get-contract-statistics`,
294 method: 'get'
295 })
296
297 export const getContractMonthStatis = () => request({
298 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-signature/get-month-signature`,
299 method: 'get'
300 })
301
302 /** 获取合约履行异常预警记录 */
303 export const getLogTableList = (params) => request({
304 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-process-log/page-abnormal-warning`,
305 method: 'post',
306 data: params
307 })
308
309 /** 生成数字签名文件 */
310 export const getSignatureFile = (params, data) => request({
311 url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-signature/get-signature-base?pageIndex=${data.pageIndex}&yPosition=${data.yPosition}`,
312 method: 'post',
313 data: params,
314 headers: {
315 'Content-Type': 'multipart/form-data'
316 }
317 })
...@@ -364,3 +364,30 @@ a { ...@@ -364,3 +364,30 @@ a {
364 .mb10 { 364 .mb10 {
365 margin-bottom: 10px; 365 margin-bottom: 10px;
366 } 366 }
367
368 .el-tabs.log-tabs {
369 height: 100%;
370
371 .el-tabs__header {
372 margin-bottom: 0;
373 }
374
375 .el-tabs__item {
376 height: 32px;
377 padding: 0px;
378 width: 90px;
379
380 &:last-child {
381 width: 90px;
382 }
383 }
384
385 .el-tabs__content {
386 height: calc(100% - 32px);
387 }
388
389 .el-tab-pane {
390 padding: 0px 16px;
391 height: 100%;
392 }
393 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -24,8 +24,7 @@ const props = defineProps({ ...@@ -24,8 +24,7 @@ const props = defineProps({
24 24
25 const emits = defineEmits(["expand"]); 25 const emits = defineEmits(["expand"]);
26 26
27 // const isExpanded = ref(true); 27 const isExpanded = ref(true);
28 const isExpanded = ref(props.isExpand);
29 28
30 watch( 29 watch(
31 () => props.isExpand, 30 () => props.isExpand,
...@@ -47,10 +46,14 @@ const expandSwicthHandler = () => { ...@@ -47,10 +46,14 @@ const expandSwicthHandler = () => {
47 </script> 46 </script>
48 47
49 <template> 48 <template>
50 <ElCard class="v-content-wrap" shadow="never" :body-style="{ 49 <ElCard
50 class="v-content-wrap"
51 shadow="never"
52 :body-style="{
51 padding: `0px`, 53 padding: `0px`,
52 height: `${isExpanded ? contentHeight + 28 : 0}px`, 54 height: `${isExpanded ? contentHeight + 28 : 0}px`,
53 }"> 55 }"
56 >
54 <template v-if="title" #header> 57 <template v-if="title" #header>
55 <div class="card-title" @click="expandSwicthHandler"> 58 <div class="card-title" @click="expandSwicthHandler">
56 <span v-if="expandSwicth" style="padding-right: 5px; cursor: pointer"> 59 <span v-if="expandSwicth" style="padding-right: 5px; cursor: pointer">
...@@ -101,7 +104,6 @@ const expandSwicthHandler = () => { ...@@ -101,7 +104,6 @@ const expandSwicthHandler = () => {
101 color: var(--el-text-color-primary); 104 color: var(--el-text-color-primary);
102 line-height: 21px; 105 line-height: 21px;
103 font-weight: 600; 106 font-weight: 600;
104 flex-shrink: 0;
105 } 107 }
106 108
107 .desc { 109 .desc {
......
...@@ -9,6 +9,18 @@ export const useValidator = () => { ...@@ -9,6 +9,18 @@ export const useValidator = () => {
9 } 9 }
10 } 10 }
11 11
12 const requiredFiles = (message?: string) => {
13 return {
14 validator: (rule: any, value: any, callback: any) => {
15 if (!value?.length) {
16 callback(new Error('请上传文件'))
17 } else {
18 callback();
19 }
20 }, trigger: 'change'
21 }
22 }
23
12 // element scrollToError的优化 24 // element scrollToError的优化
13 const scrollToError = () => { 25 const scrollToError = () => {
14 nextTick(() => { 26 nextTick(() => {
...@@ -175,6 +187,111 @@ export const useValidator = () => { ...@@ -175,6 +187,111 @@ export const useValidator = () => {
175 trigger: "blur", 187 trigger: "blur",
176 }; 188 };
177 } 189 }
190 /** 验证输入的多个IP地址 */
191 const validateIPList = (): FormItemRule => {
192 return {
193 validator: (rule: any, value: any, callback: any) => {
194 let ips = value?.split(",");
195 if (!ips) {
196 callback(new Error(`请填写合法的IP地址`));
197 return;
198 }
199 for (const ipV of ips) {
200 let ip = ipV.trim();
201 if (!ip || (!ipRegex.v4().test(ip) && !ipRegex.v6().test(ip))) {
202 callback(new Error(`请填写合法的IP地址`));
203 return;
204 }
205 }
206 callback();
207 },
208 trigger: "blur",
209 };
210 };
211
212 /** 验证输入的多个域名 */
213 const validateDomainList = (): FormItemRule => {
214 return {
215 validator: (rule: any, value: any, callback: any) => {
216 let domains = value?.split(",");
217 if (!domains) {
218 callback(new Error(`请填写合法的IP地址`));
219 return;
220 }
221 // 简单的域名验证正则表达式
222 const domainRegex =
223 /^(?!-)(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.?)+[a-zA-Z]{2,}$/;
224
225 // 更严格的正则,符合RFC标准
226 const strictDomainRegex =
227 /^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\.)+[A-Za-z]{2,}$/;
228
229 // 国际化域名支持(Punycode编码)
230 const idnRegex =
231 /^(xn--[a-zA-Z0-9]+|(?!-)(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.?)+[a-zA-Z]{2,})$/;
232 for (const dv of domains) {
233 let domain = dv.trim();
234 if (!domain) {
235 callback(new Error("请填写合法的域名,不能包含连续的逗号"));
236 return;
237 }
238
239 // 检查长度限制
240 if (domain.length > 253) {
241 callback(new Error("单个域名长度不能超过253个字符"));
242 return;
243 }
244
245 // 检查是否以点开头或结尾
246 if (domain.startsWith(".") || domain.endsWith(".")) {
247 callback(new Error("域名不能以点开头或结尾"));
248 return;
249 }
250
251 // 检查连续的点
252 if (domain.includes("..")) {
253 callback(new Error("域名不能包含连续的点"));
254 return;
255 }
256
257 // 验证每个标签(以点分隔的部分)
258 const labels = domain.split(".");
259 const tld = labels[labels.length - 1];
260
261 // 检查顶级域名(TLD)不能全是数字
262 if (/^\d+$/.test(tld)) {
263 callback(new Error("顶级域名不能全是数字"));
264 return;
265 }
266
267 // 检查每个标签的长度和内容
268 for (let i = 0; i < labels.length; i++) {
269 const label = labels[i];
270
271 // 标签长度检查
272 if (label.length < 1 || label.length > 63) {
273 callback(new Error(`标签"${label}"长度必须在1-63个字符之间`));
274 return;
275 }
276
277 // 标签内容检查
278 if (!/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$/.test(label)) {
279 callback(new Error(`标签"${label}"格式不正确`));
280 return;
281 }
282 }
283
284 // 使用正则表达式验证
285 if (!strictDomainRegex.test(domain) && !idnRegex.test(domain)) {
286 callback(new Error(`域名格式不符合规范`));
287 return;
288 }
289 }
290 callback();
291 },
292 trigger: "blur",
293 };
294 };
178 295
179 return { 296 return {
180 required, 297 required,
...@@ -184,6 +301,9 @@ export const useValidator = () => { ...@@ -184,6 +301,9 @@ export const useValidator = () => {
184 description, 301 description,
185 chOrEnPreffix, 302 chOrEnPreffix,
186 scrollToError, 303 scrollToError,
187 checkExistName 304 checkExistName,
305 requiredFiles,
306 validateIPList,
307 validateDomainList
188 } 308 }
189 } 309 }
......
1 import type { RouteRecordRaw } from 'vue-router'
2 function Layout() {
3 return import('@/layouts/index.vue')
4 }
5 const routes: RouteRecordRaw[] = [
6 {
7 path: '/data-smart-contract/strategy-management',
8 component: Layout,
9 meta: {
10 title: '策略管理',
11 icon: 'sidebar-videos',
12 },
13 children: [{
14 path: '',
15 name: 'strategyManagement',
16 component: () => import('@/views/data_smart_contract/strategyManagement.vue'),
17 meta: {
18 title: '',
19 sidebar: false,
20 breadcrumb: false,
21 cache: true,
22 editPage: true
23 },
24 }]
25 },
26 {
27 path: '/data-smart-contract/contract-template',
28 component: Layout,
29 meta: {
30 title: '合约模板',
31 icon: 'sidebar-videos',
32 },
33 children: [{
34 path: '',
35 name: 'contractTemplateManagement',
36 component: () => import('@/views/data_smart_contract/contractTemplateManagement.vue'),
37 meta: {
38 title: '',
39 sidebar: false,
40 breadcrumb: false,
41 cache: true
42 },
43 }, {
44 path: 'contract-template-create',
45 name: 'contractTemplateCreate',
46 component: () => import('@/views/data_smart_contract/contractTemplateCreate.vue'),
47 meta: {
48 title: '新建合约模板',
49 sidebar: false,
50 breadcrumb: false,
51 cache: true,
52 editPage: true,
53 reuse: true
54 },
55 beforeEnter: (to, from) => {
56 to.meta.title = !to.query.guid ? '新建合约模板' : `编辑-${to.query.name}`;
57 to.meta.editPage = true;
58 }
59 }]
60 },
61 {
62 path: '/data-smart-contract/contract-manage',
63 component: Layout,
64 meta: {
65 title: '合约管理',
66 icon: 'sidebar-videos',
67 },
68 children: [{
69 path: '',
70 name: 'smartContractManagement',
71 component: () => import('@/views/data_smart_contract/smartContractManagement.vue'),
72 meta: {
73 title: '',
74 sidebar: false,
75 breadcrumb: false,
76 cache: true,
77 editPage: true
78 },
79 }, {
80 path: 'samart-contract-create',
81 name: 'smartContractCreate',
82 component: () => import('@/views/data_smart_contract/smartContractCreate.vue'),
83 meta: {
84 title: '新建合约',
85 sidebar: false,
86 breadcrumb: false,
87 cache: true,
88 editPage: true,
89 reuse: true
90 },
91 beforeEnter: (to, from) => {
92 to.meta.title = !to.query.guid ? '新建合约' : `编辑合约-${to.query.name}`;
93 to.meta.editPage = true;
94 }
95 }, {
96 path: 'smart-contract-detail',
97 name: 'smartContractDetail',
98 component: () => import('@/views/data_smart_contract/smartContractDetail.vue'),
99 meta: {
100 title: '合约详情-',
101 sidebar: false,
102 breadcrumb: false,
103 cache: true,
104 editPage: true,
105 reuse: true
106 },
107 beforeEnter: (to, from) => {
108 if (to.query.type == 'consult') {
109 to.meta.title = `合约协商-${to.query.name}`;
110 } else if (to.query.type == 'sign') {
111 to.meta.title = `合约签署-${to.query.name}`;
112 } else if (to.query.type == 'reject') {
113 to.meta.title = `合约解除-${to.query.name}`;
114 } else {
115 to.meta.title = `合约详情-${to.query.name}`;
116 }
117 }
118 }]
119 },
120 {
121 path: '/data-smart-contract/contract-record-manage',
122 component: Layout,
123 meta: {
124 title: '合约备案',
125 icon: 'sidebar-videos',
126 },
127 children: [{
128 path: '',
129 name: 'contractRecordManage',
130 component: () => import('@/views/data_smart_contract/contractRecordManage.vue'),
131 meta: {
132 title: '',
133 sidebar: false,
134 breadcrumb: false,
135 cache: true,
136 editPage: true
137 },
138 }]
139 },
140 {
141 path: '/data-smart-contract/contract-log-manage',
142 component: Layout,
143 meta: {
144 title: '合约日志管理',
145 icon: 'sidebar-videos',
146 },
147 children: [{
148 path: '',
149 name: 'contractLogManage',
150 component: () => import('@/views/data_smart_contract/contractLogManage.vue'),
151 meta: {
152 title: '',
153 sidebar: false,
154 breadcrumb: false,
155 cache: true,
156 editPage: true
157 },
158 }]
159 },
160 {
161 path: '/data-smart-contract/exec-cnt-index',
162 component: Layout,
163 meta: {
164 title: '合约履行监测',
165 icon: 'sidebar-videos',
166 },
167 children: [{
168 path: '',
169 name: 'execCntIndex',
170 component: () => import('@/views/data_smart_contract/execCntIndex.vue'),
171 meta: {
172 title: '',
173 sidebar: false,
174 breadcrumb: false,
175 cache: true,
176 editPage: true
177 },
178 }]
179 },
180 ]
181
182 export default routes
...\ No newline at end of file ...\ No newline at end of file
...@@ -2,8 +2,8 @@ import { setupLayouts } from 'virtual:meta-layouts' ...@@ -2,8 +2,8 @@ import { setupLayouts } from 'virtual:meta-layouts'
2 import generatedRoutes from 'virtual:generated-pages' 2 import generatedRoutes from 'virtual:generated-pages'
3 import type { RouteRecordRaw } from 'vue-router' 3 import type { RouteRecordRaw } from 'vue-router'
4 import DataAssess from './modules/dataAsset'; 4 import DataAssess from './modules/dataAsset';
5 import DataAssetRegistry from './modules/dataAssetRegistry';
6 import DataService from './modules/dataService'; 5 import DataService from './modules/dataService';
6 import DataSmartContract from './modules/dataSmartContract';
7 7
8 import useSettingsStore from '@/store/modules/settings' 8 import useSettingsStore from '@/store/modules/settings'
9 9
...@@ -92,6 +92,7 @@ const systemRoutes: RouteRecordRaw[] = [ ...@@ -92,6 +92,7 @@ const systemRoutes: RouteRecordRaw[] = [
92 const asyncRoutes: RouteRecordRaw[] = [ 92 const asyncRoutes: RouteRecordRaw[] = [
93 ...DataAssess, 93 ...DataAssess,
94 ...DataService, 94 ...DataService,
95 ...DataSmartContract,
95 // ...DataAssetRegistry, 96 // ...DataAssetRegistry,
96 ] 97 ]
97 98
......
1 const useDataSmartContract = defineStore(
2 'isRefresh',
3 () => {
4 const isRefresh = ref<boolean>(false)
5
6 function set(v: boolean) {
7 isRefresh.value = v;
8 }
9
10 return {
11 isRefresh,
12 set,
13 }
14 },
15 )
16
17 export default useDataSmartContract
...\ No newline at end of file ...\ No newline at end of file
...@@ -5,7 +5,7 @@ import router from '@/router' ...@@ -5,7 +5,7 @@ import router from '@/router'
5 import { ElMessage } from 'element-plus' 5 import { ElMessage } from 'element-plus'
6 import apiUser from '@/api/modules/user' 6 import apiUser from '@/api/modules/user'
7 import { getCurrentTime } from '@/utils/common' 7 import { getCurrentTime } from '@/utils/common'
8 import { getSystemMenu, getUserInfo, getTokenByCode, loginOut, refreshToken, editPasswordInterface, getCurrentUserInfo } from '@/api/modules/queryService' 8 import { getSystemMenu, getUserInfo, getTokenByCode, loginOut, refreshToken, editPasswordInterface, getCurrentUserInfo, getTenantDetailInfo } from '@/api/modules/queryService'
9 9
10 const useUserStore = defineStore( 10 const useUserStore = defineStore(
11 // 唯一ID 11 // 唯一ID
...@@ -57,6 +57,13 @@ const useUserStore = defineStore( ...@@ -57,6 +57,13 @@ const useUserStore = defineStore(
57 currentTenantGuid.value = res.data.tenantInfoList && res.data.tenantInfoList.length ? res.data.tenantInfoList[0].guid : ''; 57 currentTenantGuid.value = res.data.tenantInfoList && res.data.tenantInfoList.length ? res.data.tenantInfoList[0].guid : '';
58 localStorage.setItem('currentTenantGuid', currentTenantGuid.value); 58 localStorage.setItem('currentTenantGuid', currentTenantGuid.value);
59 let currentTenant = res.data.tenantInfoList?.[0]; 59 let currentTenant = res.data.tenantInfoList?.[0];
60 getTenantDetailInfo(currentTenantGuid.value).then((res: any) => {
61 if (res.code == '00000') {
62 localStorage.setItem('tenantInfo', JSON.stringify(res.data));
63 } else {
64 ElMessage.error(res.msg)
65 }
66 })
60 return getCurrentUserInfo({tenantGuid: currentTenantGuid.value}).then((res: any) => { 67 return getCurrentUserInfo({tenantGuid: currentTenantGuid.value}).then((res: any) => {
61 console.log(res, 'getCurrentUserInfo'); 68 console.log(res, 'getCurrentUserInfo');
62 if (res.code == '00000') { 69 if (res.code == '00000') {
......
...@@ -565,7 +565,33 @@ export const tagType = (row, type): any => { ...@@ -565,7 +565,33 @@ export const tagType = (row, type): any => {
565 break 565 break
566 default:state = "info" 566 default:state = "info"
567 } 567 }
568 }else if(type=="releaseStatus") { 568 } else if (type == 'contractStatus') {
569 switch(row[type]) {
570 case '01':
571 state = 'primary'
572 break;
573 case '02':
574 state = 'primary'
575 break;
576 case '03':
577 state = 'primary'
578 break;
579 case '0301':
580 state = 'success'
581 break;
582 case '0302':
583 state = 'danger'
584 break;
585 case '05':
586 state = 'warning'
587 break;
588 case '06':
589 case '00':
590 state = 'info'
591 break;
592 default: state = 'info'
593 }
594 } else if(type=="releaseStatus") {
569 switch (row[type]) { 595 switch (row[type]) {
570 case 1: 596 case 1:
571 state = 'info'; //待发布 597 state = 'info'; //待发布
...@@ -889,7 +915,35 @@ export const tagMethod = (row, type) => { ...@@ -889,7 +915,35 @@ export const tagMethod = (row, type) => {
889 break; 915 break;
890 default: tag = "待发布" 916 default: tag = "待发布"
891 } 917 }
892 }else if (type == 'success') { 918 } else if (type == 'contractStatus') {
919 switch(row[type]) {
920 case '00':
921 tag = '已撤回'
922 break;
923 case '01':
924 tag = '发起'
925 break;
926 case '02':
927 tag = '协商'
928 break;
929 case '03':
930 tag = '签订'
931 break;
932 case '0301':
933 tag = '签订成功'
934 break;
935 case '0302':
936 tag = '签订失败'
937 break;
938 case '05':
939 tag = '履行中'
940 break;
941 case '06':
942 tag = '终止'
943 break;
944 default: tag = "发起"
945 }
946 } else if (type == 'success') {
893 switch (row[type]) { 947 switch (row[type]) {
894 case true: 948 case true:
895 tag = '成功' 949 tag = '成功'
......
...@@ -21,6 +21,7 @@ import { ...@@ -21,6 +21,7 @@ import {
21 } from "@/api/modules/dataService"; 21 } from "@/api/modules/dataService";
22 import useDataServiceStore from "@/store/modules/dataService"; 22 import useDataServiceStore from "@/store/modules/dataService";
23 import useUserStore from "@/store/modules/user"; 23 import useUserStore from "@/store/modules/user";
24 import { changeNum } from '@/utils/common';
24 25
25 const router = useRouter(); 26 const router = useRouter();
26 const dataServiceStore = useDataServiceStore(); 27 const dataServiceStore = useDataServiceStore();
...@@ -162,17 +163,21 @@ const tableInfo = ref({ ...@@ -162,17 +163,21 @@ const tableInfo = ref({
162 { 163 {
163 label: "平均响应时间(s)", field: "averageRespTime", width: 130, align: 'right', type: 'chnum' 164 label: "平均响应时间(s)", field: "averageRespTime", width: 130, align: 'right', type: 'chnum'
164 }, 165 },
166 {
167 label: "绑定连接器数", field: "bindingCount", width: 130, align: 'right', type: "text_btn", value: "detail", click: (scope) => {
168 if (!scope.row.bindingCount) {
169 proxy.$ElMessage.warning('当前没有绑定连接器');
170 return;
171 }
172 //TODO, 查看连接器信息。
173 }, getName: (scope) => {
174 return scope.row.bindingCount != null ? changeNum(scope.row.bindingCount ?? 0) : '--';
175 }
176 },
165 { label: "API请求路径", field: "requestUrl", width: TableColumnWidth.DESCRIPTION }, 177 { label: "API请求路径", field: "requestUrl", width: TableColumnWidth.DESCRIPTION },
166 { 178 {
167 label: '状态', field: 'apiState', type: 'switch', activeText: '启用', inactiveText: '停用', activeValue: 1, inactiveValue: 0, switchWidth: 56, width: 96, align: 'center' 179 label: '状态', field: 'apiState', type: 'switch', activeText: '启用', inactiveText: '停用', activeValue: 1, inactiveValue: 0, switchWidth: 56, width: 96, align: 'center'
168 // , isDisabled: (scope) => {
169 // if (scope.row.apiState == 1) {//被授权的不能禁用。
170 // return true;
171 // }
172 // return scope.row.approveState != 'Y';//正在审批中的不能停用。草稿中的不能启用。
173 // }
174 }, 180 },
175 // { label: "审批状态", field: "approveState", type: "tag", width: TableColumnWidth.STATE, align: 'center' },
176 { label: "API描述", field: "apiDescription", width: TableColumnWidth.DESCRIPTION }, 181 { label: "API描述", field: "apiDescription", width: TableColumnWidth.DESCRIPTION },
177 { label: "修改人", field: "updateUserName", width: TableColumnWidth.USERNAME }, 182 { label: "修改人", field: "updateUserName", width: TableColumnWidth.USERNAME },
178 { label: "修改时间", field: "updateTime", width: 170 }, 183 { label: "修改时间", field: "updateTime", width: 170 },
......
1 <script lang="ts" setup name="confirmDialog">
2
3 const props = defineProps({
4 visible: {
5 type: Boolean,
6 default: false,
7 },
8 type: {
9 type: String,
10 default: 'success'
11 },
12 msg: {
13 type: String,
14 default: ''
15 }
16 });
17
18 const dialogVisible = computed(() => {
19 return props.visible;
20 });
21
22 const emits = defineEmits([
23 "btnClick",
24 ]);
25
26 const cancelDialog = () => {
27 emits("btnClick", 'cancel');
28 }
29
30 const submit = () => {
31 emits("btnClick", 'submit');
32 }
33
34 const dialogClose = () => {
35 emits("btnClick", 'cancel');
36 }
37
38 const imgSrc = computed(() => {
39 return new URL(`../../../assets/images/confirmType/${props.type}.png`, import.meta.url).href;
40 })
41
42 </script>
43
44 <template>
45 <el-dialog v-model="dialogVisible" title="规则详情" width="460" :modal="true" :close-on-click-modal="true"
46 destroy-on-close align-center @close="dialogClose">
47 <div class="content">
48 <img class="header-img" :src="imgSrc"></img>
49 <div class="title" v-html="msg"></div>
50 </div>
51 <div class="dialog-footer">
52 <el-button @click="cancelDialog">取消</el-button>
53 <el-button @click="submit" type="primary" v-preReClick>确定</el-button>
54 </div>
55 </el-dialog>
56 </template>
57
58 <style lang="scss" scoped>
59 .content {
60 display: flex;
61 flex-direction: column;
62 justify-content: center;
63 align-items: center;
64
65 .header-img {
66 width: 126px;
67 height: 72px;
68 margin-bottom: 12px;
69 }
70
71 .title {
72 width: 364px;
73 font-size: 16px;
74 color: #212121;
75 text-align: center;
76 line-height: 24px;
77 font-weight: 400;
78 margin-bottom: 32px;
79 white-space: pre-line;
80 }
81 }
82
83 .dialog-footer {
84 width: 100%;
85 display: flex;
86 justify-content: center;
87 flex-direction: row;
88 margin-bottom: 12px;
89 }
90 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <script lang="ts" setup name="showFile">
2 import { onUploadFilePreview, onUploadFileDownload } from '@/api/modules/common';
3
4 const props = defineProps({
5 file: {
6 type: Array<any>,
7 default: []
8 },
9 showRemove: {
10 type: Boolean,
11 default: false,
12 }
13 });
14
15 const emits = defineEmits(['deleteFile'])
16
17 const handleUploadFileRemove = (file) => {
18 emits("deleteFile");
19 }
20
21 </script>
22
23 <template>
24 <span v-for="(item) in (file || [])" class="item_value" :style="{ 'padding-left': '0px' }">
25 <div class="file-operate">
26 <template
27 v-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'xls' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'xlsx' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'csv'">
28 <img class="file-img" src="../../../assets/images/excel.png" />
29 </template>
30 <template
31 v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'doc' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'docx'">
32 <img class="file-img" src="../../../assets/images/word.png" />
33 </template>
34 <template v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'zip'">
35 <img class="file-img" src="../../../assets/images/zip.png" />
36 </template>
37 <template v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'rar'">
38 <img class="file-img" src="../../../assets/images/RAR.png" />
39 </template>
40 <template v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'pdf'">
41 <img class="file-img" src="../../../assets/images/PDF.png" />
42 </template>
43 <template v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'png'">
44 <img class="file-img" src="../../../assets/images/png.png" />
45 </template>
46 <template
47 v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'jpg' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'jpeg'">
48 <img class="file-img" src="../../../assets/images/jpg.png" />
49 </template>
50 <div v-if="props.showRemove" :style="{ right: '72px' }" class="file-preview"
51 @click="handleUploadFileRemove(item)">删除
52 </div>
53 <div class="file-name" :style="{ width: showRemove ? 'calc(100% - 150px)' : 'calc(100% - 120px)' }"><ellipsis-tooltip :content="item.name ?? ''" class-name="w100f"
54 refName="tooltipOver"></ellipsis-tooltip></div>
55 <div :style="{ right: '36px' }"
56 v-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'pdf' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'png' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'jpg' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'jpeg'"
57 class="file-preview" @click="onUploadFilePreview(item)">查看</div>
58 <div :style="{ right: '0px' }" class="file-preview" @click="onUploadFileDownload(item)">下载</div>
59 </div>
60 </span>
61 </template>
62
63 <style lang="scss" scoped>
64 .file-operate {
65 display: flex;
66 align-items: center;
67 position: relative;
68
69 .file-img {
70 width: 24px;
71 height: 24px;
72 }
73
74 &:hover {
75 background-color: #f5f5f5;
76 }
77
78 .file-name {
79 width: calc(100% - 120px);
80 color: var(--el-color-regular);
81 margin-left: 4px;
82 }
83
84 .file-preview {
85 position: absolute;
86 cursor: pointer;
87 color: var(--el-color-primary);
88 margin-right: 8px;
89 }
90 }
91 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <route lang="yaml">
2 name: contractRecordManage
3 </route>
4
5 <script lang="ts" setup name="contractRecordManage">
6 import { ref } from 'vue';
7 import TableTools from "@/components/Tools/table_tools.vue";
8 import {
9 getContractOverviewPageList,
10 getContractOverviewTenantList
11 } from "@/api/modules/dataSmartContract"
12 import useDataSmartContract from "@/store/modules/dataSmartContract";
13 import { commonPageConfig } from '@/utils/enum';
14
15 const userData = JSON.parse(localStorage.userData);
16 const router = useRouter();
17 const route = useRoute();
18 const { proxy } = getCurrentInstance() as any;
19 const dataSmartContractStore = useDataSmartContract();
20
21 /** 发起主体下拉列表数据 */
22 const initiatorListData: any = ref([]);
23
24 const searchItemList = ref([
25 {
26 type: "input",
27 label: "",
28 field: "contractName",
29 default: "",
30 placeholder: "合约名称",
31 maxlength: 50,
32 clearable: true,
33 },
34 {
35 type: 'select',
36 label: '',
37 field: 'initiatorGuid',
38 default: '',
39 placeholder: '发起主体',
40 props: {
41 value: 'tenantGuid',
42 label: 'tenantName'
43 },
44 options: initiatorListData.value,
45 filterable: true,
46 clearable: true
47 },
48 {
49 type: 'date-time',
50 label: '',
51 field: 'signatureTime',
52 default: [],
53 defaultStartTime: new Date(2000, 1, 1, 0, 0, 0),
54 defaultEndTime: new Date(2000, 1, 1, 23, 59, 59),
55 startPlaceholder: '签署开始时间',
56 endPlaceholder: '签署结束时间',
57 clearable: true
58 },
59 ]);
60
61 const tableFields = ref([
62 { label: "序号", type: "index", width: 56, align: "center" },
63 { label: "合约名称", field: "contractName", width: 160, },
64 { label: "签署方式", field: "signModeName", width: 120 },
65 { label: "产品名称", field: "productName", width: 180 },
66 { label: "合约编号", field: "contractId", width: 355 },
67 { label: "发起主体", field: "tenantName", width: 205 },
68 { label: "签署时间", field: "signatureTime", width: 170 }
69 ]);
70
71 const page = ref({
72 ...commonPageConfig,
73 contractName: '',
74 initiatorGuid: '',
75 signatureTime: [],
76 });
77
78 const currTableData: any = ref({});
79 const tableInfo = ref({
80 id: 'contract-table',
81 rowKey: 'guid',
82 loading: false,
83 fields: tableFields.value,
84 data: [],
85 page: {
86 type: "normal",
87 rows: 0,
88 ...page.value,
89 },
90 actionInfo: {
91 label: "操作",
92 type: "btn",
93 width: 80,
94 btns: (scope) => {
95 let row = scope.row;
96 let btns: any = [];
97 btns.push({
98 value: 'view', label: '查看', click: () => {
99 if (scope.row.contractStatus == '05') {
100 router.push({
101 name: 'smartContractDetail',
102 query: {
103 guid: scope.row.guid,
104 name: scope.row.contractName,
105 type: 'keepAgree',
106 isDetail: 'Y'
107 }
108 });
109 } else {
110 router.push({
111 name: 'smartContractDetail',
112 query: {
113 guid: scope.row.guid,
114 name: scope.row.contractName,
115 isDetail: 'Y'
116 }
117 });
118 }
119 }
120 });
121 return btns;
122 }
123 }
124 });
125
126 const toSearch = (val: any, clear: boolean = false) => {
127 if (clear) {
128 searchItemList.value.map((item) => (item.default = ""));
129 page.value.contractName = '';
130 page.value.initiatorGuid = '';
131 page.value.signatureTime = [];
132 } else {
133 page.value.contractName = val.contractName;
134 page.value.initiatorGuid = val.initiatorGuid;
135 page.value.signatureTime = val.signatureTime;
136 }
137 getTableData();
138 };
139
140 const getTableData = () => {
141 getContractOverviewTenantList().then((res: any) => {
142 if (res?.code == proxy.$passCode) {
143 initiatorListData.value = res.data || [];
144 searchItemList.value[1].options = initiatorListData.value;
145 } else {
146 res?.msg && proxy.$ElMessage.error(res?.msg)
147 }
148 })
149 tableInfo.value.loading = true
150 getContractOverviewPageList({
151 pageIndex: page.value.curr,
152 pageSize: page.value.limit,
153 contractName: page.value.contractName,
154 initiatorGuid: page.value.initiatorGuid,
155 signatureStartTime: page.value.signatureTime?.[0],
156 signatureEndTime: page.value.signatureTime?.[1]
157 }).then((res: any) => {
158 tableInfo.value.data = [];
159 if (res?.code == proxy.$passCode) {
160 const data = res.data || {};
161 tableInfo.value.loading = false
162 tableInfo.value.data = data.records || []
163 tableInfo.value.page.limit = data.pageSize
164 tableInfo.value.page.curr = data.pageIndex
165 tableInfo.value.page.rows = data.totalRows
166 } else {
167 res?.msg && proxy.$ElMessage.error(res?.msg)
168 tableInfo.value.loading = false
169 }
170 }).catch(() => {
171 tableInfo.value.loading = false
172 })
173 };
174
175 const tablePageChange = (info) => {
176 page.value.curr = Number(info.curr);
177 page.value.limit = Number(info.limit);
178 tableInfo.value.page.curr = page.value.curr;
179 tableInfo.value.page.limit = page.value.limit;
180 getTableData();
181 };
182
183 onActivated(() => {
184 if (dataSmartContractStore.isRefresh) {//如果是首次加载,则不需要调用
185 page.value.curr = 1;
186 getTableData();
187 dataSmartContractStore.set(false);
188 }
189 })
190
191 onBeforeMount(() => {
192 !dataSmartContractStore.isRefresh && toSearch({})
193 })
194
195 </script>
196
197 <template>
198 <div class="container_wrap">
199 <div class="table_tool_wrap">
200 <TableTools :searchItems="searchItemList" :searchId="'contract-search'" @search="toSearch" :init="false" />
201 </div>
202 <div class="table_panel_wrap">
203 <Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" />
204 </div>
205 </div>
206 </template>
207
208 <style lang="scss" scoped>
209 .container_wrap {
210 padding: 0px 16px;
211
212 .table_panel_wrap {
213 height: calc(100% - 44px);
214 }
215 }
216
217 :deep(.el-tag.el-tag--primary) {
218 color: #0E5FD8;
219 background: #F2F9FF;
220 border: 1px solid rgba(224, 239, 255, 1);
221 }
222 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <route lang="yaml">
2 name: contractTemplateCreate
3 </route>
4
5 <script lang="ts" setup name="contractTemplateCreate">
6 import { useValidator } from "@/hooks/useValidator";
7 import useUserStore from "@/store/modules/user";
8 import useDataSmartContract from "@/store/modules/dataSmartContract";
9 import {
10 getContractTemplateDetail,
11 getActionPolicyList,
12 getConstraintPolicyList,
13 updateContractTemplate,
14 saveContractTemplate,
15 } from "@/api/modules/dataSmartContract"
16 import {
17 getParamsList
18 } from "@/api/modules/queryService";
19 import StrategyTable from "./components/strategyTable.vue";
20
21 const { required } = useValidator();
22 const router = useRouter();
23 const route = useRoute();
24 const { proxy } = getCurrentInstance() as any;
25 const userStore = useUserStore();
26 const dataSmartContract = useDataSmartContract();
27 const fullPath = route.fullPath;
28 const fullscreenLoading = ref(false);
29 const expandBase = ref(false);
30 const expandInfo = ref(false);
31
32 const baseInfoFormRef = ref();
33 const baseInfoFormItems = ref([{
34 type: 'input',
35 label: '合约模板名称',
36 field: 'templateName',
37 default: '',
38 placeholder: '请输入',
39 maxlength: 50,
40 clearable: true,
41 required: true
42 }, {
43 type: 'input',
44 label: '版本',
45 field: 'version',
46 default: 'v1.0.0',
47 placeholder: '-',
48 disabled: true,
49 clearable: true,
50 required: false
51 }, {
52 type: 'input',
53 label: '合约模板编号',
54 field: 'templateId',
55 default: '',
56 placeholder: '自动生成',
57 disabled: true,
58 clearable: true,
59 required: false
60 }, {
61 label: '启用状态',
62 type: 'switch',
63 field: 'bizStatus',
64 default: 'Y',
65 placeholder: '请选择',
66 activeValue: 'Y',
67 inactiveValue: 'N',
68 switchWidth: 32,
69 }, {
70 label: '模板描述',
71 type: 'textarea',
72 placeholder: '请输入',
73 field: 'description',
74 default: '',
75 block: true,
76 maxlength: 500,
77 clearable: true,
78 required: false,
79 }]);
80
81 const baseInfoFormRules = ref({
82 templateName: [required("请填写合约模板名称")],
83 });
84
85 const strategyTableRef = ref();
86
87 const cancel = () => {
88 proxy.$openMessageBox(
89 "当前页面尚未保存,确定放弃修改吗?",
90 () => {
91 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
92 router.push({
93 name: "contractTemplateManagement",
94 });
95 },
96 () => {
97 proxy.$ElMessage.info("已取消");
98 }
99 );
100 }
101
102 const submit = () => {
103 baseInfoFormRef.value.ruleFormRef?.validate((valid, errorItem) => {
104 if (valid) {
105 let validate = strategyTableRef.value?.validateValue();
106 if (!validate) {
107 expandInfo.value = true;
108 return;
109 }
110 let params = { ...baseInfoFormRef.value.formInline };
111 params.policyRQVOS = strategyTableRef.value.strategyData?.map((d, index) => {
112 return Object.assign({}, d, { orderNum: index + 1 })
113 });
114 if (route.query.guid) {
115 params.guid = route.query.guid;
116 fullscreenLoading.value = true;
117 updateContractTemplate(params).then((res: any) => {
118 fullscreenLoading.value = false;
119 if (res?.code == proxy.$passCode) {
120 proxy.$ElMessage.success('编辑合约模板成功');
121 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
122 router.push({
123 name: "contractTemplateManagement",
124 });
125 dataSmartContract.set(true);
126 } else {
127 res?.msg && proxy.$ElMessage.error(res?.msg);
128 }
129 }).catch(() => {
130 fullscreenLoading.value = false;
131 });
132 } else {
133 fullscreenLoading.value = true;
134 delete params.version;
135 saveContractTemplate(params).then((res: any) => {
136 fullscreenLoading.value = false;
137 if (res?.code == proxy.$passCode) {
138 proxy.$ElMessage.success('新建合约模板成功');
139 userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
140 router.push({
141 name: "contractTemplateManagement",
142 });
143 dataSmartContract.set(true);
144 } else {
145 res?.msg && proxy.$ElMessage.error(res?.msg);
146 }
147 }).catch(() => {
148 fullscreenLoading.value = false;
149 });
150 }
151 } else {
152 expandBase.value = true;
153 var obj = Object.keys(errorItem);
154 baseInfoFormRef.value.ruleFormRef?.scrollToField(obj[0]);
155 }
156 })
157 }
158
159 const detailInfo: any = ref({});
160 /** 约束运算符字典下拉 */
161 const operatorOptionList: any = ref([]);
162
163 /** 约束行为下拉列表 */
164 const constraintOptionsList: any = ref([]);
165
166 /** 策略操作行为下拉列表 */
167 const actionOptionsList: any = ref([]);
168
169 onBeforeMount(() => {
170 if (route.query.guid) {
171 fullscreenLoading.value = true;
172 getContractTemplateDetail({ guid: route.query.guid }).then((res: any) => {
173 fullscreenLoading.value = false;
174 if (res?.code == proxy.$passCode) {
175 detailInfo.value = res.data || {};
176 baseInfoFormItems.value.forEach(item => {
177 item.default = detailInfo.value[item.field] || "";
178 });
179 } else {
180 res?.msg && proxy.$ElMessage.error(res?.msg);
181 }
182 });
183 }
184 getParamsList({ dictType: '约束运算符' }).then((res: any) => {
185 if (res?.code == proxy.$passCode) {
186 const data = res.data || [];
187 operatorOptionList.value = data;
188 } else {
189 res?.msg && proxy.$ElMessage.error(res?.msg);
190 }
191 })
192 getActionPolicyList().then((res: any) => {
193 if (res?.code == proxy.$passCode) {
194 const data = res.data || [];
195 actionOptionsList.value = data;
196 } else {
197 res?.msg && proxy.$ElMessage.error(res?.msg);
198 }
199 })
200 getConstraintPolicyList().then((res: any) => {
201 if (res?.code == proxy.$passCode) {
202 const data = res.data || [];
203 constraintOptionsList.value = data;
204 } else {
205 res?.msg && proxy.$ElMessage.error(res?.msg);
206 }
207 })
208 })
209
210 </script>
211
212 <template>
213 <div class="container_wrap full" v-loading="fullscreenLoading">
214 <div class="content_main panel">
215 <ContentWrap title="模板信息" expandSwicth style="margin-top: 15px" :isExpand="expandBase"
216 @expand="(v) => (expandBase = v)" description="">
217 <Form ref="baseInfoFormRef" formId="base-info-form" :itemList="baseInfoFormItems" :rules="baseInfoFormRules"
218 col="col3" />
219 </ContentWrap>
220 <ContentWrap title="策略信息" expandSwicth style="margin-top: 15px" :isExpand="expandInfo"
221 @expand="(v) => (expandInfo = v)" description="">
222 <StrategyTable ref="strategyTableRef" :value="detailInfo.policyRSVOS || (route.query.guid ? [] : [{
223 index: 1,
224 action: '',
225 children: [{ childIndex: 1 }]
226 }])" :operatorOptionList="operatorOptionList" :actionOptionsList="actionOptionsList"
227 :constraintOptionsList="constraintOptionsList"></StrategyTable>
228 </ContentWrap>
229 </div>
230 <div class="tool_btns">
231 <div class="btns">
232 <el-button @click="cancel">取消</el-button>
233 <el-button type="primary" @click="submit">确定</el-button>
234 </div>
235 </div>
236 </div>
237 </template>
238
239 <style lang="scss" scoped>
240 .container_wrap {
241 overflow: hidden;
242
243 .content_main {
244 height: calc(100% - 45px);
245 overflow: hidden auto;
246
247 &.panel {
248 padding: 0 16px 16px;
249 }
250 }
251 }
252
253 .tool_btns {
254 height: 44px;
255 margin: 0 -8px;
256 display: flex;
257 justify-content: center;
258 align-items: center;
259 border-top: 1px solid #d9d9d9;
260 }
261
262 :deep(.strategyTable.el-table) {
263 .cell {
264 padding: 0px 10px;
265 }
266
267 & td.el-table__cell {
268 padding: 2px 0px;
269 height: 36px;
270 }
271 }
272 </style>
1 <route lang="yaml">
2 name: contractTemplateManagement
3 </route>
4
5 <script lang="ts" setup name="contractTemplateManagement">
6 import { ref } from 'vue';
7 import TableTools from "@/components/Tools/table_tools.vue";
8 import {
9 getContractTemplatePageList,
10 copyContractTemplate,
11 deleteContractTemplate,
12 updateContractTemplateState
13 } from "@/api/modules/dataSmartContract"
14 import useDataSmartContract from "@/store/modules/dataSmartContract";
15 import { commonPageConfig } from '@/utils/enum';
16 import { useValidator } from "@/hooks/useValidator";
17
18 const router = useRouter();
19 const route = useRoute();
20 const { proxy } = getCurrentInstance() as any;
21 const dataSmartContractStore = useDataSmartContract();
22 const { required } = useValidator();
23
24 const searchItemList = ref([
25 {
26 type: "input",
27 label: "",
28 field: "templateName",
29 default: "",
30 placeholder: "合约模板名称",
31 maxlength: 50,
32 clearable: true,
33 },
34 {
35 type: 'select',
36 label: '',
37 field: 'bizStatus',
38 default: '',
39 placeholder: '启用状态',
40 options: [
41 { label: '启用', value: 'Y' },
42 { label: '停用', value: 'N' },
43 ],
44 filterable: true,
45 clearable: true
46 }
47 ]);
48
49 const tableFields = ref([
50 { label: "序号", type: "index", width: 56, align: "center" },
51 { label: "合约模板名称", field: "templateName", width: 220, },
52 { label: "版本号", field: "version", width: 100 },
53 { label: '启用状态', width: 96, field: 'bizStatus', type: 'switch', activeText: '启用', inactiveText: '停用', activeValue: 'Y', inactiveValue: 'N', align: 'center' },
54 { label: "合约模板编号", field: "templateId", width: 190 },
55 { label: "修改人", field: "updateUserName", width: 130 },
56 { label: "修改时间", field: "updateTime", width: 170 },
57 ]);
58
59 const page = ref({
60 ...commonPageConfig,
61 templateName: '',
62 bizStatus: ''
63 });
64 const currTableData: any = ref({});
65 const tableInfo = ref({
66 id: 'contract-template-table',
67 rowKey: 'guid',
68 loading: false,
69 fields: tableFields.value,
70 data: [],
71 page: {
72 type: "normal",
73 rows: 0,
74 ...page.value,
75 },
76 actionInfo: {
77 label: "操作",
78 type: "btn",
79 width: 140,
80 btns: (scope) => {
81 let row = scope.row;
82 return [{
83 value: 'edit', label: '编辑', click: (scope) => {
84 router.push({
85 name: 'contractTemplateCreate',
86 query: {
87 guid: scope.row.guid,
88 name: scope.row.templateName
89 }
90 });
91 }
92 }, {
93 value: 'copy', label: '复制', click: copyTemplate
94 }, {
95 value: 'delete', label: '删除', click: (scope) => {
96 proxy.$openMessageBox("此操作将永久删除, 是否继续?", () => {
97 deleteContractTemplate([scope.row.guid]).then((res: any) => {
98 if (res?.code == proxy.$passCode) {
99 page.value.curr = 1;
100 getTableData();
101 proxy.$ElMessage.success('删除成功');
102 } else {
103 res?.msg && proxy.$ElMessage.error(res?.msg);
104 }
105 });
106 }, () => {
107 proxy.$ElMessage.info("已取消");
108 })
109 }
110 }]
111 }
112 }
113 });
114
115 const tableSwitchBeforeChange = (scope, field, callback) => {
116 const msg = `确定${scope.row[field] == 'Y' ? '停用' : '启用'}${scope.row.templateName}】?`
117 proxy.$openMessageBox(msg, () => {
118 const state = scope.row[field] == 'Y' ? 'N' : 'Y'
119 const result = tableSwitchChange(state, scope, field)
120 callback(result)
121 }, () => {
122 callback(false)
123 });
124 }
125
126 const tableSwitchChange = (val, scope, field) => {
127 return new Promise((resolve, reject) => {
128 let params = {
129 guid: scope.row.guid,
130 bizStatus: val
131 }
132 updateContractTemplateState(params).then((res: any) => {
133 if (res?.code == proxy.$passCode && res.data) {
134 getTableData();
135 proxy.$ElMessage({
136 type: "success",
137 message: `【${scope.row.templateName}${val == 'Y' ? '启用' : '停用'}成功`,
138 });
139 resolve(true)
140 } else {
141 res?.msg && proxy.$ElMessage.error(res?.msg)
142 reject(false)
143 }
144 }).catch(() => {
145 reject(false)
146 })
147 })
148 }
149
150
151 const copyTemplate = (scope) => {
152 currTableData.value = scope.row;
153 copyFormItems.value[0].default = scope.row.templateName + '_copy';
154 copyDialogInfo.value.formInfo.items = copyFormItems.value;
155 copyDialogInfo.value.visible = true;
156 }
157
158 const toSearch = (val: any, clear: boolean = false) => {
159 if (clear) {
160 searchItemList.value.map((item) => (item.default = ""));
161 page.value.templateName = '';
162 page.value.bizStatus = "";
163 } else {
164 page.value.templateName = val.templateName;
165 page.value.bizStatus = val.bizStatus;
166 }
167 getTableData();
168 };
169
170 const getTableData = () => {
171 tableInfo.value.loading = true
172 getContractTemplatePageList({
173 pageIndex: page.value.curr,
174 pageSize: page.value.limit,
175 templateName: page.value.templateName,
176 bizStatus: page.value.bizStatus
177 }).then((res: any) => {
178 tableInfo.value.loading = false
179 if (res?.code == proxy.$passCode) {
180 const data = res.data || {}
181 tableInfo.value.data = data.records || []
182 tableInfo.value.page.limit = data.pageSize
183 tableInfo.value.page.curr = data.pageIndex
184 tableInfo.value.page.rows = data.totalRows
185 } else {
186 res?.msg && proxy.$ElMessage.error(res?.msg)
187 }
188 }).catch(() => {
189 tableInfo.value.loading = false
190 })
191 };
192
193 const tablePageChange = (info) => {
194 page.value.curr = Number(info.curr);
195 page.value.limit = Number(info.limit);
196 tableInfo.value.page.curr = page.value.curr;
197 tableInfo.value.page.limit = page.value.limit;
198 getTableData();
199 };
200
201 const newCreate = () => {
202 router.push({
203 name: 'contractTemplateCreate'
204 });
205 }
206
207 onActivated(() => {
208 if (dataSmartContractStore.isRefresh) {//如果是首次加载,则不需要调用
209 page.value.curr = 1;
210 getTableData();
211 dataSmartContractStore.set(false);
212 }
213 })
214
215 onBeforeMount(() => {
216 !dataSmartContractStore.isRefresh && toSearch({})
217 })
218
219 /** -------------- 复制功能 ------------------- */
220 const copyFormItems = ref([{
221 type: 'input',
222 label: '合约模板名称',
223 field: 'templateName',
224 default: '',
225 block: true,
226 placeholder: '请输入',
227 maxlength: 50,
228 clearable: true,
229 required: true
230 }]);
231
232 const copyFormRules = ref({
233 templateName: [required("请填写合约模板名称")],
234 });
235
236 const copyDialogInfo = ref({
237 visible: false,
238 size: 480,
239 title: "复制合约模板",
240 type: 'add',
241 formInfo: {
242 id: 'copy-form',
243 items: copyFormItems.value,
244 rules: copyFormRules.value
245 },
246 btns: {
247 submit: (btn, info) => {
248 info.guid = currTableData.value.guid;
249 copyDialogInfo.value.submitBtnLoading = true;
250 copyContractTemplate(info).then((res: any) => {
251 copyDialogInfo.value.submitBtnLoading = false;
252 if (res.code == proxy.$passCode) {
253 page.value.curr = 1;
254 getTableData();
255 proxy.$ElMessage({
256 type: 'success',
257 message: `【${info.templateName}】复制成功`
258 })
259 copyDialogInfo.value.visible = false;
260 } else {
261 proxy.$ElMessage.error(res.msg);
262 }
263 })
264 },
265 cancel: () => {
266 copyDialogInfo.value.visible = false;
267 }
268 },
269 submitBtnLoading: false
270 });
271
272
273 </script>
274
275 <template>
276 <div class="container_wrap">
277 <div class="table_tool_wrap">
278 <TableTools :searchItems="searchItemList" :searchId="'settle-asset-search'" @search="toSearch" :init="false" />
279 <div class="tools_btns">
280 <el-button type="primary" @click="newCreate">新增</el-button>
281 </div>
282 </div>
283 <div class="table_panel_wrap">
284 <Table :tableInfo="tableInfo" @tablePageChange="tablePageChange"
285 @tableSwitchBeforeChange="tableSwitchBeforeChange" />
286 </div>
287 <!-- 复制对话框 -->
288 <Dialog_form :dialogConfigInfo="copyDialogInfo" />
289 </div>
290 </template>
291
292 <style lang="scss" scoped>
293 .container_wrap {
294 padding: 0px 16px;
295 }
296 </style>
...\ No newline at end of file ...\ No newline at end of file
1 <route lang="yaml">
2 name: execCntIndex
3 </route>
4
5 <script lang="ts" setup name="execCntIndex">
6 import { changeNum } from '@/utils/common'
7 import {
8 getContractStatis,
9 getContractMonthStatis,
10 getLogTableList
11 } from "@/api/modules/dataSmartContract";
12 import * as echarts from 'echarts';
13 import { commonPageConfig } from '@/utils/enum';
14
15 const { proxy } = getCurrentInstance() as any;
16 const detailInfo: any = ref({});
17
18 const logTableInfo: any = ref({
19 id: "plan-detail-table",
20 loading: false,
21 // height: 'auto',
22 // minPanelHeight: '60px',
23 // minHeight: '60px',
24 // maxHeight: '250px',
25 fields: [
26 { label: "序号", type: "index", width: 56, align: "center", fixed: true },
27 { label: "合约标识", field: "contractId", width: 355 },
28 { label: "合约名称", field: "contractName", width: 140 },
29 { label: "执行策略id", field: "strategyId", width: 260 },
30 { label: "执行时间", field: "operationTime", width: 170 },
31 { label: "执行节点标识", field: "executionEntityId", width: 180 },
32 { label: "上报时间", field: "operationTime", width: 170 },
33 { label: "异常类型", field: "executionResult", width: 120 },
34 ],
35 data: [],
36 page: {
37 type: "normal",
38 rows: 0,
39 ...commonPageConfig,
40 },
41 actionInfo: {
42 show: false
43 }
44 });
45
46 const pageChange = (info) => {
47 logTableInfo.value.page.curr = Number(info.curr);
48 logTableInfo.value.page.limit = Number(info.limit);
49 getLogTableListData(true);
50 };
51
52 const getLogTableListData = (isPage = false) => {
53 isPage && (logTableInfo.value.loading = true);
54 return getLogTableList({
55 pageIndex: logTableInfo.value.page.curr,
56 pageSize: logTableInfo.value.page.limit,
57 }).then((res: any) => {
58 logTableInfo.value.loading = false;
59 if (res?.code == proxy.$passCode) {
60 const data = res.data || {};
61 logTableInfo.value.data = data.records || []
62 logTableInfo.value.page.limit = data.pageSize
63 logTableInfo.value.page.curr = data.pageIndex
64 logTableInfo.value.page.rows = data.totalRows
65 } else {
66 res?.msg && proxy.$ElMessage.error(res?.msg)
67 }
68 })
69 }
70
71 let barChart: any = null;
72
73 const barChartData: any = ref([]);
74
75 onMounted(() => {
76 barChart = echarts.init(document.getElementById('bar'));
77 setBarChartOption(barChart);
78 })
79
80 watch(() => barChartData.value, (val) => {
81 setBarChartOption(barChart);
82 }, {
83 deep: true
84 })
85
86 /** 设置柱形图option,默认只 展示12次的 */
87 const setBarChartOption = (barChart) => {
88 return new Promise((resolve, reject) => {
89 if (!barChartData.value || !Object.keys(barChartData.value).length) {
90 let option1 = {
91 title: [
92 {
93 text: "",
94 left: "30px",
95 top: "30px",
96 },
97 {
98 text: "暂无数据",
99 left: "center",
100 top: "center",
101 textStyle: {
102 fontFamily: 'SimSun',
103 fontStyle: "normal",
104 fontWeight: "400",
105 fontSize: 18,
106 color: '#999'
107 },
108 },
109 ],
110 };
111 barChart.setOption(option1, true);
112 window.addEventListener("resize", () => {
113 barChart.resize();
114 });
115 return;
116 }
117 let getLast12Months = () => {
118 const months: any = [];
119 const currentDate = new Date();
120
121 for (let i = 11; i >= 0; i--) {
122 const targetDate = new Date(currentDate);
123 targetDate.setMonth(targetDate.getMonth() - i);
124
125 const year = targetDate.getFullYear();
126 const month = String(targetDate.getMonth() + 1).padStart(2, '0');
127
128 months.push(`${year}-${month}`);
129 }
130
131 return months;
132 }
133
134 // 使用示例
135 const last12Months = getLast12Months();
136
137 let itemXAxisData: any = last12Months;
138 let itemYAxisData: any = last12Months.map(v => {
139 return barChartData.value[v] || 0;
140 });
141 let option = {
142 textStyle: {
143 fontFamily: 'SimSun'
144 },
145 color: ['#5B8FF9', '#FF4E00', '#867EEC', '#FDBC3E', '#F48A64', '#276FF5', '#46D0B5'],
146 title: {
147 show: false,
148 left: '30px',
149 top: '30px',
150 },
151 tooltip: {
152 trigger: 'axis',
153 axisPointer: {
154 type: 'cross',
155 crossStyle: {
156 color: '#999'
157 }
158 },
159 textStyle: {
160 align: 'left'
161 },
162 },
163 legend: {
164 show: false,
165 right: 0,
166 textStyle: {
167 fontSize: 14
168 },
169 },
170 grid: {
171 left: 30,
172 right: 60,
173 bottom: 5,
174 containLabel: true
175 },
176 xAxis: {
177 type: 'category',
178 boundaryGap: false,
179 nameTextStyle: {
180 color: '#000000'
181 },
182 axisLabel: {
183 interval: 'auto',
184 textStyle: {
185 color: '#000000'
186 },
187 },
188 axisTick: {
189 show: false,
190 },
191 axisLine: {
192 lineStyle: {
193 color: '#d9d9d9'
194 }
195 },
196 data: itemXAxisData
197 },
198 yAxis: {
199 type: 'value',
200 name: '',
201 min: 0,
202 minInterval: 1,
203 nameTextStyle: {
204 color: '#000000'
205 },
206 axisLabel: {
207 textStyle: {
208 color: '#000000'
209 }
210 },
211 axisLine: {
212 //y轴
213 show: false
214 }
215 },
216 series: [{
217 name: '已签署合约数',
218 type: 'line',
219 data: itemYAxisData,
220 label: {
221 show: false,
222 },
223 tooltip: {
224 valueFormatter: function (value) {
225 return changeNum(value, 0);
226 }
227 },
228 yAxisIndex: 0
229 }]
230 };
231 option && barChart.setOption(option, true);
232 barChart.on('finished', () => {
233 resolve(true);
234 });
235 window.addEventListener('resize', () => {
236 barChart.resize();
237 });
238 });
239 }
240
241 const fullscreenloading = ref(false);
242
243 onBeforeMount(() => {
244 fullscreenloading.value = true;
245 let ps1 = getContractStatis().then((res: any) => {
246 if (res?.code == proxy.$passCode) {
247 detailInfo.value = res.data || {};
248 } else {
249 res?.msg && proxy.$ElMessage.error(res?.msg)
250 }
251 })
252 let ps2 = getContractMonthStatis().then((res: any) => {
253 if (res?.code == proxy.$passCode) {
254 barChartData.value = res.data || {};
255 } else {
256 res?.msg && proxy.$ElMessage.error(res?.msg)
257 }
258 })
259 let ps3 = getLogTableListData();
260 Promise.all([ps1, ps2, ps3]).then(() => {
261 fullscreenloading.value = false;
262 }).catch(() => {
263 fullscreenloading.value = false;
264 })
265 })
266
267 </script>
268
269 <template>
270 <div class="content-main" v-loading="fullscreenloading">
271 <div class="title">合约备案执行统计</div>
272 <div class="kpi-content">
273 <div class="border-content">
274 <span class="text">备案合约数</span>
275 <span class="number num-color">{{ detailInfo.registerNum != null ? changeNum(detailInfo.registerNum ?? 0) : '--'
276 }}<span class="unit" v-show="detailInfo.registerNum != null"></span></span>
277 </div>
278 <div class="border-content ml16">
279 <span class="text">备案策略数</span>
280 <span class="number num-color">{{ detailInfo.registerPolicyNum != null ? changeNum(detailInfo.registerPolicyNum
281 ?? 0) : '--'
282 }}<span class="unit" v-show="detailInfo.registerPolicyNum != null"></span></span>
283 </div>
284 <div class="border-content ml16">
285 <span class="text">策略执行数</span>
286 <span class="number num-color">{{ detailInfo.registerPolicyExecutionNum != null ?
287 (changeNum(detailInfo.registerPolicyExecutionNum ?? 0)) :
288 '--'
289 }}<span class="unit" v-show="detailInfo.registerPolicyExecutionNum != null"></span></span>
290 </div>
291 <div class="border-content ml16">
292 <span class="text">签署合约主体数</span>
293 <span class="number num-color">{{ detailInfo.registerSignatureNum != null ?
294 changeNum(detailInfo.registerSignatureNum ?? 0) : '--'
295 }}<span class="unit" v-show="detailInfo.registerSignatureNum != null"></span></span>
296 </div>
297 <div class="border-content ml16">
298 <span class="text">策略执行节点数</span>
299 <span class="number num-color">{{ detailInfo.registerExecutionNodeNum != null ?
300 changeNum(detailInfo.registerExecutionNodeNum ?? 0) : '--'
301 }}<span class="unit" v-show="detailInfo.registerExecutionNodeNum != null"></span></span>
302 </div>
303 </div>
304 <div class="title">合约履行异常预警记录</div>
305 <Table class="table-h" :tableInfo="logTableInfo" @tablePageChange="pageChange" />
306 <div class="title">近12个月备案合约趋势</div>
307 <div class="content-chart-bar" id="bar">
308 </div>
309 </div>
310 </template>
311
312 <style lang="scss" scoped>
313 .content-main {
314 height: 100%;
315 overflow-y: auto;
316 overflow-x: hidden;
317 padding: 0px 16px 16px;
318 }
319
320 .title {
321 line-height: 24px;
322 font-size: 16px;
323 color: #212121;
324 font-weight: 600;
325 margin-top: 12px;
326 margin-bottom: 8px;
327 }
328
329 .kpi-content {
330 display: flex;
331 flex-direction: row;
332 }
333
334 .border-content {
335 height: 76px;
336 display: flex;
337 flex-direction: column;
338 align-items: flex-start;
339 padding-left: 16px;
340 justify-content: center;
341 border: 1px solid #d9d9d9;
342 //width: 160px;
343 flex: 1;
344 min-width: 150px;
345 border-radius: 2px;
346
347 .number {
348 line-height: 30px;
349 font-weight: 700;
350 font-size: 20px;
351
352 .unit {
353 font-size: 18px;
354 font-weight: 400;
355 }
356 }
357
358 .num-color {
359 color: #212121;
360 }
361
362 .text {
363 font-size: 14px;
364 color: #666666;
365 display: flex;
366
367 .el-icon {
368 color: #b2b2b2;
369 }
370 }
371 }
372
373 .ml16 {
374 margin-left: 16px;
375 }
376
377 .content-chart-bar {
378 height: 300px;
379 border: 1px solid #d9d9d9;
380 padding: 8px;
381 }
382
383 .table-h {
384 height: 300px !important;
385 }
386 </style>
...\ No newline at end of file ...\ No newline at end of file
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!