数字合约功能迁移
Showing
27 changed files
with
7157 additions
and
20 deletions
| ... | @@ -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 | ... | ... |
src/api/modules/dataIdentify.ts
0 → 100644
| 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 | }) |
src/api/modules/dataSmartContract.ts
0 → 100644
| 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 | }) |
| ... | @@ -363,4 +363,31 @@ a { | ... | @@ -363,4 +363,31 @@ a { |
| 363 | 363 | ||
| 364 | .mb10 { | 364 | .mb10 { |
| 365 | margin-bottom: 10px; | 365 | margin-bottom: 10px; |
| 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 | } | ||
| 366 | } | 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 |
| 51 | padding: `0px`, | 50 | class="v-content-wrap" |
| 52 | height: `${isExpanded ? contentHeight + 28 : 0}px`, | 51 | shadow="never" |
| 53 | }"> | 52 | :body-style="{ |
| 53 | padding: `0px`, | ||
| 54 | height: `${isExpanded ? contentHeight + 28 : 0}px`, | ||
| 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 | } | ... | ... |
src/router/modules/dataSmartContract.ts
0 → 100644
| 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 | ... | ... |
src/store/modules/dataSmartContract.ts
0 → 100644
| 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 | <template> | ||
| 2 | <div v-if="showTitle" class="title-row"> | ||
| 3 | <div class="h-title">策略信息</div> | ||
| 4 | <el-button v-if="!isLook" plain @click="invokeTemplate" v-preReClick>合约模板调用</el-button> | ||
| 5 | </div> | ||
| 6 | <el-table class="strategyTable" ref="strategyTableRef" v-loading="strategyDataLoading" :data="strategyData" | ||
| 7 | :height="isReport ? 'auto' : '250px'" :highlight-current-row="true" stripe tooltip-effect="light" border :span-method="arraySpanMethod"> | ||
| 8 | <el-table-column label="序号" width="56" align="center" fixed="left" :formatter="formatIndex" /> | ||
| 9 | <el-table-column prop="action" label="操作行为" :width="isReport ? 'auto' : '150px'" :min-width="isReport ? '100px' : undefined" align="left" :show-overflow-tooltip="!isReport"> | ||
| 10 | <template #header> | ||
| 11 | <span>操作行为</span> | ||
| 12 | <span style="color:red;margin-left: 2px;">*</span> | ||
| 13 | </template> | ||
| 14 | <template #default="scope"> | ||
| 15 | <el-select v-if="!isLook" v-model="scope.row['action']" placeholder="请选择" :disabled="isLook" | ||
| 16 | @change="(val) => selectOperationChange(val, scope)" clearable filterable> | ||
| 17 | <el-option | ||
| 18 | v-for="opt in actionOptionsList.filter(a => scope.row.action == a.policyName || !strategyData.some(s => s.action == a.policyName))" | ||
| 19 | :key="opt['policyName']" :label="opt['policyName']" :value="opt['policyName']" /> | ||
| 20 | </el-select> | ||
| 21 | <span v-else>{{ scope.row['action'] || '--' }}</span> | ||
| 22 | </template> | ||
| 23 | </el-table-column> | ||
| 24 | <el-table-column prop="actionEnName" label="操作行为英文名称" :width="isReport ? 'auto' : '150px'" :min-width="isReport ? '120px' : undefined" align="left" :show-overflow-tooltip="!isReport"> | ||
| 25 | <template #default="scope"> | ||
| 26 | <el-input v-if="!isLook" v-model="scope.row['actionEnName']" :disabled="true" placeholder="-"></el-input> | ||
| 27 | <span v-else>{{ scope.row['actionEnName'] || '--' }}</span> | ||
| 28 | </template> | ||
| 29 | </el-table-column> | ||
| 30 | <el-table-column prop="constraintName" label="约束条件" :width="isReport ? 'auto' : '150px'" :min-width="isReport ? '100px' : undefined" align="left" :show-overflow-tooltip="!isReport"> | ||
| 31 | <template #header> | ||
| 32 | <span>约束条件</span> | ||
| 33 | <span style="color:red;margin-left: 2px;">*</span> | ||
| 34 | </template> | ||
| 35 | <template #default="scope"> | ||
| 36 | <el-select v-if="!isLook" v-model="scope.row['constraintName']" placeholder="请选择" :disabled="isLook" | ||
| 37 | @change="(val) => selectConditionChange(val, scope)" clearable filterable> | ||
| 38 | <el-option v-for="opt in constraintOptionsList" :key="opt['policyName']" :label="opt['policyName']" | ||
| 39 | :value="opt['policyName']" /> | ||
| 40 | </el-select> | ||
| 41 | <span v-else>{{ scope.row['constraintName'] || '--' }}</span> | ||
| 42 | </template> | ||
| 43 | </el-table-column> | ||
| 44 | <el-table-column prop="constraintEnName" label="约束条件英文名称" :width="isReport ? 'auto' : '150px'" :min-width="isReport ? '120px' : undefined" align="left" :show-overflow-tooltip="!isReport"> | ||
| 45 | <template #default="scope"> | ||
| 46 | <el-input v-if="!isLook" v-model="scope.row['constraintEnName']" :disabled="true" placeholder="-"></el-input> | ||
| 47 | <span v-else>{{ scope.row['constraintEnName'] || '--' }}</span> | ||
| 48 | </template> | ||
| 49 | </el-table-column> | ||
| 50 | <el-table-column prop="constraintOperatorCode" label="运算符" :width="isReport ? 'auto' : '150px'" :min-width="isReport ? '100px' : undefined" align="left" :show-overflow-tooltip="!isReport"> | ||
| 51 | <template #header> | ||
| 52 | <span>运算符</span> | ||
| 53 | <span style="color:red;margin-left: 2px;">*</span> | ||
| 54 | </template> | ||
| 55 | <template #default="scope"> | ||
| 56 | <el-select v-if="!isLook" v-model="scope.row['constraintOperatorCode']" placeholder="请选择" :disabled="isLook" | ||
| 57 | clearable filterable @change="(val) => handleOperatorSelectChange(val, scope, 'constraintOperatorCode')"> | ||
| 58 | <el-option v-for="opt in getActualOperationList(scope)" :key="opt['value']" :label="opt['label']" | ||
| 59 | :value="opt['value']" /> | ||
| 60 | </el-select> | ||
| 61 | <span v-else>{{ scope.row['constraintOperatorName'] || '--' }}</span> | ||
| 62 | </template> | ||
| 63 | </el-table-column> | ||
| 64 | <el-table-column prop="constraintValue" label="约束值" :width="isReport ? 'auto' : '240px'" :min-width="isReport ? '160px' : undefined" align="left" :show-overflow-tooltip="!isReport"> | ||
| 65 | <template #header> | ||
| 66 | <span>约束值</span> | ||
| 67 | <span style="color:red;margin-left: 2px;">*</span> | ||
| 68 | </template> | ||
| 69 | <template #default="scope"> | ||
| 70 | <el-input v-if="!isLook" v-model="scope.row['constraintValue']" placeholder="请输入" :maxlength="200" | ||
| 71 | @change="(val) => handleOperatorSelectChange(val, scope, 'constraintValue')" clearable></el-input> | ||
| 72 | <span v-else>{{ scope.row['constraintValue'] || '--' }}</span> | ||
| 73 | </template> | ||
| 74 | </el-table-column> | ||
| 75 | <el-table-column v-if="!isLook" label="操作" width="140px" align="left" fixed="right" show-overflow-tooltip> | ||
| 76 | <template #default="scope"> | ||
| 77 | <span class="text_btn" @click="handleConditionClickAdd(scope)" v-preReClick>添加约束</span> | ||
| 78 | <el-divider direction="vertical" /> | ||
| 79 | <span class="text_btn" @click="handleConditionDelete(scope)">删除</span> | ||
| 80 | </template> | ||
| 81 | </el-table-column> | ||
| 82 | </el-table> | ||
| 83 | <div v-if="!isLook" class="row-add-btn"> | ||
| 84 | <el-button link @click="addStrategy" :icon="CirclePlus" v-preReClick>添加操作行为</el-button> | ||
| 85 | </div> | ||
| 86 | <!-- 选择合约模板对话框 --> | ||
| 87 | <Dialog_form :dialogConfigInfo="templateDialogInfo" /> | ||
| 88 | </template> | ||
| 89 | |||
| 90 | <script lang="ts" setup name="strategyTable"> | ||
| 91 | import { useValidator } from "@/hooks/useValidator"; | ||
| 92 | import { CirclePlus } from "@element-plus/icons-vue"; | ||
| 93 | import { | ||
| 94 | getValidContractTemplateList | ||
| 95 | } from "@/api/modules/dataSmartContract" | ||
| 96 | |||
| 97 | const { required } = useValidator(); | ||
| 98 | const { proxy } = getCurrentInstance() as any; | ||
| 99 | |||
| 100 | const props = defineProps({ | ||
| 101 | isLook: { //是否是查看页面,详情查看不需要展示输入框。 | ||
| 102 | type: Boolean, | ||
| 103 | default: false | ||
| 104 | }, | ||
| 105 | value: { // 是个表格数组 | ||
| 106 | type: Array<any>, | ||
| 107 | default: <any>[] | ||
| 108 | }, | ||
| 109 | showTitle: { | ||
| 110 | type: Boolean, | ||
| 111 | default: false | ||
| 112 | }, | ||
| 113 | actionOptionsList: {//策略操作行为下拉列表 | ||
| 114 | type: Array<any>, | ||
| 115 | default: [] | ||
| 116 | }, | ||
| 117 | constraintOptionsList: {//约束行为下拉列表 | ||
| 118 | type: Array<any>, | ||
| 119 | default: [] | ||
| 120 | }, | ||
| 121 | operatorOptionList: {//运算符字典下拉列表 | ||
| 122 | type: Array<any>, | ||
| 123 | default: [] | ||
| 124 | }, | ||
| 125 | isReport: { | ||
| 126 | type: Boolean, | ||
| 127 | default: false | ||
| 128 | } | ||
| 129 | }) | ||
| 130 | |||
| 131 | const getActualOperationList = (scope) => { | ||
| 132 | let val = scope.row.constraintName; | ||
| 133 | let conditionItem = val && props.constraintOptionsList.find(c => c.policyName == val); | ||
| 134 | let constraintOperatorCodes = conditionItem?.constraintOperatorCodes || []; | ||
| 135 | if (!constraintOperatorCodes?.length) { | ||
| 136 | return props.operatorOptionList; | ||
| 137 | } | ||
| 138 | let list: any = constraintOperatorCodes?.map((c, index) => { | ||
| 139 | return { | ||
| 140 | value: c, | ||
| 141 | label: conditionItem?.constraintOperatorCodesName?.[index] || c | ||
| 142 | } | ||
| 143 | }); | ||
| 144 | return list; | ||
| 145 | } | ||
| 146 | |||
| 147 | const strategyDataLoading = ref(false); | ||
| 148 | |||
| 149 | /** 策略信息结构最终值,带children层级结构 */ | ||
| 150 | const strategyValueInfo: any = ref([{ | ||
| 151 | index: 1, | ||
| 152 | action: '', | ||
| 153 | children: [{ childIndex: 1 }] | ||
| 154 | }]); | ||
| 155 | |||
| 156 | /** 将数据库存储的值转化为该组件接收的树形结构 */ | ||
| 157 | const transferValueToNew = (val) => { | ||
| 158 | let detailPolicyListValue: any[] = [] | ||
| 159 | val?.forEach((p, index) => { | ||
| 160 | let lastItem = detailPolicyListValue?.[detailPolicyListValue.length - 1]; | ||
| 161 | let childInfo = Object.assign({}, p); | ||
| 162 | delete childInfo.children; //删掉冗余信息,否则后续修改会覆盖正确的值 | ||
| 163 | delete childInfo.action; | ||
| 164 | delete childInfo.actionEnName; | ||
| 165 | if (!lastItem || lastItem.action != p.action) { | ||
| 166 | detailPolicyListValue.push(Object.assign({ | ||
| 167 | index: detailPolicyListValue.length + 1, | ||
| 168 | }, p, { | ||
| 169 | children: [Object.assign({ childIndex: 1 }, childInfo)] | ||
| 170 | })) | ||
| 171 | } else { | ||
| 172 | lastItem.children.push(Object.assign({ childIndex: lastItem.children?.length + 1 }, childInfo)); | ||
| 173 | } | ||
| 174 | }) | ||
| 175 | return detailPolicyListValue; | ||
| 176 | } | ||
| 177 | |||
| 178 | watch(() => props.value, (val) => { | ||
| 179 | strategyValueInfo.value = transferValueToNew(val); | ||
| 180 | }, { | ||
| 181 | deep: true, | ||
| 182 | immediate: true | ||
| 183 | }) | ||
| 184 | |||
| 185 | /** 策略信息表格数据 */ | ||
| 186 | const strategyData = computed(() => { | ||
| 187 | let v: any = []; | ||
| 188 | strategyValueInfo.value.forEach(s => { | ||
| 189 | s.children?.forEach(sc => { | ||
| 190 | v.push(Object.assign({}, { | ||
| 191 | guid: sc.guid, | ||
| 192 | action: s.action, | ||
| 193 | actionEnName: s.actionEnName, | ||
| 194 | index: s.index, | ||
| 195 | orderNum: s.orderNum | ||
| 196 | }, sc)); | ||
| 197 | }) | ||
| 198 | }) | ||
| 199 | return v; | ||
| 200 | }); | ||
| 201 | |||
| 202 | /** 操作行为下拉框改变,带出英文名称等信息 */ | ||
| 203 | const selectOperationChange = (val, scope) => { | ||
| 204 | let index = scope.row.index; | ||
| 205 | let sv = strategyValueInfo.value.find(s => s.index == index); | ||
| 206 | sv && (sv.actionEnName = props.actionOptionsList.find(o => o.policyName == val)?.policyEnName); | ||
| 207 | sv && (sv.action = val); | ||
| 208 | } | ||
| 209 | |||
| 210 | /** 约束条件下拉框改变,带出英文名称 */ | ||
| 211 | const selectConditionChange = (val, scope) => { | ||
| 212 | let index = scope.row.index; | ||
| 213 | let sv = strategyValueInfo.value.find(s => s.index == index); | ||
| 214 | let svChild = sv.children?.find(c => c.childIndex == scope.row.childIndex); | ||
| 215 | svChild && (svChild.constraintEnName = props.constraintOptionsList.find(o => o.policyName == val)?.policyEnName); | ||
| 216 | svChild && (svChild.constraintName = val); | ||
| 217 | } | ||
| 218 | |||
| 219 | const handleOperatorSelectChange = (val, scope, field) => { | ||
| 220 | let index = scope.row.index; | ||
| 221 | let sv = strategyValueInfo.value.find(s => s.index == index); | ||
| 222 | let svChild = sv.children?.find(c => c.childIndex == scope.row.childIndex); | ||
| 223 | svChild && (svChild[field] = val); | ||
| 224 | } | ||
| 225 | |||
| 226 | /** 添加策略信息的操作行为行 */ | ||
| 227 | const addStrategy = () => { | ||
| 228 | let len = strategyValueInfo.value.length; | ||
| 229 | if (len == props.actionOptionsList?.length) { | ||
| 230 | proxy.$ElMessage.warning('暂无可添加的操作行为!'); | ||
| 231 | return; | ||
| 232 | } | ||
| 233 | let lastIndex = strategyValueInfo.value.at(-1)?.index || 0; | ||
| 234 | strategyValueInfo.value.push({ | ||
| 235 | index: lastIndex + 1, | ||
| 236 | action: '', | ||
| 237 | children: [{ childIndex: 1 }] | ||
| 238 | }) | ||
| 239 | } | ||
| 240 | |||
| 241 | /** 添加约束条件 */ | ||
| 242 | const handleConditionClickAdd = (scope) => { | ||
| 243 | /** 根据index值进行添加删除 */ | ||
| 244 | let index = scope.row.index; | ||
| 245 | let sv = strategyValueInfo.value.find(s => s.index == index); | ||
| 246 | if (sv) { | ||
| 247 | let childIndex = scope.row.childIndex; | ||
| 248 | let lastIndex = sv.children.at(-1)?.childIndex || 0; | ||
| 249 | sv.children.splice(childIndex, 0, { childIndex: lastIndex + 1 }) | ||
| 250 | } | ||
| 251 | } | ||
| 252 | |||
| 253 | const handleConditionDelete = (scope) => { | ||
| 254 | let index = scope.row.index; | ||
| 255 | let sv = strategyValueInfo.value.find(s => s.index == index); | ||
| 256 | if (!sv) { | ||
| 257 | return; | ||
| 258 | } | ||
| 259 | if (sv?.children?.length > 1) { | ||
| 260 | //删除约束条件。 | ||
| 261 | proxy.$openMessageBox("确定要删除该约束条件吗?", () => { | ||
| 262 | let childIndex = scope.row.childIndex; | ||
| 263 | let delIndex = sv.children.findIndex(c => c.childIndex == childIndex); | ||
| 264 | delIndex > -1 && sv.children.splice(delIndex, 1); | ||
| 265 | proxy.$ElMessage.success('删除成功'); | ||
| 266 | }, () => { | ||
| 267 | proxy.$ElMessage.info("已取消删除"); | ||
| 268 | }) | ||
| 269 | } else { | ||
| 270 | //同步删除操作行为 | ||
| 271 | proxy.$openMessageBox("确定要删除该操作行为和约束条件吗?", () => { | ||
| 272 | let index = scope.row.index; | ||
| 273 | strategyValueInfo.value.splice(index - 1, 1); | ||
| 274 | proxy.$ElMessage.success('删除成功'); | ||
| 275 | }, () => { | ||
| 276 | proxy.$ElMessage.info("已取消删除"); | ||
| 277 | }) | ||
| 278 | } | ||
| 279 | } | ||
| 280 | |||
| 281 | // 计算合并后的序号 | ||
| 282 | const mergedIndexes = computed(() => { | ||
| 283 | let index = 1; | ||
| 284 | const mergedIndexes: any[] = []; | ||
| 285 | |||
| 286 | for (let i = 0; i < strategyData.value.length; i++) { | ||
| 287 | if (i === 0 || strategyData.value[i - 1]['action'] != strategyData.value[i]['action'] || strategyData.value[i - 1]['index'] != strategyData.value[i]['index']) { | ||
| 288 | // 新合并组开始 | ||
| 289 | mergedIndexes.push(index); | ||
| 290 | index++; | ||
| 291 | } else { | ||
| 292 | // 同一合并组 | ||
| 293 | mergedIndexes.push(0); // 0表示不显示序号 | ||
| 294 | } | ||
| 295 | } | ||
| 296 | |||
| 297 | return mergedIndexes; | ||
| 298 | }); | ||
| 299 | |||
| 300 | // 序号格式化 | ||
| 301 | const formatIndex = (row, column, cellValue, index) => { | ||
| 302 | return <string>mergedIndexes.value[index] || ''; | ||
| 303 | }; | ||
| 304 | |||
| 305 | const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => { | ||
| 306 | if (columnIndex > 2) { | ||
| 307 | return [1, 1]; | ||
| 308 | } | ||
| 309 | |||
| 310 | // 查找当前字段值相同的连续行 | ||
| 311 | let startRow = rowIndex; | ||
| 312 | let endRow = rowIndex; | ||
| 313 | let field = column.field; | ||
| 314 | // 向前查找 | ||
| 315 | while (startRow > 0 && strategyData.value[startRow - 1][field] === strategyData.value[rowIndex][field] && strategyData.value[startRow - 1]['index'] == strategyData.value[rowIndex]['index']) { | ||
| 316 | startRow--; | ||
| 317 | } | ||
| 318 | |||
| 319 | // 向后查找 | ||
| 320 | while (endRow < strategyData.value.length - 1 && strategyData.value[endRow + 1][field] === strategyData.value[rowIndex][field] && strategyData.value[endRow + 1]['index'] === strategyData.value[rowIndex]['index']) { | ||
| 321 | endRow++; | ||
| 322 | } | ||
| 323 | |||
| 324 | // 如果当前行不是相同值组的起始行,则不显示 | ||
| 325 | if (startRow !== rowIndex) { | ||
| 326 | return [0, 0]; | ||
| 327 | } | ||
| 328 | |||
| 329 | // 返回合并的行数 | ||
| 330 | const rowspan = endRow - startRow + 1; | ||
| 331 | return [rowspan, 1]; | ||
| 332 | } | ||
| 333 | |||
| 334 | /** 弹出模板选择对话框 */ | ||
| 335 | const invokeTemplate = () => { | ||
| 336 | /** 调用获取启用的模板列表接口,如果返回null则提示没有可调用的模板。 */ | ||
| 337 | getValidContractTemplateList().then((res: any) => { | ||
| 338 | if (res?.code == proxy.$passCode) { | ||
| 339 | const listData = res.data || []; | ||
| 340 | if (!listData?.length) { | ||
| 341 | proxy.$ElMessage.warning('当前没有可调用的合约模板'); | ||
| 342 | return; | ||
| 343 | } | ||
| 344 | templateFormItems.value[0].options = listData; | ||
| 345 | templateFormItems.value[0].default = ''; | ||
| 346 | templateDialogInfo.value.visible = true; | ||
| 347 | } else { | ||
| 348 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 349 | } | ||
| 350 | }) | ||
| 351 | } | ||
| 352 | |||
| 353 | const templateFormItems = ref([{ | ||
| 354 | type: 'select', | ||
| 355 | label: '合约模板名称', | ||
| 356 | field: 'guid', | ||
| 357 | default: '', | ||
| 358 | block: true, | ||
| 359 | placeholder: '请选择', | ||
| 360 | options: [], | ||
| 361 | props: { | ||
| 362 | value: 'guid', | ||
| 363 | label: 'templateName' | ||
| 364 | }, | ||
| 365 | filterable: true, | ||
| 366 | clearable: true, | ||
| 367 | required: true | ||
| 368 | }]); | ||
| 369 | |||
| 370 | const templateFormRules = ref({ | ||
| 371 | guid: [required("请选择合约模板名称")], | ||
| 372 | }); | ||
| 373 | |||
| 374 | const templateDialogInfo = ref({ | ||
| 375 | visible: false, | ||
| 376 | size: 480, | ||
| 377 | title: "合约模板调用", | ||
| 378 | type: 'edit', | ||
| 379 | formInfo: { | ||
| 380 | id: 'copy-form', | ||
| 381 | items: templateFormItems.value, | ||
| 382 | rules: templateFormRules.value | ||
| 383 | }, | ||
| 384 | btns: { | ||
| 385 | submit: (btn, info) => { | ||
| 386 | templateDialogInfo.value.visible = false; | ||
| 387 | //将选择的值带入表格 TODO,跟经理确认是全量覆盖,还是保留操作行为不同的行。暂时先做成全量覆盖吧。 | ||
| 388 | let item: any = templateFormItems.value[0].options?.find((i: any) => i.guid == info.guid); | ||
| 389 | strategyValueInfo.value = transferValueToNew(item?.policyRSVOS || []); | ||
| 390 | }, | ||
| 391 | cancel: () => { | ||
| 392 | templateDialogInfo.value.visible = false; | ||
| 393 | } | ||
| 394 | }, | ||
| 395 | submitBtnLoading: false | ||
| 396 | }); | ||
| 397 | |||
| 398 | const validateValue = () => { | ||
| 399 | for (const d of strategyData.value) { | ||
| 400 | if (!d.action) { | ||
| 401 | proxy.$ElMessage.error('操作行为必填,请填写完整'); | ||
| 402 | return false; | ||
| 403 | } | ||
| 404 | if (!d.constraintName) { | ||
| 405 | proxy.$ElMessage.error('约束条件必填,请填写完整'); | ||
| 406 | return false; | ||
| 407 | } | ||
| 408 | if (!d.constraintOperatorCode) { | ||
| 409 | proxy.$ElMessage.error('运算符必填,请填写完整'); | ||
| 410 | return false; | ||
| 411 | } | ||
| 412 | if (!d.constraintValue) { | ||
| 413 | proxy.$ElMessage.error('约束值必填,请填写完整'); | ||
| 414 | return false; | ||
| 415 | } | ||
| 416 | } | ||
| 417 | return true; | ||
| 418 | } | ||
| 419 | |||
| 420 | defineExpose({ | ||
| 421 | strategyData, | ||
| 422 | validateValue | ||
| 423 | }) | ||
| 424 | </script> | ||
| 425 | |||
| 426 | <style lang="scss" scoped> | ||
| 427 | .row-add-btn { | ||
| 428 | .el-button--default { | ||
| 429 | padding: 4px 0px; | ||
| 430 | margin-top: 4px; | ||
| 431 | } | ||
| 432 | |||
| 433 | :deep(.el-icon) { | ||
| 434 | width: 16px; | ||
| 435 | height: 16px; | ||
| 436 | |||
| 437 | svg { | ||
| 438 | width: 16px; | ||
| 439 | height: 16px; | ||
| 440 | } | ||
| 441 | } | ||
| 442 | } | ||
| 443 | |||
| 444 | .title-row { | ||
| 445 | display: flex; | ||
| 446 | flex-direction: row; | ||
| 447 | height: 44px; | ||
| 448 | align-items: center; | ||
| 449 | |||
| 450 | .el-button { | ||
| 451 | color: var(--el-button-hover-text-color); | ||
| 452 | border-color: var(--el-button-hover-border-color); | ||
| 453 | } | ||
| 454 | } | ||
| 455 | |||
| 456 | .h-title { | ||
| 457 | font-size: 14px; | ||
| 458 | color: #212121; | ||
| 459 | font-weight: 600; | ||
| 460 | margin-right: 8px; | ||
| 461 | } | ||
| 462 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | <route lang="yaml"> | ||
| 2 | name: contractLogManage | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="contractLogManage"> | ||
| 6 | import TableTools from "@/components/Tools/table_tools.vue"; | ||
| 7 | import { commonPageConfig, TableColumnWidth } from "@/utils/enum"; | ||
| 8 | import { | ||
| 9 | getContractOperationLog, | ||
| 10 | getContractOperationLogDetail, | ||
| 11 | getContractProcessLog, | ||
| 12 | getContractProcessLogDetail, | ||
| 13 | getContractNegoPlicyByVersion | ||
| 14 | } from "@/api/modules/dataSmartContract"; | ||
| 15 | import StrategyTable from './components/strategyTable.vue'; | ||
| 16 | |||
| 17 | const { proxy } = getCurrentInstance() as any; | ||
| 18 | |||
| 19 | const activeTabName = ref('operation'); | ||
| 20 | |||
| 21 | /** 操作主体下拉列表 */ | ||
| 22 | // const operationEntityListData: any = ref([]); | ||
| 23 | |||
| 24 | /** 操作记录筛选框 */ | ||
| 25 | const opSearchItemList = ref([{ | ||
| 26 | type: 'date-time', | ||
| 27 | label: '', | ||
| 28 | field: 'operatorTime', | ||
| 29 | default: [], | ||
| 30 | defaultStartTime: new Date(2000, 1, 1, 0, 0, 0), | ||
| 31 | defaultEndTime: new Date(2000, 1, 1, 23, 59, 59), | ||
| 32 | startPlaceholder: '操作开始时间', | ||
| 33 | endPlaceholder: '操作结束时间', | ||
| 34 | clearable: true | ||
| 35 | }, { | ||
| 36 | type: 'input', | ||
| 37 | label: '', | ||
| 38 | field: 'operationEntityName', | ||
| 39 | default: '', | ||
| 40 | placeholder: '操作主体', | ||
| 41 | // props: { | ||
| 42 | // value: 'tenantGuid', | ||
| 43 | // label: 'tenantName' | ||
| 44 | // }, | ||
| 45 | // options: operationEntityListData.value, | ||
| 46 | //filterable: true, | ||
| 47 | maxlength: 50, | ||
| 48 | clearable: true | ||
| 49 | }, { | ||
| 50 | type: "input", | ||
| 51 | label: "", | ||
| 52 | field: "contractName", | ||
| 53 | default: "", | ||
| 54 | placeholder: "合约名称", | ||
| 55 | maxlength: 50, | ||
| 56 | clearable: true, | ||
| 57 | },]); | ||
| 58 | |||
| 59 | /** 过程记录筛选框 */ | ||
| 60 | const processTableSearchItemList = ref([{ | ||
| 61 | type: 'date-time', | ||
| 62 | label: '', | ||
| 63 | field: 'operatorTime', | ||
| 64 | default: [], | ||
| 65 | defaultStartTime: new Date(2000, 1, 1, 0, 0, 0), | ||
| 66 | defaultEndTime: new Date(2000, 1, 1, 23, 59, 59), | ||
| 67 | startPlaceholder: '操作开始时间', | ||
| 68 | endPlaceholder: '操作结束时间', | ||
| 69 | clearable: true | ||
| 70 | }, { | ||
| 71 | type: 'select', | ||
| 72 | label: '', | ||
| 73 | field: 'executionProcess', | ||
| 74 | default: '', | ||
| 75 | placeholder: '执行环节', | ||
| 76 | props: { | ||
| 77 | value: 'value', | ||
| 78 | label: 'label' | ||
| 79 | }, | ||
| 80 | options: [{ | ||
| 81 | value: '策略解析', | ||
| 82 | }, { | ||
| 83 | value: '行为校验', | ||
| 84 | }, { | ||
| 85 | value: '操作执行', | ||
| 86 | }], | ||
| 87 | filterable: true, | ||
| 88 | clearable: true | ||
| 89 | }, { | ||
| 90 | type: "input", | ||
| 91 | label: "", | ||
| 92 | field: "executionEntityName", | ||
| 93 | default: "", | ||
| 94 | placeholder: "执行节点名称", | ||
| 95 | maxlength: 50, | ||
| 96 | clearable: true, | ||
| 97 | },]); | ||
| 98 | |||
| 99 | /** ------------------ 操作记录 ----------------------- */ | ||
| 100 | const opPage = ref({ | ||
| 101 | ...commonPageConfig, | ||
| 102 | contractName: '', | ||
| 103 | operatorTime: [], | ||
| 104 | operationEntityName: '' | ||
| 105 | }); | ||
| 106 | |||
| 107 | const currTableData: any = ref({}); | ||
| 108 | |||
| 109 | const opTableInfo = ref({ | ||
| 110 | id: "op-table", | ||
| 111 | rowKey: 'guid', | ||
| 112 | fields: [ | ||
| 113 | { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" }, | ||
| 114 | { label: "操作编号", field: "operationId", width: 140 }, | ||
| 115 | { label: "操作时间", field: "operationTime", width: 170 }, | ||
| 116 | { label: "操作主体", field: "operationEntityName", width: 220 }, | ||
| 117 | { label: "操作合约名称", field: "contractName", width: 160 }, | ||
| 118 | { label: "操作合约标识", field: "contractId", width: 355 }, | ||
| 119 | { label: "操作类型", field: "operationType", width: 120 }, | ||
| 120 | ], | ||
| 121 | data: [], | ||
| 122 | showPage: true, | ||
| 123 | page: { | ||
| 124 | type: "normal", | ||
| 125 | rows: 0, | ||
| 126 | ...opPage.value, | ||
| 127 | }, | ||
| 128 | actionInfo: { | ||
| 129 | label: "操作", | ||
| 130 | type: "btn", | ||
| 131 | width: 80, | ||
| 132 | btns: [{ | ||
| 133 | value: 'view', label: '查看', click: (scope) => { | ||
| 134 | currTableData.value = scope.row; | ||
| 135 | detailDialogInfo.value.visible = true; | ||
| 136 | detailDialogInfo.value.contentLoading = true; | ||
| 137 | getContractOperationLogDetail(scope.row.guid).then((res: any) => { | ||
| 138 | detailDialogInfo.value.contentLoading = false; | ||
| 139 | if (res?.code == proxy.$passCode) { | ||
| 140 | opDetailInfo.value = res.data || {}; | ||
| 141 | } else { | ||
| 142 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 143 | } | ||
| 144 | }) | ||
| 145 | } | ||
| 146 | }] | ||
| 147 | }, | ||
| 148 | loading: false | ||
| 149 | }); | ||
| 150 | |||
| 151 | const toTableSearch = (val: any, clear: boolean = false) => { | ||
| 152 | if (clear) { | ||
| 153 | opSearchItemList.value.map((item) => (item.default = "")); | ||
| 154 | opPage.value.contractName = ''; | ||
| 155 | opPage.value.operationEntityName = ''; | ||
| 156 | opPage.value.operatorTime = []; | ||
| 157 | } else { | ||
| 158 | opPage.value.contractName = val.contractName; | ||
| 159 | opPage.value.operationEntityName = val.operationEntityName; | ||
| 160 | opPage.value.operatorTime = val.operatorTime; | ||
| 161 | } | ||
| 162 | getOpTableData(); | ||
| 163 | }; | ||
| 164 | |||
| 165 | const getOpTableData = () => { | ||
| 166 | opTableInfo.value.loading = true | ||
| 167 | getContractOperationLog({ | ||
| 168 | pageIndex: opPage.value.curr, | ||
| 169 | pageSize: opPage.value.limit, | ||
| 170 | contractName: opPage.value.contractName, | ||
| 171 | operationEntityName: opPage.value.operationEntityName, | ||
| 172 | operationTimeStart: opPage.value.operatorTime?.[0], | ||
| 173 | operationTimeEnd: opPage.value.operatorTime?.[1] | ||
| 174 | }).then((res: any) => { | ||
| 175 | opTableInfo.value.data = []; | ||
| 176 | if (res?.code == proxy.$passCode) { | ||
| 177 | const data = res.data || {}; | ||
| 178 | opTableInfo.value.loading = false | ||
| 179 | opTableInfo.value.data = data.records || [] | ||
| 180 | opTableInfo.value.page.limit = data.pageSize | ||
| 181 | opTableInfo.value.page.curr = data.pageIndex | ||
| 182 | opTableInfo.value.page.rows = data.totalRows | ||
| 183 | } else { | ||
| 184 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 185 | opTableInfo.value.loading = false | ||
| 186 | } | ||
| 187 | }).catch(() => { | ||
| 188 | opTableInfo.value.loading = false | ||
| 189 | }) | ||
| 190 | } | ||
| 191 | |||
| 192 | const opTablePageChange = (info) => { | ||
| 193 | opPage.value.curr = Number(info.curr); | ||
| 194 | opPage.value.limit = Number(info.limit); | ||
| 195 | opTableInfo.value.page.curr = opPage.value.curr; | ||
| 196 | opTableInfo.value.page.limit = opPage.value.limit; | ||
| 197 | getOpTableData(); | ||
| 198 | }; | ||
| 199 | |||
| 200 | /** ------------------ 过程记录 ----------------------- */ | ||
| 201 | const processPage = ref({ | ||
| 202 | ...commonPageConfig, | ||
| 203 | executionEntityName: '', | ||
| 204 | operatorTime: [], | ||
| 205 | executionProcess: '' | ||
| 206 | }); | ||
| 207 | |||
| 208 | const processTableInfo = ref({ | ||
| 209 | id: "process-table", | ||
| 210 | rowKey: 'guid', | ||
| 211 | fields: [ | ||
| 212 | { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" }, | ||
| 213 | { label: "执行编号", field: "operationId", width: 140 }, | ||
| 214 | { label: "执行时间", field: "operationTime", width: 170 }, | ||
| 215 | { label: "执行节点名称", field: "executionEntityName", width: 220 }, | ||
| 216 | { label: "执行节点标识", field: "executionEntityId", width: 175 }, | ||
| 217 | { label: "执行合约名称", field: "contractName", width: 160 }, | ||
| 218 | { label: "执行环节", field: "executionProcess", width: 120 }, | ||
| 219 | ], | ||
| 220 | data: [], | ||
| 221 | showPage: true, | ||
| 222 | page: { | ||
| 223 | type: "normal", | ||
| 224 | rows: 0, | ||
| 225 | ...processPage.value, | ||
| 226 | }, | ||
| 227 | actionInfo: { | ||
| 228 | label: "操作", | ||
| 229 | type: "btn", | ||
| 230 | width: 80, | ||
| 231 | btns: [{ | ||
| 232 | value: 'view', label: '查看', click: (scope) => { | ||
| 233 | currTableData.value = scope.row; | ||
| 234 | processDetailDialogInfo.value.visible = true; | ||
| 235 | processDetailDialogInfo.value.contentLoading = true; | ||
| 236 | getContractProcessLogDetail(scope.row.guid).then((res: any) => { | ||
| 237 | processDetailDialogInfo.value.contentLoading = false; | ||
| 238 | if (res?.code == proxy.$passCode) { | ||
| 239 | processDetailInfo.value = res.data || {}; | ||
| 240 | execContractTableInfo.value.data = processDetailInfo.value.policys || []; | ||
| 241 | } else { | ||
| 242 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 243 | } | ||
| 244 | }) | ||
| 245 | } | ||
| 246 | }] | ||
| 247 | }, | ||
| 248 | loading: false | ||
| 249 | }); | ||
| 250 | |||
| 251 | const toProcessTableSearch = (val: any, clear: boolean = false) => { | ||
| 252 | if (clear) { | ||
| 253 | processTableSearchItemList.value.map((item) => (item.default = "")); | ||
| 254 | processPage.value.executionEntityName = ''; | ||
| 255 | processPage.value.executionProcess = ''; | ||
| 256 | processPage.value.operatorTime = []; | ||
| 257 | } else { | ||
| 258 | processPage.value.executionEntityName = val.executionEntityName; | ||
| 259 | processPage.value.executionProcess = val.executionProcess; | ||
| 260 | processPage.value.operatorTime = val.operatorTime; | ||
| 261 | } | ||
| 262 | getProcessTableData(); | ||
| 263 | }; | ||
| 264 | |||
| 265 | const getProcessTableData = () => { | ||
| 266 | processTableInfo.value.loading = true | ||
| 267 | getContractProcessLog({ | ||
| 268 | pageIndex: processPage.value.curr, | ||
| 269 | pageSize: processPage.value.limit, | ||
| 270 | executionEntityName: processPage.value.executionEntityName, | ||
| 271 | executionProcess: processPage.value.executionProcess, | ||
| 272 | operationTimeStart: processPage.value.operatorTime?.[0], | ||
| 273 | operationTimeEnd: processPage.value.operatorTime?.[1] | ||
| 274 | }).then((res: any) => { | ||
| 275 | processTableInfo.value.data = []; | ||
| 276 | if (res?.code == proxy.$passCode) { | ||
| 277 | const data = res.data || {}; | ||
| 278 | processTableInfo.value.loading = false | ||
| 279 | processTableInfo.value.data = data.records || [] | ||
| 280 | processTableInfo.value.page.limit = data.pageSize | ||
| 281 | processTableInfo.value.page.curr = data.pageIndex | ||
| 282 | processTableInfo.value.page.rows = data.totalRows | ||
| 283 | } else { | ||
| 284 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 285 | processTableInfo.value.loading = false | ||
| 286 | } | ||
| 287 | }).catch(() => { | ||
| 288 | processTableInfo.value.loading = false | ||
| 289 | }) | ||
| 290 | } | ||
| 291 | |||
| 292 | const processTablePageChange = (info) => { | ||
| 293 | processPage.value.curr = Number(info.curr); | ||
| 294 | processPage.value.limit = Number(info.limit); | ||
| 295 | processTableInfo.value.page.curr = processPage.value.curr; | ||
| 296 | processTableInfo.value.page.limit = processPage.value.limit; | ||
| 297 | getProcessTableData(); | ||
| 298 | }; | ||
| 299 | |||
| 300 | onBeforeMount(() => { | ||
| 301 | toTableSearch({}); | ||
| 302 | toProcessTableSearch({}); | ||
| 303 | }) | ||
| 304 | |||
| 305 | /** 操作记录详情对话框 */ | ||
| 306 | const detailDialogInfo = ref({ | ||
| 307 | visible: false, | ||
| 308 | size: 855, | ||
| 309 | direction: "column", | ||
| 310 | header: { | ||
| 311 | title: "查看操作记录", | ||
| 312 | }, | ||
| 313 | type: '', | ||
| 314 | contents: [], | ||
| 315 | footer: { | ||
| 316 | show: false | ||
| 317 | }, | ||
| 318 | contentLoading: false, | ||
| 319 | }); | ||
| 320 | |||
| 321 | /** 查看操作记录详情 */ | ||
| 322 | const opDetailInfo: any = ref({}); | ||
| 323 | |||
| 324 | const handleDialogBtnClick = (btn) => { | ||
| 325 | if (btn.value == 'cancel') { | ||
| 326 | detailDialogInfo.value.visible = false; | ||
| 327 | } | ||
| 328 | } | ||
| 329 | |||
| 330 | /** 查看操作记录详情对话框 */ | ||
| 331 | const versionDetailDialogInfo = ref({ | ||
| 332 | visible: false, | ||
| 333 | size: 800, | ||
| 334 | direction: "column", | ||
| 335 | header: { | ||
| 336 | title: "查看版本详情", | ||
| 337 | }, | ||
| 338 | type: '', | ||
| 339 | contents: [], | ||
| 340 | footer: { | ||
| 341 | show: false | ||
| 342 | }, | ||
| 343 | contentLoading: false, | ||
| 344 | }); | ||
| 345 | |||
| 346 | /** 查看协商策略版本详情 */ | ||
| 347 | const versionDetail: any = ref([]); | ||
| 348 | |||
| 349 | const handleVersionDialogBtnClick = (btn) => { | ||
| 350 | if (btn.value == 'cancel') { | ||
| 351 | versionDetailDialogInfo.value.visible = false; | ||
| 352 | } | ||
| 353 | } | ||
| 354 | |||
| 355 | /** 店家查看协商版本 */ | ||
| 356 | const clickVersion = (child) => { | ||
| 357 | versionDetailDialogInfo.value.visible = true; | ||
| 358 | versionDetailDialogInfo.value.header.title = '查看版本详情' + '(' + child.version + ')'; | ||
| 359 | versionDetailDialogInfo.value.contentLoading = true; | ||
| 360 | getContractNegoPlicyByVersion({ | ||
| 361 | guid: currTableData.value.contractGuid, | ||
| 362 | version: child.version | ||
| 363 | }).then((res: any) => { | ||
| 364 | versionDetailDialogInfo.value.contentLoading = false; | ||
| 365 | if (res?.code == proxy.$passCode) { | ||
| 366 | const data = res.data || []; | ||
| 367 | versionDetail.value = data; | ||
| 368 | } else { | ||
| 369 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 370 | } | ||
| 371 | }) | ||
| 372 | } | ||
| 373 | |||
| 374 | /** 操作记录详情对话框 */ | ||
| 375 | const processDetailDialogInfo = ref({ | ||
| 376 | visible: false, | ||
| 377 | size: 855, | ||
| 378 | direction: "column", | ||
| 379 | header: { | ||
| 380 | title: "查看过程记录", | ||
| 381 | }, | ||
| 382 | type: '', | ||
| 383 | contents: [], | ||
| 384 | footer: { | ||
| 385 | show: false | ||
| 386 | }, | ||
| 387 | contentLoading: false, | ||
| 388 | }); | ||
| 389 | |||
| 390 | /** 查看操作记录详情 */ | ||
| 391 | const processDetailInfo: any = ref({}); | ||
| 392 | |||
| 393 | const handleProcessDialogBtnClick = (btn) => { | ||
| 394 | if (btn.value == 'cancel') { | ||
| 395 | processDetailDialogInfo.value.visible = false; | ||
| 396 | } | ||
| 397 | } | ||
| 398 | |||
| 399 | const execContractTableInfo = ref({ | ||
| 400 | id: "exec-contract-table", | ||
| 401 | height: '214px', | ||
| 402 | fields: <any[]>[ | ||
| 403 | { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" }, | ||
| 404 | { label: "策略id", field: "strategyId", width: 260 }, | ||
| 405 | { label: "操作行为", field: "action", width: 120 }, | ||
| 406 | { label: "操作行为英文名称", field: "actionEnName", width: 140 }, | ||
| 407 | { label: "约束条件", field: "constraintName", width: 120 }, | ||
| 408 | { label: "约束条件英文名称", field: "constraintEnName", width: 140 }, | ||
| 409 | { label: "约束条件运算符", field: "constraintOperatorName", width: 140 }, | ||
| 410 | { label: "约束条件值", field: "constraintValue", width: 150 }, | ||
| 411 | { label: "执行结果", field: "result", width: 130 }, | ||
| 412 | // { label: "上报时间", field: "reportingTime", width: 170 }, | ||
| 413 | ], | ||
| 414 | data: [], | ||
| 415 | showPage: false, | ||
| 416 | actionInfo: { | ||
| 417 | show: false | ||
| 418 | }, | ||
| 419 | loading: false | ||
| 420 | }); | ||
| 421 | |||
| 422 | </script> | ||
| 423 | |||
| 424 | <template> | ||
| 425 | <el-tabs v-model="activeTabName" class="log-tabs"> | ||
| 426 | <el-tab-pane label="操作记录" name="operation"> | ||
| 427 | <div class="table_tool_wrap"> | ||
| 428 | <TableTools :searchItems="opSearchItemList" :init="false" searchId="op-table-search" @search="toTableSearch" /> | ||
| 429 | </div> | ||
| 430 | <div class="table_panel_wrap"> | ||
| 431 | <Table :tableInfo="opTableInfo" @tablePageChange="opTablePageChange" /> | ||
| 432 | </div> | ||
| 433 | </el-tab-pane> | ||
| 434 | <el-tab-pane label="过程记录" name="process"> | ||
| 435 | <div class="table_tool_wrap"> | ||
| 436 | <TableTools :searchItems="processTableSearchItemList" :init="false" searchId="process-table-search" | ||
| 437 | @search="toProcessTableSearch" /> | ||
| 438 | </div> | ||
| 439 | <div class="table_panel_wrap"> | ||
| 440 | <Table :tableInfo="processTableInfo" @tablePageChange="processTablePageChange" /> | ||
| 441 | </div> | ||
| 442 | </el-tab-pane> | ||
| 443 | <Dialog ref="dialogRef" :dialogInfo="detailDialogInfo" class="log-table-detail" @btnClick="handleDialogBtnClick"> | ||
| 444 | <template #extra-content> | ||
| 445 | <div class="main-content" v-loading="detailDialogInfo.contentLoading"> | ||
| 446 | <div class="list_panel"> | ||
| 447 | <div class="list_item is_block"> | ||
| 448 | <span class="item_label">操作类型:</span> | ||
| 449 | <span class="item_value">{{ opDetailInfo?.operationType || '--' }}</span> | ||
| 450 | </div> | ||
| 451 | <div class="list_item"> | ||
| 452 | <span class="item_label">合约标识:</span> | ||
| 453 | <span class="item_value"><ellipsis-tooltip :content="opDetailInfo?.contractId || '--'" | ||
| 454 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'contractId'"></ellipsis-tooltip></span> | ||
| 455 | </div> | ||
| 456 | <div class="list_item"> | ||
| 457 | <span class="item_label">合约名称:</span> | ||
| 458 | <span class="item_value"><ellipsis-tooltip :content="opDetailInfo?.contractName || '--'" | ||
| 459 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'contractName'"></ellipsis-tooltip></span> | ||
| 460 | </div> | ||
| 461 | <div class="list_item"> | ||
| 462 | <span class="item_label">操作主体标识:</span> | ||
| 463 | <span class="item_value"><ellipsis-tooltip :content="opDetailInfo?.operationEntityId || '--'" | ||
| 464 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'operationEntityId'"></ellipsis-tooltip></span> | ||
| 465 | </div> | ||
| 466 | <div class="list_item"> | ||
| 467 | <span class="item_label">操作主体名称:</span> | ||
| 468 | <span class="item_value"><ellipsis-tooltip :content="opDetailInfo?.operationEntityName || '--'" | ||
| 469 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'operationEntityName'"></ellipsis-tooltip></span> | ||
| 470 | </div> | ||
| 471 | <div class="list_item is_block"> | ||
| 472 | <span class="item_label">操作时间:</span> | ||
| 473 | <span class="item_value">{{ opDetailInfo?.operationTime || '--' }}</span> | ||
| 474 | </div> | ||
| 475 | <div class="list_item is_block"> | ||
| 476 | <span class="item_label">操作内容:</span> | ||
| 477 | <span class="item_value">修改前<span class="link" | ||
| 478 | @click="clickVersion(opDetailInfo.operationContent?.[0])">{{ | ||
| 479 | opDetailInfo.operationContent?.[0]?.version || '--' }}</span> | ||
| 480 | <span class="item_value" style="display: block;padding-left: 0px;">修改后<span class="link" | ||
| 481 | @click="clickVersion(opDetailInfo.operationContent?.[1])">{{ | ||
| 482 | opDetailInfo.operationContent?.[1]?.version || '--' }}</span></span></span> | ||
| 483 | </div> | ||
| 484 | </div> | ||
| 485 | </div> | ||
| 486 | </template> | ||
| 487 | </Dialog> | ||
| 488 | |||
| 489 | <Dialog ref="processDialogRef" :dialogInfo="processDetailDialogInfo" class="log-process-detail" | ||
| 490 | @btnClick="handleProcessDialogBtnClick"> | ||
| 491 | <template #extra-content> | ||
| 492 | <div class="main-content" v-loading="processDetailDialogInfo.contentLoading"> | ||
| 493 | <div class="list_panel"> | ||
| 494 | <div class="list_item"> | ||
| 495 | <span class="item_label">执行时间:</span> | ||
| 496 | <span class="item_value">{{ processDetailInfo?.operationTime || '--' }}</span> | ||
| 497 | </div> | ||
| 498 | <div class="list_item"> | ||
| 499 | <span class="item_label">执行结果:</span> | ||
| 500 | <span class="item_value"><ellipsis-tooltip :content="processDetailInfo?.executionResult || '--'" | ||
| 501 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'executionResult'"></ellipsis-tooltip></span> | ||
| 502 | </div> | ||
| 503 | <div class="list_item"> | ||
| 504 | <span class="item_label">执行环节:</span> | ||
| 505 | <span class="item_value"><ellipsis-tooltip :content="processDetailInfo?.executionProcess || '--'" | ||
| 506 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'executionProcess'"></ellipsis-tooltip></span> | ||
| 507 | </div> | ||
| 508 | <div class="list_item"> | ||
| 509 | <span class="item_label">合约名称:</span> | ||
| 510 | <span class="item_value"><ellipsis-tooltip :content="processDetailInfo?.contractName || '--'" | ||
| 511 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'contractName'"></ellipsis-tooltip></span> | ||
| 512 | </div> | ||
| 513 | <div class="list_item"> | ||
| 514 | <span class="item_label">执行节点标识:</span> | ||
| 515 | <span class="item_value"><ellipsis-tooltip :content="processDetailInfo?.executionEntityId || '--'" | ||
| 516 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'executionEntityId'"></ellipsis-tooltip></span> | ||
| 517 | </div> | ||
| 518 | <div class="list_item"> | ||
| 519 | <span class="item_label">执行节点名称:</span> | ||
| 520 | <span class="item_value"><ellipsis-tooltip :content="processDetailInfo?.executionEntityName || '--'" | ||
| 521 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'executionEntityName'"></ellipsis-tooltip></span> | ||
| 522 | </div> | ||
| 523 | <div class="h-title">策略信息</div> | ||
| 524 | <Table :table-info="execContractTableInfo"></Table> | ||
| 525 | </div> | ||
| 526 | </div> | ||
| 527 | </template> | ||
| 528 | </Dialog> | ||
| 529 | <Dialog ref="versionDialogRef" :dialogInfo="versionDetailDialogInfo" class="policy-table-detail" | ||
| 530 | @btnClick="handleVersionDialogBtnClick"> | ||
| 531 | <template #extra-content> | ||
| 532 | <div v-loading="versionDetailDialogInfo.contentLoading"> | ||
| 533 | <StrategyTable ref="strategyTableDetailRef" :show-title="true" :is-look="true" :value="versionDetail"> | ||
| 534 | </StrategyTable> | ||
| 535 | </div> | ||
| 536 | </template> | ||
| 537 | </Dialog> | ||
| 538 | </el-tabs> | ||
| 539 | </template> | ||
| 540 | |||
| 541 | <style lang="scss" scoped> | ||
| 542 | .table_panel_wrap { | ||
| 543 | height: calc(100% - 44px); | ||
| 544 | } | ||
| 545 | |||
| 546 | .main-content { | ||
| 547 | margin: 20px; | ||
| 548 | } | ||
| 549 | |||
| 550 | .list_panel { | ||
| 551 | display: flex; | ||
| 552 | flex-wrap: wrap; | ||
| 553 | display: flex; | ||
| 554 | align-items: flex-start; | ||
| 555 | |||
| 556 | &.main { | ||
| 557 | .list_item { | ||
| 558 | width: 25%; | ||
| 559 | } | ||
| 560 | } | ||
| 561 | |||
| 562 | .list_item { | ||
| 563 | width: 50%; | ||
| 564 | line-height: 32px; | ||
| 565 | font-size: 14px; | ||
| 566 | color: var(--el-text-color-regular); | ||
| 567 | display: flex; | ||
| 568 | justify-content: space-between; | ||
| 569 | min-width: 120px; | ||
| 570 | |||
| 571 | .item_label { | ||
| 572 | text-align: left; | ||
| 573 | } | ||
| 574 | |||
| 575 | .item_value { | ||
| 576 | color: var(--el-color-regular); | ||
| 577 | padding: 0 4px 0 0; | ||
| 578 | flex: 1; | ||
| 579 | text-align: justify; | ||
| 580 | min-width: 0; | ||
| 581 | |||
| 582 | .link { | ||
| 583 | color: var(--el-color-primary); | ||
| 584 | cursor: pointer; | ||
| 585 | margin-left: 4px; | ||
| 586 | } | ||
| 587 | |||
| 588 | } | ||
| 589 | |||
| 590 | &.is_block { | ||
| 591 | width: 100%; | ||
| 592 | |||
| 593 | .item_value { | ||
| 594 | white-space: pre-wrap; | ||
| 595 | } | ||
| 596 | } | ||
| 597 | |||
| 598 | } | ||
| 599 | } | ||
| 600 | |||
| 601 | :deep(.policy-table-detail) { | ||
| 602 | .dialog_content { | ||
| 603 | padding: 0px 20px 20px; | ||
| 604 | } | ||
| 605 | } | ||
| 606 | |||
| 607 | .h-title { | ||
| 608 | font-size: 14px; | ||
| 609 | color: #212121; | ||
| 610 | font-weight: 600; | ||
| 611 | margin-right: 8px; | ||
| 612 | margin-bottom: 8px; | ||
| 613 | } | ||
| 614 | </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 |
| 1 | <route lang="yaml"> | ||
| 2 | name: smartContractCreate | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="smartContractCreate"> | ||
| 6 | import { useValidator } from "@/hooks/useValidator"; | ||
| 7 | import useUserStore from "@/store/modules/user"; | ||
| 8 | import { | ||
| 9 | getContractDetail, | ||
| 10 | getActionPolicyList, | ||
| 11 | getConstraintPolicyList, | ||
| 12 | getContractDataProduct, | ||
| 13 | getContractTenantList, | ||
| 14 | saveContract, | ||
| 15 | updateContract, | ||
| 16 | } from "@/api/modules/dataSmartContract" | ||
| 17 | import StrategyTable from "./components/strategyTable.vue"; | ||
| 18 | import { CirclePlus } from "@element-plus/icons-vue"; | ||
| 19 | import { scrollLastRowToView } from "@/utils/common"; | ||
| 20 | import { TableColumnWidth } from "@/utils/enum"; | ||
| 21 | import { | ||
| 22 | getParamsList, | ||
| 23 | } from "@/api/modules/queryService"; | ||
| 24 | import useDataSmartContract from "@/store/modules/dataSmartContract"; | ||
| 25 | import { getEnterpriseData } from "@/api/modules/dataIdentify"; | ||
| 26 | |||
| 27 | const { required } = useValidator(); | ||
| 28 | const userStore = useUserStore(); | ||
| 29 | const userData = JSON.parse(localStorage.userData); | ||
| 30 | const tenantData = JSON.parse(localStorage.tenantInfo); | ||
| 31 | const router = useRouter(); | ||
| 32 | const route = useRoute(); | ||
| 33 | const fullscreenLoading = ref(false); | ||
| 34 | const expandBase = ref(false); | ||
| 35 | const expandInfo = ref(false); | ||
| 36 | const expandPolicy = ref(false); | ||
| 37 | const fullPath = route.fullPath; | ||
| 38 | const dataSmartContract = useDataSmartContract(); | ||
| 39 | const { proxy } = getCurrentInstance() as any; | ||
| 40 | |||
| 41 | const signModeList = ref([]); | ||
| 42 | |||
| 43 | const baseInfoFormRef = ref(); | ||
| 44 | |||
| 45 | const baseInfoFormItems = ref([{ | ||
| 46 | label: '合约名称', | ||
| 47 | type: 'input', | ||
| 48 | placeholder: '请输入', | ||
| 49 | field: 'contractName', | ||
| 50 | default: '', | ||
| 51 | maxlength: 50, | ||
| 52 | clearable: true, | ||
| 53 | required: true | ||
| 54 | }, { | ||
| 55 | label: '签署模式', | ||
| 56 | type: 'select', | ||
| 57 | placeholder: '请选择', | ||
| 58 | field: 'signModeCode', | ||
| 59 | default: '01', | ||
| 60 | options: signModeList.value, | ||
| 61 | props: { | ||
| 62 | value: 'value', | ||
| 63 | label: 'label' | ||
| 64 | }, | ||
| 65 | disabled: false, | ||
| 66 | required: true, | ||
| 67 | visible: true | ||
| 68 | }, { | ||
| 69 | label: "终止时间", | ||
| 70 | type: "datetime", | ||
| 71 | field: "endTime", | ||
| 72 | defaultTime: new Date(2000, 1, 1, 23, 59, 59), | ||
| 73 | default: null, | ||
| 74 | placeholder: "请选择", | ||
| 75 | clearable: true, | ||
| 76 | disabledDate: (date) => { | ||
| 77 | const today = new Date(); | ||
| 78 | // 将 today 设置为 00:00:00,只比较日期部分(本地时间) | ||
| 79 | const todayStart = new Date( | ||
| 80 | today.getFullYear(), | ||
| 81 | today.getMonth(), | ||
| 82 | today.getDate() | ||
| 83 | ); | ||
| 84 | |||
| 85 | // 将 date 也转换为本地日期的开始时间(避免 UTC 问题) | ||
| 86 | const dateStart = new Date( | ||
| 87 | date.getFullYear(), | ||
| 88 | date.getMonth(), | ||
| 89 | date.getDate() | ||
| 90 | ); | ||
| 91 | |||
| 92 | // 禁用 dateStart < todayStart 的日期(即今天之前) | ||
| 93 | return dateStart.getTime() < todayStart.getTime(); | ||
| 94 | }, | ||
| 95 | required: true, | ||
| 96 | }, { | ||
| 97 | label: '合约简介', | ||
| 98 | type: 'textarea', | ||
| 99 | focusValue: false, | ||
| 100 | placeholder: '请输入', | ||
| 101 | field: 'contractAbstract', | ||
| 102 | default: '', | ||
| 103 | clearable: true, | ||
| 104 | required: false, | ||
| 105 | block: true, | ||
| 106 | maxlength: 500 | ||
| 107 | }]); | ||
| 108 | |||
| 109 | const baseInfoFormRules = ref({ | ||
| 110 | contractName: [required('请填写合约名称')], | ||
| 111 | signModeCode: [required('请选择签署模式')], | ||
| 112 | endTime: [required('请选择终止时间')], | ||
| 113 | }); | ||
| 114 | |||
| 115 | const handleFormSelectChange = (val, row, info) => { | ||
| 116 | if (row.field == 'signModeCode') { //签署模式改变会影响下面的合约策略执行者的显示 | ||
| 117 | let nodeInfo = nodeInfoFormRef.value.formInline; | ||
| 118 | nodeInfoFormItems.value.forEach((item, index) => { | ||
| 119 | item.default = nodeInfo[item.field]; | ||
| 120 | if (index == 1) { | ||
| 121 | item.default = val == '01' ? userData.tenantGuid : ''; | ||
| 122 | } else if (index == 2) { | ||
| 123 | item.default = val == '01' ? tenantList.value.find(t => t.guid == userData.tenantGuid)?.socialCreditCode : ''; | ||
| 124 | } | ||
| 125 | }) | ||
| 126 | productList.value = productList.value?.map(d => { | ||
| 127 | d.disabled = val == '01' && d.enterpriseName != userData.tenantName; //点对点,只能选择自己公司所属产品 | ||
| 128 | return d; | ||
| 129 | }) || []; | ||
| 130 | productTableInfo.value.editInfo.dataProductId.options = productList.value; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | /** ----------------- 扩展字段相关信息 ----------------------------- */ | ||
| 135 | const extendTableRef = ref(); | ||
| 136 | const extendData: any = ref([]); | ||
| 137 | |||
| 138 | /** 合约扩展字段类型 */ | ||
| 139 | const dataTypeList: any = ref([]); | ||
| 140 | |||
| 141 | /** 基本信息的入参定义表格配置 */ | ||
| 142 | const extendTableInfo = ref({ | ||
| 143 | id: "input-extend-table", | ||
| 144 | height: '214px', | ||
| 145 | fields: [ | ||
| 146 | { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" }, | ||
| 147 | { label: "扩展字段名称", field: "expansionFieldName", width: 160, required: true, columClass: 'edit-colum', type: 'edit' }, | ||
| 148 | { label: "字段类型", field: "fieldType", width: 140, required: true, columClass: 'edit-colum', type: 'edit' }, | ||
| 149 | { label: "输入内容", field: "content", width: 300, required: false, columClass: 'edit-colum', type: 'edit' }, | ||
| 150 | ], | ||
| 151 | editInfo: { | ||
| 152 | expansionFieldName: { | ||
| 153 | label: '', | ||
| 154 | type: 'input', | ||
| 155 | field: 'expansionFieldName', | ||
| 156 | default: '', | ||
| 157 | maxlength: 50, | ||
| 158 | placeholder: '请输入', | ||
| 159 | clearable: true, | ||
| 160 | }, | ||
| 161 | fieldType: { | ||
| 162 | label: '', | ||
| 163 | type: 'select', | ||
| 164 | field: 'fieldType', | ||
| 165 | default: '', | ||
| 166 | options: dataTypeList.value, | ||
| 167 | props: { | ||
| 168 | label: 'label', | ||
| 169 | value: 'value' | ||
| 170 | }, | ||
| 171 | placeholder: '请选择', | ||
| 172 | clearable: false, | ||
| 173 | filterable: true | ||
| 174 | }, | ||
| 175 | content: { | ||
| 176 | label: '', | ||
| 177 | type: 'input', | ||
| 178 | field: 'content', | ||
| 179 | default: '', | ||
| 180 | maxlength: 200, | ||
| 181 | placeholder: '请输入', | ||
| 182 | clearable: true, | ||
| 183 | } | ||
| 184 | }, | ||
| 185 | STATUS: 'edit', | ||
| 186 | data: extendData.value, | ||
| 187 | showPage: false, | ||
| 188 | actionInfo: { | ||
| 189 | show: true, | ||
| 190 | label: "操作", | ||
| 191 | type: "btn", | ||
| 192 | width: 60, | ||
| 193 | fixed: 'right', | ||
| 194 | btns: [ | ||
| 195 | { | ||
| 196 | label: "删除", value: "remove", click: (scope) => { | ||
| 197 | let index = scope.$index; | ||
| 198 | proxy.$openMessageBox("此操作将永久删除, 是否继续?", () => { | ||
| 199 | extendData.value.splice(index, 1); | ||
| 200 | extendTableInfo.value.data = extendData.value; | ||
| 201 | proxy.$ElMessage.success('扩展字段删除成功'); | ||
| 202 | }, () => { | ||
| 203 | proxy.$ElMessage.info("已取消"); | ||
| 204 | }); | ||
| 205 | } | ||
| 206 | }, | ||
| 207 | ] | ||
| 208 | }, | ||
| 209 | loading: false | ||
| 210 | }); | ||
| 211 | |||
| 212 | /** 给表格添加一行入参定义。 */ | ||
| 213 | const addExtend = () => { | ||
| 214 | extendData.value.push({ expansionFieldName: '', fieldType: '', content: '' }); | ||
| 215 | extendTableInfo.value.data = extendData.value; | ||
| 216 | nextTick(() => { | ||
| 217 | scrollLastRowToView(extendTableRef.value?.tableRef, extendData.value.length); | ||
| 218 | }) | ||
| 219 | } | ||
| 220 | |||
| 221 | /** ----------------- 数据产品表格相关信息 ----------------------------- */ | ||
| 222 | const productTableRef = ref(); | ||
| 223 | const productData: any = ref([]); | ||
| 224 | |||
| 225 | const productList: any = ref([]); | ||
| 226 | |||
| 227 | /** 基本信息的入参定义表格配置 */ | ||
| 228 | const productTableInfo = ref({ | ||
| 229 | id: "input-product-table", | ||
| 230 | height: '214px', | ||
| 231 | fields: [ | ||
| 232 | { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" }, | ||
| 233 | { label: "数据产品", field: "dataProductId", width: 180, required: true, columClass: 'edit-colum', type: 'edit' }, | ||
| 234 | { label: "数据产品编码", field: "dataProductId", width: 261 }, | ||
| 235 | { label: "所属主体名称", field: "dataProductEntityName", width: 200 }, | ||
| 236 | { label: "产品简介", field: "dataProductAbstract", width: 240 }, | ||
| 237 | ], | ||
| 238 | editInfo: { | ||
| 239 | dataProductId: { | ||
| 240 | label: '', | ||
| 241 | type: 'select', | ||
| 242 | field: 'dataProductId', | ||
| 243 | default: '', | ||
| 244 | options: productList.value, | ||
| 245 | props: { | ||
| 246 | label: 'productNameDesc', | ||
| 247 | value: 'productId', | ||
| 248 | disabled: 'disabled' | ||
| 249 | }, | ||
| 250 | placeholder: '请选择', | ||
| 251 | clearable: false, | ||
| 252 | filterable: true | ||
| 253 | }, | ||
| 254 | }, | ||
| 255 | STATUS: 'edit', | ||
| 256 | data: productData.value, | ||
| 257 | showPage: false, | ||
| 258 | actionInfo: { | ||
| 259 | show: true, | ||
| 260 | label: "操作", | ||
| 261 | type: "btn", | ||
| 262 | width: 60, | ||
| 263 | fixed: 'right', | ||
| 264 | btns: [ | ||
| 265 | { | ||
| 266 | label: "删除", value: "remove", click: (scope) => { | ||
| 267 | let index = scope.$index; | ||
| 268 | proxy.$openMessageBox("此操作将永久删除, 是否继续?", () => { | ||
| 269 | productData.value.splice(index, 1); | ||
| 270 | productTableInfo.value.data = productData.value; | ||
| 271 | proxy.$ElMessage.success('产品删除成功'); | ||
| 272 | }, () => { | ||
| 273 | proxy.$ElMessage.info("已取消"); | ||
| 274 | }); | ||
| 275 | } | ||
| 276 | }, | ||
| 277 | ] | ||
| 278 | }, | ||
| 279 | loading: false | ||
| 280 | }); | ||
| 281 | |||
| 282 | /** 给表格添加一行入参定义。 */ | ||
| 283 | const addProduct = () => { | ||
| 284 | productData.value.push({ dataProductId: '' }); | ||
| 285 | productTableInfo.value.data = productData.value; | ||
| 286 | nextTick(() => { | ||
| 287 | scrollLastRowToView(productTableRef.value?.tableRef, productData.value.length); | ||
| 288 | }) | ||
| 289 | } | ||
| 290 | |||
| 291 | /** 根据下拉选择的产品带出产品相关信息 */ | ||
| 292 | const hanldeTableSelectChange = (val, scope, item) => { | ||
| 293 | let productItem = val && productList.value.find(p => p.productId == val); | ||
| 294 | scope.row.dataProductId = val; | ||
| 295 | scope.row.dataProductCode = val; | ||
| 296 | scope.row.dataProductName = productItem?.productName; | ||
| 297 | scope.row.dataProductEntityId = productItem?.enterpriseCode; | ||
| 298 | scope.row.dataProductAbstract = productItem?.description; | ||
| 299 | scope.row.dataProductEntityName = productItem?.enterpriseName; | ||
| 300 | let nodeInfo = nodeInfoFormRef.value.formInline; | ||
| 301 | if (scope.$index == 0) { | ||
| 302 | nodeInfoFormItems.value.forEach((item, index) => { | ||
| 303 | item.default = nodeInfo[item.field]; | ||
| 304 | if (index == 1) { | ||
| 305 | item.default = tenantList.value.find(t => t.socialCreditCode == scope.row.dataProductEntityId)?.guid || scope.row.dataProductEntityName; | ||
| 306 | } else if (index == 2) { | ||
| 307 | item.default = scope.row.dataProductEntityId || ''; | ||
| 308 | } | ||
| 309 | }) | ||
| 310 | } | ||
| 311 | } | ||
| 312 | |||
| 313 | /** ---------------- 合约策略执行者相关表单信息 ----------------------------------- */ | ||
| 314 | |||
| 315 | /** 策略执行者下拉列表 */ | ||
| 316 | const tenantList: any = ref([]); | ||
| 317 | |||
| 318 | const nodeInfoFormRef = ref(); | ||
| 319 | |||
| 320 | // 策略执行者类型列表 | ||
| 321 | const executorTypeList: any = ref([]); | ||
| 322 | |||
| 323 | const nodeInfoFormItems = ref([{ | ||
| 324 | label: '策略执行者类型', | ||
| 325 | type: 'input', | ||
| 326 | placeholder: '-', | ||
| 327 | field: 'dataProviderType', | ||
| 328 | default: '', | ||
| 329 | disabled: true, | ||
| 330 | visible: true | ||
| 331 | }, { | ||
| 332 | label: '策略执行者名称', | ||
| 333 | type: 'select', | ||
| 334 | placeholder: '请选择', | ||
| 335 | field: 'dataProviderGuid', | ||
| 336 | default: '', | ||
| 337 | options: tenantList.value, //先禁用,选择产品后自动带出 | ||
| 338 | props: { | ||
| 339 | value: 'guid', | ||
| 340 | label: 'tenantName' | ||
| 341 | }, | ||
| 342 | filterable: true, | ||
| 343 | clearable: true, | ||
| 344 | disabled: true, | ||
| 345 | required: true, | ||
| 346 | visible: true | ||
| 347 | }, { | ||
| 348 | label: '策略执行者标识', | ||
| 349 | type: 'input', | ||
| 350 | placeholder: '-', | ||
| 351 | field: 'dataProviderId', | ||
| 352 | default: '', | ||
| 353 | disabled: true, | ||
| 354 | visible: true | ||
| 355 | }, { | ||
| 356 | label: '策略执行者类型', | ||
| 357 | type: 'input', | ||
| 358 | placeholder: '-', | ||
| 359 | field: 'dataUserType', | ||
| 360 | default: '', | ||
| 361 | disabled: true, | ||
| 362 | visible: true | ||
| 363 | }, { | ||
| 364 | label: '策略执行者名称', | ||
| 365 | type: 'select', | ||
| 366 | placeholder: '请选择', | ||
| 367 | field: 'dataUserGuid', | ||
| 368 | default: '', | ||
| 369 | options: tenantList.value, | ||
| 370 | props: { | ||
| 371 | value: 'guid', | ||
| 372 | label: 'tenantName' | ||
| 373 | }, | ||
| 374 | filterable: true, | ||
| 375 | clearable: true, | ||
| 376 | required: true, | ||
| 377 | visible: true | ||
| 378 | }, { | ||
| 379 | label: '策略执行者标识', | ||
| 380 | type: 'input', | ||
| 381 | placeholder: '-', | ||
| 382 | field: 'dataUserId', | ||
| 383 | default: '', | ||
| 384 | disabled: true, | ||
| 385 | visible: true | ||
| 386 | }]) | ||
| 387 | |||
| 388 | const nodeInfoFormRules = ref({ | ||
| 389 | // dataProviderGuid: [required('请选择数据供给方策略执行者名称')], | ||
| 390 | dataUserGuid: [required('请选择数据使用方策略执行者名称')], | ||
| 391 | }); | ||
| 392 | |||
| 393 | const handleNodeSelectChange = (val, row, info) => { | ||
| 394 | if (row.field == 'dataUserGuid') { | ||
| 395 | let tenantItem = tenantList.value.find(t => t.guid == val); | ||
| 396 | info.dataUserId = tenantItem?.socialCreditCode || ''; | ||
| 397 | nodeInfoFormItems.value.forEach(item => { | ||
| 398 | item.default = info[item.field]; | ||
| 399 | }); | ||
| 400 | } | ||
| 401 | } | ||
| 402 | |||
| 403 | const strategyTableRef = ref(); | ||
| 404 | |||
| 405 | /** 约束运算符字典下拉 */ | ||
| 406 | const operatorOptionList: any = ref([]); | ||
| 407 | |||
| 408 | /** 约束行为下拉列表 */ | ||
| 409 | const constraintOptionsList: any = ref([]); | ||
| 410 | |||
| 411 | /** 策略操作行为下拉列表 */ | ||
| 412 | const actionOptionsList: any = ref([]); | ||
| 413 | |||
| 414 | const getSubmitInfo = () => { | ||
| 415 | let baseInfo = baseInfoFormRef.value.formInline; | ||
| 416 | let nodeInfo = nodeInfoFormRef.value.formInline; | ||
| 417 | let params = { ...baseInfo }; | ||
| 418 | params.contractExpansions = extendData.value; | ||
| 419 | params.contractSubjects = productData.value; | ||
| 420 | params.executionNodes = [{ | ||
| 421 | executionerTypeCode: executorTypeList.value[0]?.value, | ||
| 422 | executionerGuid: nodeInfo.dataProviderGuid, | ||
| 423 | executionerId: nodeInfo.dataProviderId, | ||
| 424 | executionerName: tenantList.value.find(t => t.guid == nodeInfo.dataProviderGuid)?.tenantName | ||
| 425 | }, { | ||
| 426 | executionerTypeCode: executorTypeList.value[1]?.value, | ||
| 427 | executionerGuid: nodeInfo.dataUserGuid, | ||
| 428 | executionerId: nodeInfo.dataUserId, | ||
| 429 | executionerName: tenantList.value.find(t => t.guid == nodeInfo.dataUserGuid)?.tenantName | ||
| 430 | }]; | ||
| 431 | params.policys = strategyTableRef.value.strategyData?.map((d, index) => { | ||
| 432 | return Object.assign({}, d, { orderNum: index + 1 }) | ||
| 433 | }) || []; | ||
| 434 | return params; | ||
| 435 | } | ||
| 436 | |||
| 437 | const saveDraft = () => { | ||
| 438 | let params: any = getSubmitInfo(); | ||
| 439 | params.isResubmit = false; | ||
| 440 | fullscreenLoading.value = true; | ||
| 441 | if (!route.query.guid) { | ||
| 442 | saveContract(params).then((res: any) => { | ||
| 443 | fullscreenLoading.value = false; | ||
| 444 | if (res?.code == proxy.$passCode) { | ||
| 445 | proxy.$ElMessage.success('合约保存成功'); | ||
| 446 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | ||
| 447 | router.push({ | ||
| 448 | name: "smartContractManagement", | ||
| 449 | }); | ||
| 450 | dataSmartContract.set(true); | ||
| 451 | } else { | ||
| 452 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 453 | } | ||
| 454 | }) | ||
| 455 | } else { | ||
| 456 | params.guid = route.query.guid; | ||
| 457 | params.isResubmit = false; | ||
| 458 | updateContract(params).then((res: any) => { | ||
| 459 | fullscreenLoading.value = false; | ||
| 460 | if (res?.code == proxy.$passCode) { | ||
| 461 | proxy.$ElMessage.success('合约编辑保存成功'); | ||
| 462 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | ||
| 463 | router.push({ | ||
| 464 | name: "smartContractManagement", | ||
| 465 | }); | ||
| 466 | dataSmartContract.set(true); | ||
| 467 | } else { | ||
| 468 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 469 | } | ||
| 470 | }) | ||
| 471 | } | ||
| 472 | } | ||
| 473 | |||
| 474 | const submit = () => { | ||
| 475 | baseInfoFormRef.value.ruleFormRef?.validate((valid, errorItem) => { | ||
| 476 | if (valid) { | ||
| 477 | for (const data of extendData.value) { | ||
| 478 | if (!data.expansionFieldName) { | ||
| 479 | proxy.$ElMessage.error('扩展信息中的扩展字段名称不能为空'); | ||
| 480 | handleLeft('base-info'); | ||
| 481 | expandBase.value = true; | ||
| 482 | return; | ||
| 483 | } | ||
| 484 | if (!data.fieldType) { | ||
| 485 | proxy.$ElMessage.error('扩展信息中的字段类型不能为空'); | ||
| 486 | handleLeft('base-info'); | ||
| 487 | expandBase.value = true; | ||
| 488 | return; | ||
| 489 | } | ||
| 490 | } | ||
| 491 | if (!productData.value?.length) { | ||
| 492 | proxy.$ElMessage.error('合约标的的数据产品不能为空'); | ||
| 493 | expandInfo.value = true; | ||
| 494 | handleLeft('product-info'); | ||
| 495 | return; | ||
| 496 | } | ||
| 497 | let index = 0; | ||
| 498 | for (const pd of productData.value) { | ||
| 499 | if (!pd.dataProductId) { | ||
| 500 | proxy.$ElMessage.error('合约标的的数据产品不能为空'); | ||
| 501 | expandInfo.value = true; | ||
| 502 | handleLeft('product-info'); | ||
| 503 | return; | ||
| 504 | } | ||
| 505 | if (userData.superTubeFlag == 'Y') { //只有主平台模式下需判断 | ||
| 506 | if (baseInfoFormRef.value.formInline.signModeCode == '02' && index > 0 && productData.value[index].dataProductEntityId != pd.dataProductEntityId) { | ||
| 507 | proxy.$ElMessage.error('合约标的的数据产品不能来自不同的企业主体'); | ||
| 508 | expandInfo.value = true; | ||
| 509 | handleLeft('product-info'); | ||
| 510 | return; | ||
| 511 | } else { | ||
| 512 | if (pd.dataProductEntityId != nodeInfoFormRef.value?.formInline?.dataProviderId) { | ||
| 513 | proxy.$ElMessage.error('合约标的的数据产品所属主体与数据提供方的策略执行者不一致,请检查!'); | ||
| 514 | expandInfo.value = true; | ||
| 515 | handleLeft('product-info'); | ||
| 516 | return; | ||
| 517 | } | ||
| 518 | } | ||
| 519 | } | ||
| 520 | index++; | ||
| 521 | } | ||
| 522 | nodeInfoFormRef.value.ruleFormRef?.validate((valid1, errorItem1) => { | ||
| 523 | if (valid1) { | ||
| 524 | let nodeInfo = nodeInfoFormRef.value.formInline; | ||
| 525 | if (nodeInfo.dataProviderGuid == nodeInfo.dataUserGuid) { | ||
| 526 | proxy.$ElMessage.error(`${executorTypeList.value[0].label}和${executorTypeList.value[1].label}的策略执行者不能选择同一个`); | ||
| 527 | expandPolicy.value = true; | ||
| 528 | handleLeft('policy-info'); | ||
| 529 | return; | ||
| 530 | } | ||
| 531 | if (!strategyTableRef.value.validateValue()) { | ||
| 532 | expandPolicy.value = true; | ||
| 533 | handleLeft('policy-info'); | ||
| 534 | return; | ||
| 535 | } | ||
| 536 | let params: any = getSubmitInfo(); | ||
| 537 | params.isResubmit = detailInfo.value?.contractStatus == '00'; | ||
| 538 | params.contractStatus = '02'; | ||
| 539 | fullscreenLoading.value = true; | ||
| 540 | if (!route.query.guid) { | ||
| 541 | saveContract(params).then((res: any) => { | ||
| 542 | fullscreenLoading.value = false; | ||
| 543 | if (res?.code == proxy.$passCode) { | ||
| 544 | proxy.$ElMessage.success('合约协商成功'); | ||
| 545 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | ||
| 546 | router.push({ | ||
| 547 | name: "smartContractManagement", | ||
| 548 | }); | ||
| 549 | dataSmartContract.set(true); | ||
| 550 | } else { | ||
| 551 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 552 | } | ||
| 553 | }) | ||
| 554 | } else { | ||
| 555 | params.guid = route.query.guid; | ||
| 556 | updateContract(params).then((res: any) => { | ||
| 557 | fullscreenLoading.value = false; | ||
| 558 | if (res?.code == proxy.$passCode) { | ||
| 559 | proxy.$ElMessage.success('合约协商成功'); | ||
| 560 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | ||
| 561 | router.push({ | ||
| 562 | name: "smartContractManagement", | ||
| 563 | }); | ||
| 564 | dataSmartContract.set(true); | ||
| 565 | } else { | ||
| 566 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 567 | } | ||
| 568 | }) | ||
| 569 | } | ||
| 570 | } else { | ||
| 571 | expandPolicy.value = true; | ||
| 572 | var obj = Object.keys(errorItem1); | ||
| 573 | nodeInfoFormRef.value.ruleFormRef?.scrollToField(obj[0]); | ||
| 574 | } | ||
| 575 | }) | ||
| 576 | } else { | ||
| 577 | expandBase.value = true; | ||
| 578 | var obj = Object.keys(errorItem); | ||
| 579 | baseInfoFormRef.value.ruleFormRef?.scrollToField(obj[0]); | ||
| 580 | nodeInfoFormRef.value.validate(); | ||
| 581 | } | ||
| 582 | }); | ||
| 583 | } | ||
| 584 | |||
| 585 | const handleLeft = (id) => { | ||
| 586 | let dom = document.getElementById(id); | ||
| 587 | dom && dom.scrollIntoView({ | ||
| 588 | behavior: "smooth", // 平滑过渡 | ||
| 589 | block: "start", // 上边框与视窗顶部平齐。默认值 | ||
| 590 | }); | ||
| 591 | } | ||
| 592 | |||
| 593 | const cancel = () => { | ||
| 594 | proxy.$openMessageBox("当前页面尚未保存,确定放弃修改吗?", () => { | ||
| 595 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | ||
| 596 | router.push({ | ||
| 597 | name: "smartContractManagement", | ||
| 598 | }); | ||
| 599 | }, () => { | ||
| 600 | proxy.$ElMessage.info("已取消"); | ||
| 601 | }); | ||
| 602 | } | ||
| 603 | |||
| 604 | const detailInfo: any = ref({}); | ||
| 605 | |||
| 606 | /** 当前会员是否认证信息 */ | ||
| 607 | const currTenantDetailInfo: any = ref({ }); | ||
| 608 | |||
| 609 | const psLogon = ref(); | ||
| 610 | |||
| 611 | onBeforeMount(() => { | ||
| 612 | let exec = () => { | ||
| 613 | if (userData.superTubeFlag != 'Y') { | ||
| 614 | baseInfoFormItems.value[1].disabled = true; | ||
| 615 | baseInfoFormItems.value[1].default = '01'; | ||
| 616 | productTableInfo.value.editInfo.dataProductId.props.label = 'productName'; | ||
| 617 | } else { //可以选点对点。未认证时只能选择中介参与 | ||
| 618 | baseInfoFormItems.value[1].disabled = !currTenantDetailInfo.value.trustedIdentityCredential; | ||
| 619 | baseInfoFormItems.value[1].default = !currTenantDetailInfo.value.trustedIdentityCredential ? '02' : '01'; | ||
| 620 | productTableInfo.value.editInfo.dataProductId.props.label = 'productNameDesc'; | ||
| 621 | } | ||
| 622 | if (route.query.guid) { | ||
| 623 | fullscreenLoading.value = true; | ||
| 624 | getContractDetail(route.query.guid).then((res: any) => { | ||
| 625 | fullscreenLoading.value = false; | ||
| 626 | if (res?.code == proxy.$passCode) { | ||
| 627 | detailInfo.value = res.data || {}; | ||
| 628 | baseInfoFormItems.value.forEach(item => { | ||
| 629 | item.default = detailInfo.value[item.field]; | ||
| 630 | }); | ||
| 631 | // if (baseInfoFormItems.value[1].default == '01') { | ||
| 632 | // // 默认点对点,数据使用方可以选择 | ||
| 633 | // nodeInfoFormItems.value[1].disabled = true; | ||
| 634 | // } else { | ||
| 635 | // nodeInfoFormItems.value[1].disabled = false; | ||
| 636 | // } | ||
| 637 | // nodeInfoFormItems.value[1].disabled = detailInfo.value.signModeCode == '01'; | ||
| 638 | let executionNodes = detailInfo.value.executionNodes || []; | ||
| 639 | let provider = executionNodes.find(e => e.executionerTypeCode == '01'); | ||
| 640 | let user = executionNodes.find(e => e.executionerTypeCode == '02'); | ||
| 641 | nodeInfoFormItems.value[1].default = provider.executionerGuid; | ||
| 642 | nodeInfoFormItems.value[2].default = provider.executionerId; | ||
| 643 | nodeInfoFormItems.value[4].default = user.executionerGuid; | ||
| 644 | nodeInfoFormItems.value[5].default = user.executionerId; | ||
| 645 | if (baseInfoFormItems.value[1].default == '01' && userData.superTubeFlag == 'Y') { | ||
| 646 | productList.value = res.data?.map(d => { | ||
| 647 | d.disabled = d.enterpriseName != userData.tenantName; //点对点,只能选择自己公司所属产品 | ||
| 648 | return d; | ||
| 649 | }) || []; | ||
| 650 | } | ||
| 651 | productTableInfo.value.editInfo.dataProductId.options = productList.value; | ||
| 652 | extendData.value = detailInfo.value.contractExpansions || []; | ||
| 653 | extendTableInfo.value.data = extendData.value; | ||
| 654 | productData.value = detailInfo.value.contractSubjects || []; | ||
| 655 | productTableInfo.value.data = productData.value; | ||
| 656 | } else { | ||
| 657 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 658 | } | ||
| 659 | }) | ||
| 660 | } else { | ||
| 661 | if (baseInfoFormItems.value[1].default == '01') { | ||
| 662 | // 默认点对点,数据使用方可以选择 | ||
| 663 | // nodeInfoFormItems.value[1].disabled = true; | ||
| 664 | nodeInfoFormItems.value[1].default = userData.tenantGuid; | ||
| 665 | if (tenantList.value.length) { | ||
| 666 | let item = tenantList.value.find(t => t.guid == userData.tenantGuid); | ||
| 667 | nodeInfoFormItems.value[2].default = item?.socialCreditCode; | ||
| 668 | } | ||
| 669 | } else { | ||
| 670 | // nodeInfoFormItems.value[1].disabled = false; | ||
| 671 | nodeInfoFormItems.value[1].default = ''; //如果是中介的话,不能选择自己吧。 | ||
| 672 | } | ||
| 673 | } | ||
| 674 | getContractDataProduct().then((res: any) => { | ||
| 675 | if (res?.code == proxy.$passCode) { | ||
| 676 | productList.value = res.data?.map(d => { | ||
| 677 | d.productNameDesc = d.productName + '(' + d.enterpriseName + ')'; | ||
| 678 | d.disabled = userData.superTubeFlag == 'Y' && baseInfoFormItems.value[1].default == '01' && d.enterpriseName != userData.tenantName; //点对点,只能选择自己公司所属产品 | ||
| 679 | return d; | ||
| 680 | }) || []; | ||
| 681 | productTableInfo.value.editInfo.dataProductId.options = productList.value; | ||
| 682 | } else { | ||
| 683 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 684 | } | ||
| 685 | }) | ||
| 686 | } | ||
| 687 | fullscreenLoading.value = true; | ||
| 688 | psLogon.value = getEnterpriseData({ | ||
| 689 | logonUser: userData.tenantName == "非认证会员" ? userData.logonUser : tenantData.logonUser | ||
| 690 | }).then((res: any) => { | ||
| 691 | psLogon.value = null; | ||
| 692 | fullscreenLoading.value = false; | ||
| 693 | if (res?.code == proxy.$passCode) { | ||
| 694 | currTenantDetailInfo.value = res.data || {}; | ||
| 695 | exec(); | ||
| 696 | } else { | ||
| 697 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 698 | exec(); | ||
| 699 | } | ||
| 700 | }).catch(() => { | ||
| 701 | psLogon.value = null; | ||
| 702 | fullscreenLoading.value = false; | ||
| 703 | exec(); | ||
| 704 | }); | ||
| 705 | getParamsList({ dictType: '合约签署模式' }).then((res: any) => { | ||
| 706 | if (res?.code == proxy.$passCode) { | ||
| 707 | const data = res.data || []; | ||
| 708 | signModeList.value = data; | ||
| 709 | baseInfoFormItems.value[1].options = signModeList.value; | ||
| 710 | } else { | ||
| 711 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 712 | } | ||
| 713 | }) | ||
| 714 | getParamsList({ dictType: '合约扩展字段类型' }).then((res: any) => { | ||
| 715 | if (res?.code == proxy.$passCode) { | ||
| 716 | const data = res.data || []; | ||
| 717 | dataTypeList.value = data; | ||
| 718 | extendTableInfo.value.editInfo.fieldType.options = dataTypeList.value; | ||
| 719 | } else { | ||
| 720 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 721 | } | ||
| 722 | }) | ||
| 723 | getParamsList({ dictType: '约束运算符' }).then((res: any) => { | ||
| 724 | if (res?.code == proxy.$passCode) { | ||
| 725 | const data = res.data || []; | ||
| 726 | operatorOptionList.value = data; | ||
| 727 | } else { | ||
| 728 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 729 | } | ||
| 730 | }) | ||
| 731 | getActionPolicyList().then((res: any) => { | ||
| 732 | if (res?.code == proxy.$passCode) { | ||
| 733 | const data = res.data || []; | ||
| 734 | actionOptionsList.value = data; | ||
| 735 | } else { | ||
| 736 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 737 | } | ||
| 738 | }) | ||
| 739 | getConstraintPolicyList().then((res: any) => { | ||
| 740 | if (res?.code == proxy.$passCode) { | ||
| 741 | const data = res.data || []; | ||
| 742 | constraintOptionsList.value = data; | ||
| 743 | } else { | ||
| 744 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 745 | } | ||
| 746 | }) | ||
| 747 | getParamsList({ dictType: '策略执行者类型' }).then((res: any) => { | ||
| 748 | if (res?.code == proxy.$passCode) { | ||
| 749 | const data = res.data || []; | ||
| 750 | executorTypeList.value = data; | ||
| 751 | nodeInfoFormItems.value[0].default = executorTypeList.value[0]?.label; | ||
| 752 | nodeInfoFormItems.value[3].default = executorTypeList.value[1]?.label; | ||
| 753 | } else { | ||
| 754 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 755 | } | ||
| 756 | }) | ||
| 757 | getContractTenantList().then((res: any) => { | ||
| 758 | if (res.code == proxy.$passCode) { | ||
| 759 | tenantList.value = res.data || []; | ||
| 760 | nodeInfoFormItems.value[1].options = tenantList.value; | ||
| 761 | nodeInfoFormItems.value[4].options = tenantList.value; | ||
| 762 | if (nodeInfoFormItems.value[1].default) { | ||
| 763 | let item = tenantList.value.find(t => t.guid == nodeInfoFormItems.value[1].default); | ||
| 764 | nodeInfoFormItems.value[2].default = item?.socialCreditCode; | ||
| 765 | } | ||
| 766 | } else { | ||
| 767 | res?.msg && proxy.$ElMessage.error(res.msg); | ||
| 768 | } | ||
| 769 | }) | ||
| 770 | }); | ||
| 771 | |||
| 772 | onActivated(() => { | ||
| 773 | if (route.query.guid) { | ||
| 774 | let tab: any = userStore.tabbar.find((tab: any) => tab.fullPath === fullPath); | ||
| 775 | if (tab) { | ||
| 776 | document.title = `编辑合约-${route.query.name}`; | ||
| 777 | tab.meta.title = `编辑合约-${route.query.name}`; | ||
| 778 | } | ||
| 779 | } | ||
| 780 | }) | ||
| 781 | |||
| 782 | </script> | ||
| 783 | |||
| 784 | <template> | ||
| 785 | <div class="container_wrap full" v-loading="fullscreenLoading"> | ||
| 786 | <div class="content_main panel"> | ||
| 787 | <ContentWrap id="base-info" title="合约信息" expandSwicth style="margin-top: 15px" :isExpand="expandBase" | ||
| 788 | @expand="(v) => (expandBase = v)" description=""> | ||
| 789 | <Form ref="baseInfoFormRef" formId="base-info-form" :itemList="baseInfoFormItems" :rules="baseInfoFormRules" | ||
| 790 | col="col3" @select-change="handleFormSelectChange" /> | ||
| 791 | <Table ref="extendTableRef" :tableInfo="extendTableInfo" class="fiveRow-table" /> | ||
| 792 | <div class="row-add-btn"> | ||
| 793 | <el-button link @click="addExtend" :icon="CirclePlus" v-preReClick>添加扩展信息</el-button> | ||
| 794 | </div> | ||
| 795 | </ContentWrap> | ||
| 796 | <ContentWrap id="product-info" title="合约标的" expandSwicth style="margin-top: 15px" :isExpand="expandInfo" | ||
| 797 | @expand="(v) => (expandInfo = v)" description=""> | ||
| 798 | <Table ref="productTableRef" :tableInfo="productTableInfo" class="fiveRow-table" | ||
| 799 | @table-select-change="hanldeTableSelectChange" /> | ||
| 800 | <div class="row-add-btn"> | ||
| 801 | <el-button link @click="addProduct" :icon="CirclePlus" v-preReClick>添加产品</el-button> | ||
| 802 | </div> | ||
| 803 | </ContentWrap> | ||
| 804 | <ContentWrap id="policy-info" title="合约策略" expandSwicth style="margin-top: 15px" :isExpand="expandPolicy" | ||
| 805 | @expand="(v) => (expandPolicy = v)" description=""> | ||
| 806 | <div class="h-title">策略执行节点</div> | ||
| 807 | <Form ref="nodeInfoFormRef" formId="node-info-form" :itemList="nodeInfoFormItems" :rules="nodeInfoFormRules" | ||
| 808 | @select-change="handleNodeSelectChange" col="col3" /> | ||
| 809 | <StrategyTable ref="strategyTableRef" :show-title="true" :value="detailInfo.policys || []" | ||
| 810 | :operatorOptionList="operatorOptionList" :actionOptionsList="actionOptionsList" | ||
| 811 | :constraintOptionsList="constraintOptionsList"></StrategyTable> | ||
| 812 | </ContentWrap> | ||
| 813 | </div> | ||
| 814 | <div class="tool_btns"> | ||
| 815 | <div class="btns"> | ||
| 816 | <el-button @click="cancel">取消</el-button> | ||
| 817 | <el-button @click="saveDraft" v-show="detailInfo?.contractStatus != '00'">保存</el-button> | ||
| 818 | <el-button type="primary" @click="submit">合约协商</el-button> | ||
| 819 | </div> | ||
| 820 | </div> | ||
| 821 | </div> | ||
| 822 | </template> | ||
| 823 | |||
| 824 | <style lang="scss" scoped> | ||
| 825 | .container_wrap { | ||
| 826 | overflow: hidden; | ||
| 827 | |||
| 828 | .content_main { | ||
| 829 | height: calc(100% - 45px); | ||
| 830 | overflow: hidden auto; | ||
| 831 | |||
| 832 | &.panel { | ||
| 833 | padding: 0 16px 16px; | ||
| 834 | } | ||
| 835 | } | ||
| 836 | } | ||
| 837 | |||
| 838 | .tool_btns { | ||
| 839 | height: 44px; | ||
| 840 | margin: 0 -8px; | ||
| 841 | display: flex; | ||
| 842 | justify-content: center; | ||
| 843 | align-items: center; | ||
| 844 | border-top: 1px solid #d9d9d9; | ||
| 845 | } | ||
| 846 | |||
| 847 | .row-add-btn { | ||
| 848 | .el-button--default { | ||
| 849 | padding: 4px 0px; | ||
| 850 | margin-top: 4px; | ||
| 851 | } | ||
| 852 | |||
| 853 | :deep(.el-icon) { | ||
| 854 | width: 16px; | ||
| 855 | height: 16px; | ||
| 856 | |||
| 857 | svg { | ||
| 858 | width: 16px; | ||
| 859 | height: 16px; | ||
| 860 | } | ||
| 861 | } | ||
| 862 | } | ||
| 863 | |||
| 864 | .h-title { | ||
| 865 | font-size: 14px; | ||
| 866 | color: #212121; | ||
| 867 | font-weight: 600; | ||
| 868 | margin-bottom: 4px; | ||
| 869 | } | ||
| 870 | </style> |
| 1 | <route lang="yaml"> | ||
| 2 | name: smartContractDetail | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="smartContractDetail"> | ||
| 6 | import { | ||
| 7 | getContractDetail, | ||
| 8 | getActionPolicyList, | ||
| 9 | getConstraintPolicyList, | ||
| 10 | getContractNegotiate, | ||
| 11 | getContractNegoPlicyByVersion, | ||
| 12 | continueContractNegotiate, | ||
| 13 | rejectContract, | ||
| 14 | confirmContract, | ||
| 15 | signContract, | ||
| 16 | getSignListInfo, | ||
| 17 | getContractExecList, | ||
| 18 | terminateContract, | ||
| 19 | getTerminateDetailInfo, | ||
| 20 | getSignatureFile | ||
| 21 | } from "@/api/modules/dataSmartContract"; | ||
| 22 | import { | ||
| 23 | tagMethod, | ||
| 24 | tagType | ||
| 25 | } from "@/utils/common"; | ||
| 26 | import { | ||
| 27 | getParamsList, | ||
| 28 | } from "@/api/modules/queryService"; | ||
| 29 | import { commonPageConfig, TableColumnWidth } from "@/utils/enum"; | ||
| 30 | import StrategyTable from './components/strategyTable.vue'; | ||
| 31 | import { onUploadFilePreview, onUploadFileDownload } from '@/api/modules/common'; | ||
| 32 | import { useValidator } from "@/hooks/useValidator"; | ||
| 33 | import useUserStore from "@/store/modules/user"; | ||
| 34 | import useDataSmartContract from "@/store/modules/dataSmartContract"; | ||
| 35 | import ConfirmDialog from "./components/confirmDialog.vue"; | ||
| 36 | import { getEnterpriseData } from "@/api/modules/dataIdentify"; | ||
| 37 | import showFile from "./components/showFile.vue"; | ||
| 38 | // @ts-ignore | ||
| 39 | import html2pdf from 'html2pdf.js'; | ||
| 40 | import { getPathUrl, getUpFileSignByUrl, obsUploadRequest } from "@/api/modules/obsService"; | ||
| 41 | import { ElMessage } from "element-plus"; | ||
| 42 | |||
| 43 | const { required, requiredFiles } = useValidator(); | ||
| 44 | const userStore = useUserStore(); | ||
| 45 | const userData = JSON.parse(localStorage.userData) | ||
| 46 | const tenantData = JSON.parse(localStorage.tenantInfo); | ||
| 47 | const dataSmartContract = useDataSmartContract(); | ||
| 48 | const router = useRouter(); | ||
| 49 | const route = useRoute(); | ||
| 50 | const fullPath = route.fullPath; | ||
| 51 | const fullscreenLoading = ref(false); | ||
| 52 | const expandBase = ref(false); | ||
| 53 | const expandInfo = ref(false); | ||
| 54 | const expandPolicy = ref(false); | ||
| 55 | const expandPolicyConsult = ref(false); | ||
| 56 | const expandConsultHistory = ref(false); | ||
| 57 | const expandSign = ref(false);//合约签署 | ||
| 58 | const expandKeep = ref(false);//合约履约执行信息 | ||
| 59 | const expandReject = ref(false);//合约解除 | ||
| 60 | const { proxy } = getCurrentInstance() as any; | ||
| 61 | const detailInfo: any = ref({}); | ||
| 62 | const detailType = ref(route.query.type); //为null表示第一步查看,其余协整和签署等需要传递type | ||
| 63 | const isDetail = ref(route.query.isDetail == 'Y'); | ||
| 64 | |||
| 65 | const toolBtns: any = computed(() => { | ||
| 66 | let btnsArr: any = [{ | ||
| 67 | label: isDetail.value ? "关闭" : '取消', value: "cancel", plain: true | ||
| 68 | }]; | ||
| 69 | let contractStatus = detailInfo.value.contractStatus; | ||
| 70 | if ((!detailType.value || currentStep.value == 1) && contractStatus == '01') { | ||
| 71 | btnsArr.push({ | ||
| 72 | label: "合约协商", value: "consult", type: 'primary' | ||
| 73 | }); | ||
| 74 | } | ||
| 75 | if (detailType.value == 'consult') { | ||
| 76 | btnsArr.push({ | ||
| 77 | label: "拒绝本次合约", value: "refuse", plain: true | ||
| 78 | }); | ||
| 79 | btnsArr.push({ | ||
| 80 | label: "确认本次合约", value: "confirm", type: 'primary', disabled: disableConfirmBtn.value | ||
| 81 | }); | ||
| 82 | btnsArr.push({ | ||
| 83 | label: "继续协商", value: "continue", type: 'primary', disabled: !disableConfirmBtn.value | ||
| 84 | }); | ||
| 85 | } else if (detailType.value == 'sign') { | ||
| 86 | btnsArr.push({ | ||
| 87 | label: "确定签署", value: "confirmSign", type: 'primary', disabled: !confirmAuth.value | ||
| 88 | }); | ||
| 89 | } else if (detailType.value == 'reject' && (!currentStep.value || currentStep.value == 5)) { | ||
| 90 | // btnsArr.push({ | ||
| 91 | // label: "上一步", value: "lastStep", plain: true | ||
| 92 | // }); | ||
| 93 | btnsArr.push({ | ||
| 94 | label: "确认提交", value: "confirmReject", type: 'primary' | ||
| 95 | }); | ||
| 96 | } | ||
| 97 | return btnsArr; | ||
| 98 | }); | ||
| 99 | |||
| 100 | const btnHandles = ref({ | ||
| 101 | 'cancel': () => { | ||
| 102 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | ||
| 103 | router.push({ | ||
| 104 | name: "smartContractManagement", | ||
| 105 | }); | ||
| 106 | }, | ||
| 107 | 'consult': () => { | ||
| 108 | if (!detailType.value) { | ||
| 109 | router.push({ | ||
| 110 | name: "smartContractManagement", | ||
| 111 | }); | ||
| 112 | return; | ||
| 113 | } | ||
| 114 | if (detailType.value == 'consult') { | ||
| 115 | currentStep.value = 2; | ||
| 116 | } | ||
| 117 | }, | ||
| 118 | 'refuse': () => { | ||
| 119 | confirmDialogInfo.value.type = 'fail'; | ||
| 120 | confirmDialogInfo.value.dialogVisible = true; | ||
| 121 | }, | ||
| 122 | 'continue': () => { //继续协商 | ||
| 123 | if (!strategyTableEditRef.value.validateValue()) { | ||
| 124 | return; | ||
| 125 | } | ||
| 126 | fullscreenLoading.value = true; | ||
| 127 | continueContractNegotiate({ | ||
| 128 | contractGuid: route.query.guid, | ||
| 129 | policys: strategyTableEditRef.value.strategyData?.map((d, index) => { | ||
| 130 | return Object.assign({}, d, { orderNum: index + 1 }) | ||
| 131 | }) | ||
| 132 | }).then((res: any) => { | ||
| 133 | fullscreenLoading.value = false; | ||
| 134 | if (res?.code == proxy.$passCode) { | ||
| 135 | proxy.$ElMessage.success('合约继续协商提交成功'); | ||
| 136 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | ||
| 137 | router.push({ | ||
| 138 | name: "smartContractManagement", | ||
| 139 | }); | ||
| 140 | dataSmartContract.set(true); | ||
| 141 | } else { | ||
| 142 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 143 | } | ||
| 144 | }) | ||
| 145 | }, | ||
| 146 | 'confirm': () => { //确认本次合约。如果还需另一方确认,就需要清空confirmGuids。 | ||
| 147 | confirmDialogInfo.value.type = detailInfo.value.signModeCode == '01' ? 'success' : (!detailInfo.value.confirmGuids?.length ? 'warning' : 'success'); | ||
| 148 | confirmDialogInfo.value.dialogVisible = true; | ||
| 149 | }, | ||
| 150 | 'confirmSign': () => { | ||
| 151 | signInfoFormRef.value?.ruleFormRef?.validate((valid, errorItem) => { | ||
| 152 | if (valid) { | ||
| 153 | if (!signFileUrlInfo.value?.url) { | ||
| 154 | proxy.$ElMessage.error('签署签名文件不能为空!'); | ||
| 155 | return; | ||
| 156 | } | ||
| 157 | let signFormInline = signInfoFormRef.value.formInline; | ||
| 158 | let params: any = { | ||
| 159 | contractGuid: route.query.guid, | ||
| 160 | signatureEntityGuid: userData.tenantGuid, | ||
| 161 | signatureEntityId: signTenantDetailInfo.value.socialCreditCode, | ||
| 162 | signatureEntityName: userData.tenantName, | ||
| 163 | identityCertificate: { url: signTenantDetailInfo.value.trustedIdentityCredential }, | ||
| 164 | signature: signFileUrlInfo.value?.url ? { | ||
| 165 | name: signFileUrlInfo.value.name, | ||
| 166 | url: signFileUrlInfo.value.url, | ||
| 167 | } : {}, | ||
| 168 | attachment: signFormInline.file?.length ? { | ||
| 169 | name: signFormInline.file[0].name, | ||
| 170 | url: signFormInline.file[0].url, | ||
| 171 | } : {}, | ||
| 172 | }; | ||
| 173 | fullscreenLoading.value = true; | ||
| 174 | signContract(params).then((res: any) => { | ||
| 175 | fullscreenLoading.value = false; | ||
| 176 | if (res?.code == proxy.$passCode) { | ||
| 177 | proxy.$ElMessage.success('合约确定签署成功'); | ||
| 178 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | ||
| 179 | router.push({ | ||
| 180 | name: "smartContractManagement", | ||
| 181 | }); | ||
| 182 | dataSmartContract.set(true); | ||
| 183 | } else { | ||
| 184 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 185 | } | ||
| 186 | }) | ||
| 187 | } else { | ||
| 188 | expandSign.value = true; | ||
| 189 | var obj = Object.keys(errorItem); | ||
| 190 | signInfoFormRef.value.ruleFormRef?.scrollToField(obj[0]); | ||
| 191 | } | ||
| 192 | }) | ||
| 193 | }, | ||
| 194 | 'lastStep': () => { | ||
| 195 | if (detailType.value == 'reject' && !currentStep.value) { | ||
| 196 | currentStep.value = 4; | ||
| 197 | } else { | ||
| 198 | currentStep.value--; | ||
| 199 | } | ||
| 200 | }, | ||
| 201 | 'confirmReject': () => { //确认解除合约 | ||
| 202 | //后端需要检验选择的合同约定终止时间不能大于合同生效时间 | ||
| 203 | rejectInfoFormRef.value.ruleFormRef?.validate((valid, errorItem) => { | ||
| 204 | if (valid) { | ||
| 205 | proxy.$openMessageBox('确认提交合约解除信息吗?', () => { | ||
| 206 | let params = { ...rejectInfoFormRef.value.formInline }; | ||
| 207 | let file = params.dataProcessingProof || []; | ||
| 208 | params.dataProcessingProof = { | ||
| 209 | name: file?.[0]?.name, | ||
| 210 | url: file?.[0]?.url | ||
| 211 | } | ||
| 212 | params.contractGuid = route.query.guid; | ||
| 213 | fullscreenLoading.value = true; | ||
| 214 | terminateContract(params).then((res: any) => { | ||
| 215 | fullscreenLoading.value = false; | ||
| 216 | if (res?.code == proxy.$passCode) { | ||
| 217 | proxy.$ElMessage.success('合约解除信息提交成功'); | ||
| 218 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | ||
| 219 | router.push({ | ||
| 220 | name: "smartContractManagement", | ||
| 221 | }); | ||
| 222 | dataSmartContract.set(true); | ||
| 223 | } else { | ||
| 224 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 225 | } | ||
| 226 | }) | ||
| 227 | }, () => { | ||
| 228 | proxy.$ElMessage.info("已取消"); | ||
| 229 | }); | ||
| 230 | } else { | ||
| 231 | var obj = Object.keys(errorItem); | ||
| 232 | rejectInfoFormRef.value.ruleFormRef.scrollToField(obj[0]) | ||
| 233 | } | ||
| 234 | }) | ||
| 235 | } | ||
| 236 | }); | ||
| 237 | |||
| 238 | const extendTableInfo = ref({ | ||
| 239 | id: "input-extend-table", | ||
| 240 | height: '214px', | ||
| 241 | fields: [ | ||
| 242 | { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" }, | ||
| 243 | { label: "扩展字段名称", field: "expansionFieldName", width: 160 }, | ||
| 244 | { label: "字段类型", field: "fieldTypeName", width: 140 }, | ||
| 245 | { label: "输入内容", field: "content", width: 300 }, | ||
| 246 | ], | ||
| 247 | data: [], | ||
| 248 | showPage: false, | ||
| 249 | actionInfo: { | ||
| 250 | show: false | ||
| 251 | }, | ||
| 252 | loading: false | ||
| 253 | }); | ||
| 254 | |||
| 255 | const exportExtendTableInfo = computed(() => { | ||
| 256 | return { | ||
| 257 | id: "export-input-extend-table", | ||
| 258 | height: 'auto', | ||
| 259 | minPanelHeight: '60px', | ||
| 260 | minHeight: '60px', | ||
| 261 | fields: [ | ||
| 262 | { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center", showTooltip: false }, | ||
| 263 | { label: "扩展字段名称", field: "expansionFieldName", width: "auto", minWidth: 140, showTooltip: false }, | ||
| 264 | { label: "字段类型", field: "fieldTypeName", width: "auto", minWidth: 100, showTooltip: false }, | ||
| 265 | { label: "输入内容", field: "content", width: "auto", minWidth: 250, showTooltip: false }, | ||
| 266 | ], | ||
| 267 | data: extendTableInfo.value.data, | ||
| 268 | showPage: false, | ||
| 269 | actionInfo: { | ||
| 270 | show: false | ||
| 271 | }, | ||
| 272 | loading: false | ||
| 273 | } | ||
| 274 | }); | ||
| 275 | |||
| 276 | const productTableInfo = ref({ | ||
| 277 | id: "input-product-table", | ||
| 278 | height: '214px', | ||
| 279 | fields: [ | ||
| 280 | { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" }, | ||
| 281 | { label: "数据产品", field: "dataProductName", width: 180 }, | ||
| 282 | { label: "数据产品编码", field: "dataProductId", width: 261 }, | ||
| 283 | { label: "所属主体名称", field: "dataProductEntityName", width: 240 }, | ||
| 284 | { label: "产品简介", field: "dataProductAbstract", width: 240 }, | ||
| 285 | ], | ||
| 286 | data: [], | ||
| 287 | showPage: false, | ||
| 288 | actionInfo: { | ||
| 289 | show: false | ||
| 290 | }, | ||
| 291 | loading: false | ||
| 292 | }); | ||
| 293 | |||
| 294 | |||
| 295 | const exportProductTableInfo = computed(() => { | ||
| 296 | return { | ||
| 297 | id: "export-input-product-table", | ||
| 298 | height: 'auto', | ||
| 299 | minPanelHeight: '60px', | ||
| 300 | minHeight: '60px', | ||
| 301 | fields: [ | ||
| 302 | { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center", showTooltip: false }, | ||
| 303 | { label: "数据产品", field: "dataProductName", minWidth: 120, showTooltip: false, width: "auto" }, | ||
| 304 | { label: "数据产品编码", field: "dataProductId", width: "auto", minWidth: 140, showTooltip: false }, | ||
| 305 | { label: "所属主体名称", field: "dataProductEntityName", width: "auto", minWidth: 150, showTooltip: false }, | ||
| 306 | { label: "产品简介", field: "dataProductAbstract", width: "auto", minWidth: 160, showTooltip: false }, | ||
| 307 | ], | ||
| 308 | data: productTableInfo.value.data, | ||
| 309 | showPage: false, | ||
| 310 | actionInfo: { | ||
| 311 | show: false | ||
| 312 | }, | ||
| 313 | loading: false | ||
| 314 | } | ||
| 315 | }); | ||
| 316 | |||
| 317 | |||
| 318 | const nodeInfoFormRef = ref(); | ||
| 319 | |||
| 320 | const nodeInfoFormItems = ref([{ | ||
| 321 | label: '策略执行者类型', | ||
| 322 | type: 'input', | ||
| 323 | placeholder: '请选择', | ||
| 324 | field: 'dataProviderType', | ||
| 325 | default: '数据供给方', | ||
| 326 | disabled: true, | ||
| 327 | visible: true | ||
| 328 | }, { | ||
| 329 | label: '策略执行者名称', | ||
| 330 | type: 'input', | ||
| 331 | placeholder: '请选择', | ||
| 332 | field: 'dataProviderName', | ||
| 333 | default: '', | ||
| 334 | options: [], | ||
| 335 | props: { | ||
| 336 | value: 'value', | ||
| 337 | label: 'label' | ||
| 338 | }, | ||
| 339 | filterable: true, | ||
| 340 | clearable: true, | ||
| 341 | required: true, | ||
| 342 | disabled: true, | ||
| 343 | visible: true | ||
| 344 | }, { | ||
| 345 | label: '策略执行者标识', | ||
| 346 | type: 'input', | ||
| 347 | placeholder: '请输入', | ||
| 348 | field: 'dataProviderId', | ||
| 349 | default: '', | ||
| 350 | disabled: true, | ||
| 351 | visible: true | ||
| 352 | }, { | ||
| 353 | label: '策略执行者类型', | ||
| 354 | type: 'input', | ||
| 355 | placeholder: '请选择', | ||
| 356 | field: 'dataUserType', | ||
| 357 | default: '数据使用方', | ||
| 358 | disabled: true, | ||
| 359 | visible: true | ||
| 360 | }, { | ||
| 361 | label: '策略执行者名称', | ||
| 362 | type: 'input', | ||
| 363 | placeholder: '请选择', | ||
| 364 | field: 'dataUserName', | ||
| 365 | default: '', | ||
| 366 | options: [], | ||
| 367 | props: { | ||
| 368 | value: 'value', | ||
| 369 | label: 'label' | ||
| 370 | }, | ||
| 371 | filterable: true, | ||
| 372 | clearable: true, | ||
| 373 | required: true, | ||
| 374 | disabled: true, | ||
| 375 | visible: true | ||
| 376 | }, { | ||
| 377 | label: '策略执行者标识', | ||
| 378 | type: 'input', | ||
| 379 | placeholder: '请输入', | ||
| 380 | field: 'dataUserId', | ||
| 381 | default: '', | ||
| 382 | disabled: true, | ||
| 383 | visible: true | ||
| 384 | }]) | ||
| 385 | |||
| 386 | const currentStep = ref(0); | ||
| 387 | |||
| 388 | const handleClickStep = (number) => { | ||
| 389 | currentStep.value = number; | ||
| 390 | } | ||
| 391 | |||
| 392 | /** ---------------------- 合约协商 ------------------------- */ | ||
| 393 | const strategyTableEditRef = ref(); | ||
| 394 | |||
| 395 | /** 时间线列表 */ | ||
| 396 | const activities: any = ref([]); | ||
| 397 | |||
| 398 | const detailDialogInfo = ref({ | ||
| 399 | visible: false, | ||
| 400 | size: 800, | ||
| 401 | direction: "column", | ||
| 402 | header: { | ||
| 403 | title: "查看版本详情", | ||
| 404 | }, | ||
| 405 | type: '',//标识是否是重新提交 | ||
| 406 | contents: [], | ||
| 407 | footer: { | ||
| 408 | show: false | ||
| 409 | }, | ||
| 410 | contentLoading: false, | ||
| 411 | }); | ||
| 412 | |||
| 413 | const versionDetail: any = ref([]); | ||
| 414 | |||
| 415 | const clickVersion = (child) => { | ||
| 416 | detailDialogInfo.value.visible = true; | ||
| 417 | detailDialogInfo.value.header.title = '查看版本详情' + '(' + child.version + ')'; | ||
| 418 | detailDialogInfo.value.contentLoading = true; | ||
| 419 | getContractNegoPlicyByVersion({ | ||
| 420 | guid: route.query.guid, | ||
| 421 | version: child.version | ||
| 422 | }).then((res: any) => { | ||
| 423 | detailDialogInfo.value.contentLoading = false; | ||
| 424 | if (res?.code == proxy.$passCode) { | ||
| 425 | const data = res.data || []; | ||
| 426 | versionDetail.value = data; | ||
| 427 | } else { | ||
| 428 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 429 | } | ||
| 430 | }) | ||
| 431 | } | ||
| 432 | |||
| 433 | const handleVersionDialogBtnClick = (btn) => { | ||
| 434 | if (btn.value == 'cancel') { | ||
| 435 | detailDialogInfo.value.visible = false; | ||
| 436 | } | ||
| 437 | } | ||
| 438 | |||
| 439 | const disableConfirmBtn = computed(() => { | ||
| 440 | let newValue = strategyTableEditRef.value?.strategyData || []; | ||
| 441 | let originValue = consultDetailInfo.value.policys || []; | ||
| 442 | if (newValue.length != originValue.length) { | ||
| 443 | return true; | ||
| 444 | } | ||
| 445 | let index = 0; | ||
| 446 | for (const newItem of newValue) { | ||
| 447 | let oldItem = originValue[index]; | ||
| 448 | if (newItem.action != oldItem.action || newItem.constraintEnName != oldItem.constraintEnName || | ||
| 449 | newItem.constraintOperatorCode != oldItem.constraintOperatorCode || newItem.constraintValue != oldItem.constraintValue) { | ||
| 450 | return true; | ||
| 451 | } | ||
| 452 | index++; | ||
| 453 | } | ||
| 454 | }) | ||
| 455 | |||
| 456 | const confirmDialogInfo = ref({ | ||
| 457 | dialogVisible: false, | ||
| 458 | type: 'success', | ||
| 459 | msg: { | ||
| 460 | 'success': '确认合约表示您已仔细查阅并接受本次合约所有相关信息,确定提交后将为您跳转合约签署环节。\n如有疑问可取消操作。', | ||
| 461 | 'warning': '确认合约表示您已仔细查阅并接受本次合约所有相关信息,确定提交后待对方确认合约后再进入签署环节。', | ||
| 462 | 'fail': '拒绝后将终止本次合约协商流程,请谨慎操作。\n如有疑问可联络合约发起方详细咨询。' | ||
| 463 | }, | ||
| 464 | }); | ||
| 465 | |||
| 466 | const handleConfirmDialog = (btn) => { | ||
| 467 | if (btn == 'submit') { | ||
| 468 | confirmDialogInfo.value.dialogVisible = false; | ||
| 469 | if (confirmDialogInfo.value.type == 'fail') { | ||
| 470 | fullscreenLoading.value = true; | ||
| 471 | rejectContract(route.query.guid).then((res: any) => { | ||
| 472 | fullscreenLoading.value = false; | ||
| 473 | if (res?.code == proxy.$passCode) { | ||
| 474 | proxy.$ElMessage.success('拒绝本次合约提交成功'); | ||
| 475 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | ||
| 476 | router.push({ | ||
| 477 | name: "smartContractManagement", | ||
| 478 | }); | ||
| 479 | dataSmartContract.set(true); | ||
| 480 | } else { | ||
| 481 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 482 | } | ||
| 483 | }) | ||
| 484 | } else { | ||
| 485 | fullscreenLoading.value = true; | ||
| 486 | confirmContract(route.query.guid).then((res: any) => { | ||
| 487 | fullscreenLoading.value = false; | ||
| 488 | if (res?.code == proxy.$passCode) { | ||
| 489 | proxy.$ElMessage.success('确认本次合约成功'); | ||
| 490 | userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath)); | ||
| 491 | router.push({ | ||
| 492 | name: "smartContractManagement", | ||
| 493 | }); | ||
| 494 | dataSmartContract.set(true); | ||
| 495 | } else { | ||
| 496 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 497 | } | ||
| 498 | }) | ||
| 499 | } | ||
| 500 | } else { | ||
| 501 | confirmDialogInfo.value.dialogVisible = false | ||
| 502 | } | ||
| 503 | } | ||
| 504 | |||
| 505 | /** ------------------------- 合约签署 -------------------------- */ | ||
| 506 | const confirmAuth = ref(false); //是否勾选确权 | ||
| 507 | |||
| 508 | const signInfoFormRef = ref(); | ||
| 509 | |||
| 510 | const signInfoFormItems = ref([{ | ||
| 511 | label: '附件上传', | ||
| 512 | tip: '文件大小不超过20MB', | ||
| 513 | type: 'upload-file', | ||
| 514 | limitSize: 20, | ||
| 515 | required: false, | ||
| 516 | default: [], | ||
| 517 | block: true, | ||
| 518 | field: 'file', | ||
| 519 | }, | ||
| 520 | // { | ||
| 521 | // label: '签署签名', | ||
| 522 | // tip: '文件大小不超过20MB', | ||
| 523 | // type: 'upload-file', | ||
| 524 | // limitSize: 20, | ||
| 525 | // limit: 1, | ||
| 526 | // required: true, | ||
| 527 | // default: [], | ||
| 528 | // block: false, | ||
| 529 | // field: 'signFile', | ||
| 530 | // }, | ||
| 531 | // { | ||
| 532 | // label: '签署时间', | ||
| 533 | // type: 'input', | ||
| 534 | // placeholder: '确定签署提交的时间', | ||
| 535 | // field: 'submitTime', | ||
| 536 | // default: '', | ||
| 537 | // maxlength: 50, | ||
| 538 | // disabled: true | ||
| 539 | // }, | ||
| 540 | ]); | ||
| 541 | |||
| 542 | const signInfoFormRules = ref({ | ||
| 543 | // signFile: [{ | ||
| 544 | // validator: (rule: any, value: any, callback: any) => { | ||
| 545 | // if (!value?.length) { | ||
| 546 | // callback(new Error('请上传文件')) | ||
| 547 | // } else { | ||
| 548 | // callback(); | ||
| 549 | // } | ||
| 550 | // }, trigger: 'change' | ||
| 551 | // }], | ||
| 552 | }); | ||
| 553 | |||
| 554 | const viewResultVoucherFile = (url) => { | ||
| 555 | if (!url) { | ||
| 556 | proxy.$ElMessage.error('暂无可查看的身份凭证证书'); | ||
| 557 | return; | ||
| 558 | } | ||
| 559 | onUploadFilePreview(url); | ||
| 560 | } | ||
| 561 | |||
| 562 | const signFileLoading = ref(false); | ||
| 563 | |||
| 564 | const signFileUrlInfo: any = ref({ name: '', url: '' }); | ||
| 565 | |||
| 566 | function getElementPdfPosition(element, options = {}) { | ||
| 567 | const { scale = 2, pageHeightPt = 842 } = options; | ||
| 568 | |||
| 569 | // 1. 获取元素距离容器顶部的像素距离 | ||
| 570 | const container = document.getElementById('pdf-container'); // 你的根容器 | ||
| 571 | const rect = element.getBoundingClientRect(); | ||
| 572 | const containerRect = container.getBoundingClientRect(); | ||
| 573 | const topPx = rect.top - containerRect.top + window.scrollY; | ||
| 574 | |||
| 575 | // 2. html2canvas 默认使用 devicePixelRatio,但 html2pdf 通常固定 scale | ||
| 576 | // html2pdf 内部会将 canvas 高度按比例缩放到 PDF 页面宽度 | ||
| 577 | // 简化模型:假设 PDF 宽度 = 595pt (A4),对应 canvas.width / scale px | ||
| 578 | |||
| 579 | const pdfPageWidthPt = 595; // A4 width in pt | ||
| 580 | const containerWidthPx = container.offsetWidth; | ||
| 581 | const pxToPtRatio = pdfPageWidthPt / containerWidthPx; // 每像素多少 pt | ||
| 582 | |||
| 583 | const topPt = topPx * pxToPtRatio; | ||
| 584 | |||
| 585 | // 3. 计算落在第几页 & 页内 Y 坐标 | ||
| 586 | const page = Math.floor(topPt / pageHeightPt) + 1; | ||
| 587 | const yInPage = topPt % pageHeightPt; | ||
| 588 | |||
| 589 | return { | ||
| 590 | page, | ||
| 591 | x: rect.left * pxToPtRatio, // 可选 X 坐标 | ||
| 592 | y: yInPage, | ||
| 593 | totalY: topPt | ||
| 594 | }; | ||
| 595 | } | ||
| 596 | |||
| 597 | |||
| 598 | const geneSignFile = async () => { | ||
| 599 | const element = document.getElementById('pdf-content'); // 指定要转PDF的DOM | ||
| 600 | if (!element) { | ||
| 601 | proxy.$ElMessage.error('找不到生成pdf文件的网页内容'); | ||
| 602 | return; | ||
| 603 | } | ||
| 604 | signFileLoading.value = true; | ||
| 605 | element.style.display = ''; | ||
| 606 | await nextTick(); | ||
| 607 | setTimeout(async () => { | ||
| 608 | let fileName = detailInfo.value.contractName + '_' + tenantData.abbreviation + '.pdf'; | ||
| 609 | const options = { | ||
| 610 | margin: [10, 3, 10, 3], | ||
| 611 | filename: fileName, | ||
| 612 | image: { | ||
| 613 | type: 'jpeg', | ||
| 614 | quality: 0.9 | ||
| 615 | }, | ||
| 616 | html2canvas: { | ||
| 617 | scale: 2, | ||
| 618 | useCORS: true, | ||
| 619 | allowTaint: false, | ||
| 620 | logging: false, | ||
| 621 | backgroundColor: '#ffffff' | ||
| 622 | }, | ||
| 623 | jsPDF: { | ||
| 624 | unit: 'pt', | ||
| 625 | format: 'a4', | ||
| 626 | orientation: 'portrait' | ||
| 627 | }, | ||
| 628 | // 防止文字被切断的关键配置 | ||
| 629 | pagebreak: { | ||
| 630 | mode: ['css', 'avoid-all', 'legacy'], | ||
| 631 | avoid: ['.avoid-break', '.el-card__header'] | ||
| 632 | } | ||
| 633 | }; | ||
| 634 | |||
| 635 | // 方法1: 直接生成并下载 | ||
| 636 | try { | ||
| 637 | html2pdf().from(element).set(options).toPdf().get('pdf').then(pdf => { | ||
| 638 | let totalPages = pdf.internal.getNumberOfPages(); | ||
| 639 | |||
| 640 | // 获取最后一页的结束位置 | ||
| 641 | for (let i = 1; i <= totalPages; i++) { | ||
| 642 | pdf.setPage(i); | ||
| 643 | } | ||
| 644 | |||
| 645 | const pageInfo = pdf.internal.getCurrentPageInfo(); | ||
| 646 | |||
| 647 | const pdfPageWidthPt = parseInt(pageInfo.pageContext?.mediaBox?.topRightX); // A4 width in pt | ||
| 648 | const pageHeightPt = parseInt(pageInfo.pageContext?.mediaBox?.topRightY); | ||
| 649 | const containerWidthPx = element.offsetWidth; | ||
| 650 | let lastThree: any = element.children[3];//产品 | ||
| 651 | let lastCont: any = element.children[4]; | ||
| 652 | let lastEle: any = element.children[5]; | ||
| 653 | const pxToPtRatio = pdfPageWidthPt / containerWidthPx; // 每像素多少 pt | ||
| 654 | const topPt = element.offsetHeight * pxToPtRatio; | ||
| 655 | let yInPage: any = 0; | ||
| 656 | if (totalPages == 1) { | ||
| 657 | yInPage = pageHeightPt - 20; | ||
| 658 | } else if (totalPages == 2) { | ||
| 659 | if ((element.children[0].offsetHeight + element.children[2].offsetHeight + lastThree.offsetHeight) * pxToPtRatio > (pageHeightPt + 25) ) { | ||
| 660 | //第一页装不下产品。 | ||
| 661 | yInPage = (Math.ceil((lastThree.offsetHeight + lastCont.offsetHeight) * pxToPtRatio) + 150) | ||
| 662 | } else if ((element.offsetHeight - lastEle.offsetHeight) * pxToPtRatio > (pageHeightPt + 25)) { //装不下策略信息 | ||
| 663 | yInPage = (Math.ceil(lastCont.offsetHeight * pxToPtRatio) + 150); | ||
| 664 | } else { | ||
| 665 | yInPage = 70; | ||
| 666 | } | ||
| 667 | } else if (totalPages == 3) { | ||
| 668 | yInPage = Math.ceil(pageHeightPt / 2); | ||
| 669 | } | ||
| 670 | |||
| 671 | let blob = pdf.output('blob'); | ||
| 672 | const formData = new FormData(); | ||
| 673 | formData.append('image', blob, fileName); // 可以指定文件名 | ||
| 674 | getSignatureFile(formData, { pageIndex: totalPages, yPosition: yInPage }).then((res: any) => { | ||
| 675 | if (res?.code == proxy.$passCode) { | ||
| 676 | if (!res.data) { | ||
| 677 | signFileLoading.value = false; | ||
| 678 | proxy.$ElMessage.error('生成的签名文件为空'); | ||
| 679 | return; | ||
| 680 | } | ||
| 681 | // 将 base64 转换为二进制数据 | ||
| 682 | const byteCharacters = atob(res.data); | ||
| 683 | const byteArrays: any = []; | ||
| 684 | |||
| 685 | for (let offset = 0; offset < byteCharacters.length; offset += 512) { | ||
| 686 | const slice = byteCharacters.slice(offset, offset + 512); | ||
| 687 | const byteNumbers = new Array(slice.length); | ||
| 688 | |||
| 689 | for (let i = 0; i < slice.length; i++) { | ||
| 690 | byteNumbers[i] = slice.charCodeAt(i); | ||
| 691 | } | ||
| 692 | |||
| 693 | const byteArray = new Uint8Array(byteNumbers); | ||
| 694 | byteArrays.push(byteArray); | ||
| 695 | } | ||
| 696 | |||
| 697 | // 创建 Blob 然后转换为 File | ||
| 698 | const blob = new Blob(byteArrays, { type: 'application/pdf' }); | ||
| 699 | let fileObject = new File([blob], fileName, { type: 'application/pdf' }); | ||
| 700 | getUpFileSignByUrl({ fileName: fileName }) | ||
| 701 | .then((res: any) => { | ||
| 702 | obsUploadRequest({ | ||
| 703 | signedUrl: res.data.signedUrl, | ||
| 704 | file: fileObject, | ||
| 705 | actualSignedRequestHeaders: res.data.actualSignedRequestHeaders | ||
| 706 | }).then(() => { | ||
| 707 | signFileLoading.value = false; | ||
| 708 | if (res.code == '00000') { | ||
| 709 | const fileUrl = res.data.signedUrl ? getPathUrl(res.data.signedUrl) : ''; | ||
| 710 | signFileUrlInfo.value = { | ||
| 711 | name: fileName, | ||
| 712 | url: fileUrl | ||
| 713 | }; | ||
| 714 | ElMessage.success('生成成功'); | ||
| 715 | } else { | ||
| 716 | signFileLoading.value = false; | ||
| 717 | ElMessage.error('文件生成失败!'); | ||
| 718 | } | ||
| 719 | }) | ||
| 720 | }) | ||
| 721 | .catch(() => { | ||
| 722 | signFileLoading.value = false; | ||
| 723 | ElMessage.error('文件生成失败'); | ||
| 724 | }); | ||
| 725 | // downloadPdf(res.data || '') | ||
| 726 | } else { | ||
| 727 | signFileLoading.value = false; | ||
| 728 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 729 | } | ||
| 730 | }) | ||
| 731 | }) | ||
| 732 | } catch { | ||
| 733 | signFileLoading.value = false; | ||
| 734 | } | ||
| 735 | }, 50) | ||
| 736 | } | ||
| 737 | |||
| 738 | const deleteSignFile = () => { | ||
| 739 | proxy.$openMessageBox('确定要删除该签名文件吗?', () => { | ||
| 740 | signFileUrlInfo.value = {}; | ||
| 741 | proxy.$ElMessage({ | ||
| 742 | type: "success", | ||
| 743 | message: "删除成功", | ||
| 744 | }); | ||
| 745 | }, () => { | ||
| 746 | proxy.$ElMessage.info("已取消删除"); | ||
| 747 | }) | ||
| 748 | } | ||
| 749 | |||
| 750 | /** ------------------------- 履约信息 ------------------------- */ | ||
| 751 | |||
| 752 | const execContractTableInfo = ref({ | ||
| 753 | id: "exec-contract-table", | ||
| 754 | height: '214px', | ||
| 755 | fields: <any[]>[ | ||
| 756 | { label: "序号", type: "index", width: TableColumnWidth.INDEX, align: "center" }, | ||
| 757 | { label: "策略id", field: "strategyId", width: 260 }, | ||
| 758 | { label: "操作行为", field: "action", width: 120 }, | ||
| 759 | { label: "操作行为英文名称", field: "actionEnName", width: 140 }, | ||
| 760 | { label: "约束条件", field: "constraintName", width: 120 }, | ||
| 761 | { label: "约束条件英文名称", field: "constraintEnName", width: 140 }, | ||
| 762 | { label: "约束条件运算符", field: "constraintOperatorCodeName", width: 140 }, | ||
| 763 | { label: "约束条件值", field: "constraintValue", width: 150 }, | ||
| 764 | { label: "执行结果", field: "result", width: 130 }, | ||
| 765 | { label: "上报时间", field: "reportingTime", width: 170 }, | ||
| 766 | ], | ||
| 767 | data: [], | ||
| 768 | showPage: true, | ||
| 769 | page: { | ||
| 770 | type: "normal", | ||
| 771 | rows: 0, | ||
| 772 | ...commonPageConfig, | ||
| 773 | }, | ||
| 774 | actionInfo: { | ||
| 775 | show: false | ||
| 776 | }, | ||
| 777 | loading: false | ||
| 778 | }); | ||
| 779 | |||
| 780 | const pageChange = (info) => { | ||
| 781 | execContractTableInfo.value.page.curr = Number(info.curr); | ||
| 782 | execContractTableInfo.value.page.limit = Number(info.limit); | ||
| 783 | getStepFourExecInfo(); | ||
| 784 | }; | ||
| 785 | |||
| 786 | /** ------------------ 合约解除 ----------------------- */ | ||
| 787 | const rejectInfoFormRef = ref(); | ||
| 788 | const terminateTypeList: any = ref([]); | ||
| 789 | |||
| 790 | const rejectInfoFormItems = ref([{ | ||
| 791 | label: '解除类型', //合约解除类型 | ||
| 792 | type: 'select', | ||
| 793 | placeholder: '请选择', | ||
| 794 | field: 'terminateTypeCode', | ||
| 795 | default: 'TQ', | ||
| 796 | options: terminateTypeList.value, | ||
| 797 | filterable: true, | ||
| 798 | required: true, | ||
| 799 | visible: true, | ||
| 800 | disabled: false | ||
| 801 | }, { | ||
| 802 | label: '合约生效时间', | ||
| 803 | type: 'input', | ||
| 804 | placeholder: '-', | ||
| 805 | field: 'activationTime', | ||
| 806 | default: '', | ||
| 807 | disabled: true, | ||
| 808 | visible: true | ||
| 809 | }, { | ||
| 810 | label: '合约终止时间', | ||
| 811 | type: 'input', | ||
| 812 | placeholder: '-', | ||
| 813 | field: 'scheduledEndTime', | ||
| 814 | default: '', | ||
| 815 | disabled: true, | ||
| 816 | visible: true | ||
| 817 | }, { | ||
| 818 | label: "合同约定终止时间", | ||
| 819 | type: "datetime", | ||
| 820 | field: "agreedEndTime", | ||
| 821 | defaultTime: new Date(2000, 1, 1, 23, 59, 59), | ||
| 822 | default: null, | ||
| 823 | placeholder: "请选择", | ||
| 824 | clearable: true, | ||
| 825 | // disabledDate: (date) => { | ||
| 826 | // const today = new Date(); | ||
| 827 | // // 将 today 设置为 00:00:00,只比较日期部分(本地时间) | ||
| 828 | // const todayStart = new Date( | ||
| 829 | // today.getFullYear(), | ||
| 830 | // today.getMonth(), | ||
| 831 | // today.getDate() | ||
| 832 | // ); | ||
| 833 | |||
| 834 | // // 将 date 也转换为本地日期的开始时间(避免 UTC 问题) | ||
| 835 | // const dateStart = new Date( | ||
| 836 | // date.getFullYear(), | ||
| 837 | // date.getMonth(), | ||
| 838 | // date.getDate() | ||
| 839 | // ); | ||
| 840 | |||
| 841 | // // 禁用 dateStart < todayStart 的日期(即今天之前) | ||
| 842 | // return dateStart.getTime() < todayStart.getTime(); | ||
| 843 | // }, | ||
| 844 | visible: true, //提前解除才展示 | ||
| 845 | required: true, | ||
| 846 | }, { | ||
| 847 | label: '合约解除原因', | ||
| 848 | type: 'textarea', | ||
| 849 | placeholder: '请输入', | ||
| 850 | field: 'issueReason', | ||
| 851 | default: '', | ||
| 852 | rows: 2, | ||
| 853 | clearable: true, | ||
| 854 | required: true, | ||
| 855 | block: true, | ||
| 856 | visible: true, //提前解除才展示 | ||
| 857 | maxlength: 200 | ||
| 858 | }, { | ||
| 859 | label: '数据处理方式', | ||
| 860 | type: 'textarea', | ||
| 861 | placeholder: '请输入', | ||
| 862 | field: 'dataProcessingMethod', | ||
| 863 | default: '', | ||
| 864 | clearable: true, | ||
| 865 | required: true, | ||
| 866 | rows: 2, | ||
| 867 | block: true, | ||
| 868 | visible: true, | ||
| 869 | maxlength: 200 | ||
| 870 | }, { | ||
| 871 | label: '数据处理指令', | ||
| 872 | type: 'textarea', | ||
| 873 | placeholder: '请输入', | ||
| 874 | field: 'dataProcessingInstructions', | ||
| 875 | default: '', | ||
| 876 | clearable: true, | ||
| 877 | required: true, | ||
| 878 | rows: 2, | ||
| 879 | block: true, | ||
| 880 | visible: true, | ||
| 881 | maxlength: 200 | ||
| 882 | }, { | ||
| 883 | label: "数据处理证明", | ||
| 884 | tip: "单个文件不得大于20M", | ||
| 885 | type: "upload-file", | ||
| 886 | limitSize: 20, | ||
| 887 | limit: 1, | ||
| 888 | default: [], | ||
| 889 | field: "dataProcessingProof", | ||
| 890 | required: true, | ||
| 891 | },]); | ||
| 892 | |||
| 893 | const rejectInfoFormRules = ref({ | ||
| 894 | terminateTypeCode: [required('请选择解除类型')], | ||
| 895 | agreedEndTime: [required('请选择合同约定终止时间')], | ||
| 896 | issueReason: [required('请填写合同解除原因')], | ||
| 897 | dataProcessingMethod: [required('请填写数据处理方式')], | ||
| 898 | dataProcessingInstructions: [required('请填写数据处理指令')], | ||
| 899 | dataProcessingProof: [requiredFiles()], | ||
| 900 | }); | ||
| 901 | |||
| 902 | const handleRejectFormSelectChange = (val, row, info) => { | ||
| 903 | if (row.field == 'terminateTypeCode') { | ||
| 904 | rejectInfoFormItems.value[3].visible = val == 'TQ'; | ||
| 905 | rejectInfoFormItems.value[4].visible = val == 'TQ'; | ||
| 906 | rejectInfoFormItems.value.forEach(item => { | ||
| 907 | item.default = info[item.field]; | ||
| 908 | }) | ||
| 909 | } | ||
| 910 | } | ||
| 911 | |||
| 912 | /** --- 合约协商信息 -- */ | ||
| 913 | const consultDetailInfo: any = ref({}); | ||
| 914 | |||
| 915 | /** 约束运算符字典下拉 */ | ||
| 916 | const operatorOptionList: any = ref([]); | ||
| 917 | |||
| 918 | /** 约束行为下拉列表 */ | ||
| 919 | const constraintOptionsList: any = ref([]); | ||
| 920 | |||
| 921 | /** 策略操作行为下拉列表 */ | ||
| 922 | const actionOptionsList: any = ref([]); | ||
| 923 | |||
| 924 | /** 获取第二步合约协商信息 */ | ||
| 925 | const getStepTwoNegotiateInfo = (loading = true) => { | ||
| 926 | fullscreenLoading.value = true; | ||
| 927 | getContractNegotiate(route.query.guid).then((res: any) => { | ||
| 928 | loading && (fullscreenLoading.value = false); | ||
| 929 | if (res?.code == proxy.$passCode) { | ||
| 930 | consultDetailInfo.value = res.data || {}; | ||
| 931 | let negotiateRecord = consultDetailInfo.value.negotiateRecord || {}; | ||
| 932 | activities.value = []; | ||
| 933 | for (const key in negotiateRecord) { | ||
| 934 | activities.value.push({ | ||
| 935 | timestamp: key, | ||
| 936 | type: 'primary', | ||
| 937 | hollow: true, | ||
| 938 | children: negotiateRecord[key] || [] | ||
| 939 | }) | ||
| 940 | } | ||
| 941 | } else { | ||
| 942 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 943 | } | ||
| 944 | }) | ||
| 945 | } | ||
| 946 | |||
| 947 | /** 已签署过的详情信息 */ | ||
| 948 | const signDetailInfo: any = ref([]); | ||
| 949 | |||
| 950 | const getStepThreeSignInfo = () => { | ||
| 951 | fullscreenLoading.value = true; | ||
| 952 | return getSignListInfo(route.query.guid).then((res: any) => { | ||
| 953 | // fullscreenLoading.value = false; | ||
| 954 | if (res?.code == proxy.$passCode) { | ||
| 955 | signDetailInfo.value = res.data || []; | ||
| 956 | } else { | ||
| 957 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 958 | } | ||
| 959 | }) | ||
| 960 | } | ||
| 961 | |||
| 962 | /** 履约证明信息 */ | ||
| 963 | // const execProofDetailInfo: any = ref({}); | ||
| 964 | |||
| 965 | /** 获取履约执行信息和证明信息 */ | ||
| 966 | const getStepFourExecInfo = () => { | ||
| 967 | // getContractProof(route.query.guid).then((res: any) => { | ||
| 968 | // if (res?.code == proxy.$passCode) { | ||
| 969 | // execProofDetailInfo.value = res.data || {}; | ||
| 970 | // } else { | ||
| 971 | // res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 972 | // } | ||
| 973 | // }) | ||
| 974 | execContractTableInfo.value.loading = true; | ||
| 975 | getContractExecList({ | ||
| 976 | contractGuid: route.query.guid, | ||
| 977 | pageIndex: execContractTableInfo.value.page.curr, | ||
| 978 | pageSize: execContractTableInfo.value.page.limit, | ||
| 979 | }).then((res: any) => { | ||
| 980 | execContractTableInfo.value.loading = false; | ||
| 981 | if (res?.code == proxy.$passCode) { | ||
| 982 | const data = res.data || {}; | ||
| 983 | execContractTableInfo.value.data = data.records || [] | ||
| 984 | execContractTableInfo.value.page.limit = data.pageSize | ||
| 985 | execContractTableInfo.value.page.curr = data.pageIndex | ||
| 986 | execContractTableInfo.value.page.rows = data.totalRows | ||
| 987 | } else { | ||
| 988 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 989 | } | ||
| 990 | }) | ||
| 991 | } | ||
| 992 | |||
| 993 | /** 终止合约信息详情 */ | ||
| 994 | const terminateDetailInfo: any = ref({}); | ||
| 995 | |||
| 996 | /** 获取第五步终止合约信息详情 */ | ||
| 997 | const getStepTerminateInfo = () => { | ||
| 998 | fullscreenLoading.value = true; | ||
| 999 | getTerminateDetailInfo(route.query.guid).then((res: any) => { | ||
| 1000 | fullscreenLoading.value = false; | ||
| 1001 | if (res?.code == proxy.$passCode) { | ||
| 1002 | terminateDetailInfo.value = res.data || {}; | ||
| 1003 | } else { | ||
| 1004 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 1005 | } | ||
| 1006 | }) | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | /** 企业注册认证信息详情,供签署时显示 */ | ||
| 1010 | const signTenantDetailInfo: any = ref({}); | ||
| 1011 | |||
| 1012 | onBeforeMount(() => { | ||
| 1013 | if (isDetail.value) { //若是查看详情,默认都展示第一步。 | ||
| 1014 | currentStep.value = 1; | ||
| 1015 | } | ||
| 1016 | fullscreenLoading.value = true; | ||
| 1017 | let detailPs = getContractDetail(route.query.guid).then((res: any) => { | ||
| 1018 | detailType.value != 'sign' && (fullscreenLoading.value = false); | ||
| 1019 | if (res?.code == proxy.$passCode) { | ||
| 1020 | detailInfo.value = res.data || {}; | ||
| 1021 | if (isDetail.value || detailType.value == 'reject') { | ||
| 1022 | detailInfo.value.negotiateEntityGuid && getStepTwoNegotiateInfo(); | ||
| 1023 | detailInfo.value.signatureList?.length && getStepThreeSignInfo(); | ||
| 1024 | detailInfo.value.contractStatus == '05' && getStepFourExecInfo(); | ||
| 1025 | detailInfo.value.contractStatus == '06' && getStepFourExecInfo(); | ||
| 1026 | detailInfo.value.contractStatus == '06' && getStepTerminateInfo(); | ||
| 1027 | } | ||
| 1028 | let executionNodes = detailInfo.value.executionNodes || []; | ||
| 1029 | let provider = executionNodes.find(e => e.executionerTypeCode == '01'); | ||
| 1030 | let user = executionNodes.find(e => e.executionerTypeCode == '02'); | ||
| 1031 | nodeInfoFormItems.value[0].default = provider.executionerTypeName; | ||
| 1032 | nodeInfoFormItems.value[1].default = provider.executionerName; | ||
| 1033 | nodeInfoFormItems.value[2].default = provider.executionerId; | ||
| 1034 | nodeInfoFormItems.value[3].default = user.executionerTypeName; | ||
| 1035 | nodeInfoFormItems.value[4].default = user.executionerName; | ||
| 1036 | nodeInfoFormItems.value[5].default = user.executionerId; | ||
| 1037 | extendTableInfo.value.data = detailInfo.value.contractExpansions || []; | ||
| 1038 | productTableInfo.value.data = detailInfo.value.contractSubjects || []; | ||
| 1039 | } else { | ||
| 1040 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 1041 | } | ||
| 1042 | }) | ||
| 1043 | // 企业来做协商处理,先调用详情接口。 | ||
| 1044 | if (detailType.value == 'consult') { | ||
| 1045 | getStepTwoNegotiateInfo(); | ||
| 1046 | getParamsList({ dictType: '约束运算符' }).then((res: any) => { | ||
| 1047 | if (res?.code == proxy.$passCode) { | ||
| 1048 | const data = res.data || []; | ||
| 1049 | operatorOptionList.value = data; | ||
| 1050 | } else { | ||
| 1051 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 1052 | } | ||
| 1053 | }) | ||
| 1054 | getActionPolicyList().then((res: any) => { | ||
| 1055 | if (res?.code == proxy.$passCode) { | ||
| 1056 | const data = res.data || []; | ||
| 1057 | actionOptionsList.value = data; | ||
| 1058 | } else { | ||
| 1059 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 1060 | } | ||
| 1061 | }) | ||
| 1062 | getConstraintPolicyList().then((res: any) => { | ||
| 1063 | if (res?.code == proxy.$passCode) { | ||
| 1064 | const data = res.data || []; | ||
| 1065 | constraintOptionsList.value = data; | ||
| 1066 | } else { | ||
| 1067 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 1068 | } | ||
| 1069 | }) | ||
| 1070 | } else if (detailType.value == 'sign') { | ||
| 1071 | getStepTwoNegotiateInfo(false); | ||
| 1072 | fullscreenLoading.value = true; | ||
| 1073 | detailPs.then(() => { | ||
| 1074 | fullscreenLoading.value = true; | ||
| 1075 | let psSign = getStepThreeSignInfo(); | ||
| 1076 | let psLogon = getEnterpriseData({ | ||
| 1077 | logonUser: userData.tenantName == "非认证会员" ? userData.logonUser : tenantData.logonUser | ||
| 1078 | }).then((res: any) => { | ||
| 1079 | if (res?.code == proxy.$passCode) { | ||
| 1080 | signTenantDetailInfo.value = res.data || {}; | ||
| 1081 | } else { | ||
| 1082 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 1083 | } | ||
| 1084 | }); | ||
| 1085 | Promise.all([psSign, psLogon]).then(() => { | ||
| 1086 | fullscreenLoading.value = false; | ||
| 1087 | }).catch(() => { | ||
| 1088 | fullscreenLoading.value = false; | ||
| 1089 | }) | ||
| 1090 | }) | ||
| 1091 | } else if (detailType.value == 'reject') { | ||
| 1092 | let psType = getParamsList({ dictType: '合约解除类型' }).then((res: any) => { | ||
| 1093 | if (res?.code == proxy.$passCode) { | ||
| 1094 | const data = res.data || []; | ||
| 1095 | terminateTypeList.value = data; | ||
| 1096 | rejectInfoFormItems.value[0].options = terminateTypeList.value; | ||
| 1097 | } else { | ||
| 1098 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 1099 | } | ||
| 1100 | }) | ||
| 1101 | // 详情跟类型都返回之后再设置选项 | ||
| 1102 | Promise.all([detailPs, psType]).then((res: any) => { | ||
| 1103 | //选项待定,只有未到合同终止时间才可以选择提前解除。 | ||
| 1104 | let endTime = detailInfo.value.endTime; | ||
| 1105 | let currDate = new Date(); | ||
| 1106 | let endDate = new Date(endTime); | ||
| 1107 | if (currDate > endDate) { //终止时间大于当前时间,可以选择全部包括提前解除和到期解除 | ||
| 1108 | rejectInfoFormItems.value[0].options = terminateTypeList.value.filter(t => t.value == 'DQ'); | ||
| 1109 | rejectInfoFormItems.value[0].default = 'DQ' | ||
| 1110 | } else { | ||
| 1111 | rejectInfoFormItems.value[0].options = terminateTypeList.value.filter(t => t.value == 'TQ'); | ||
| 1112 | rejectInfoFormItems.value[0].default = 'TQ' | ||
| 1113 | } | ||
| 1114 | rejectInfoFormItems.value[1].default = detailInfo.value.signatureTime; | ||
| 1115 | rejectInfoFormItems.value[2].default = detailInfo.value.endTime; | ||
| 1116 | rejectInfoFormItems.value[3].visible = rejectInfoFormItems.value[0].default == 'TQ'; | ||
| 1117 | rejectInfoFormItems.value[4].visible = rejectInfoFormItems.value[0].default == 'TQ'; | ||
| 1118 | }) | ||
| 1119 | } | ||
| 1120 | }); | ||
| 1121 | |||
| 1122 | onActivated(() => { | ||
| 1123 | let tab: any = userStore.tabbar.find((tab: any) => tab.fullPath === fullPath); | ||
| 1124 | if (tab) { | ||
| 1125 | if (detailType.value == 'consult') { | ||
| 1126 | document.title = `合约协商-${route.query.name}`; | ||
| 1127 | tab.meta.title = `合约协商-${route.query.name}`; | ||
| 1128 | } else if (detailType.value == 'sign') { | ||
| 1129 | document.title = `合约签署-${route.query.name}`; | ||
| 1130 | tab.meta.title = `合约签署-${route.query.name}`; | ||
| 1131 | } else if (detailType.value == 'reject') { | ||
| 1132 | document.title = `合约解除-${route.query.name}`; | ||
| 1133 | tab.meta.title = `合约解除-${route.query.name}`; | ||
| 1134 | } else { | ||
| 1135 | document.title = `合约详情-${route.query.name}`; | ||
| 1136 | tab.meta.title = `合约详情-${route.query.name}`; | ||
| 1137 | } | ||
| 1138 | } | ||
| 1139 | }) | ||
| 1140 | |||
| 1141 | </script> | ||
| 1142 | |||
| 1143 | <template> | ||
| 1144 | <div class="container_wrap full" v-loading="fullscreenLoading"> | ||
| 1145 | <div class="content_main panel"> | ||
| 1146 | <div class="first-title-row"> | ||
| 1147 | <div class="title-row"> | ||
| 1148 | <div class="title"><ellipsis-tooltip :content="detailInfo?.contractName || '--'" class-name="w100f" | ||
| 1149 | :refName="'tooltipOver' + 'contractName'"></ellipsis-tooltip></div> | ||
| 1150 | <el-tag :type="tagType(detailInfo, 'contractStatus')">{{ tagMethod(detailInfo, 'contractStatus') }}</el-tag> | ||
| 1151 | </div> | ||
| 1152 | <div class="list_panel mt6"> | ||
| 1153 | <div class="list_item"> | ||
| 1154 | <span class="item_label">合约编号:</span> | ||
| 1155 | <span class="item_value"><ellipsis-tooltip :content="detailInfo?.contractId || '--'" | ||
| 1156 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'contractId'"></ellipsis-tooltip></span> | ||
| 1157 | </div> | ||
| 1158 | <div class="list_item"> | ||
| 1159 | <span class="item_label">合约版本:</span> | ||
| 1160 | <span class="item_value">{{ detailInfo?.policys?.at(-1)?.version || 'v1.0.0' }}</span> | ||
| 1161 | </div> | ||
| 1162 | <div class="list_item"> | ||
| 1163 | <span class="item_label">创建时间:</span> | ||
| 1164 | <span class="item_value">{{ detailInfo.createTime || '--' }}</span> | ||
| 1165 | </div> | ||
| 1166 | <div class="list_item"> | ||
| 1167 | <span class="item_label">发起主体:</span> | ||
| 1168 | <span class="item_value"><ellipsis-tooltip :content="detailInfo?.tenantName || '--'" | ||
| 1169 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'tenantName'"></ellipsis-tooltip></span> | ||
| 1170 | </div> | ||
| 1171 | <div class="list_item"> | ||
| 1172 | <span class="item_label">签署时间:</span> | ||
| 1173 | <span class="item_value">{{ detailInfo.signatureTime || '--' }}</span> | ||
| 1174 | </div> | ||
| 1175 | <div class="list_item"> | ||
| 1176 | <span class="item_label">有效期:</span> | ||
| 1177 | <span class="item_value">{{ !detailInfo.signatureTime ? '--' : (detailInfo.signatureTime + '至' + | ||
| 1178 | detailInfo.endTime) }}</span> | ||
| 1179 | </div> | ||
| 1180 | </div> | ||
| 1181 | </div> | ||
| 1182 | <div class="empty-div"></div> | ||
| 1183 | <div class="progress"> | ||
| 1184 | <div :class="{ 'active': true, 'no-select': detailType && currentStep != 1 || (isDetail && currentStep > 1) }" | ||
| 1185 | style="cursor: pointer;" @click="handleClickStep(1)">1、合约信息</div> | ||
| 1186 | <div | ||
| 1187 | :class="{ 'bg-gray': true, 'active': !!detailType || (isDetail && detailInfo?.negotiateEntityGuid), 'cursor-pointer': !!detailType || (isDetail && detailInfo?.negotiateEntityGuid), 'no-select': (currentStep && currentStep != 2) || (detailType != 'consult' && !currentStep) }" | ||
| 1188 | @click="(!!detailType || (isDetail && detailInfo?.negotiateEntityGuid)) ? handleClickStep(2) : () => { }"> | ||
| 1189 | <div class="triangle-box"> | ||
| 1190 | <div | ||
| 1191 | :class="{ 'triangle': true, 'active': true, 'no-select': detailType && currentStep != 1 || (isDetail && currentStep > 1) }"> | ||
| 1192 | </div> | ||
| 1193 | </div> | ||
| 1194 | 2、合约协商 | ||
| 1195 | </div> | ||
| 1196 | <div :class="{ | ||
| 1197 | 'bg-gray': true, 'active': detailType == 'sign' || detailType == 'keepAgree' || detailType == 'reject' || (isDetail && detailInfo.signatureList?.length), 'cursor-pointer': detailType == 'sign' || detailType == 'keepAgree' || detailType == 'reject' || (isDetail && detailInfo.signatureList?.length), | ||
| 1198 | 'no-select': (currentStep && currentStep != 3) || (detailType != 'sign' && !currentStep) | ||
| 1199 | }" | ||
| 1200 | @click="(detailType == 'sign' || detailType == 'keepAgree' || detailType == 'reject' || (isDetail && detailInfo.signatureList?.length)) ? handleClickStep(3) : () => { }"> | ||
| 1201 | <div class="triangle-box"> | ||
| 1202 | <div | ||
| 1203 | :class="{ 'triangle': true, 'active': !!detailType || (isDetail && detailInfo?.negotiateEntityGuid), 'no-select': (currentStep && currentStep != 2) || (detailType != 'consult' && !currentStep) }"> | ||
| 1204 | </div> | ||
| 1205 | </div> | ||
| 1206 | 3、合约签署 | ||
| 1207 | </div> | ||
| 1208 | <div :class="{ | ||
| 1209 | 'bg-gray': true, 'active': detailType == 'keepAgree' || detailType == 'reject' || (isDetail && detailInfo.contractStatus == '06'), 'cursor-pointer': detailType == 'keepAgree' || detailType == 'reject' || (isDetail && detailInfo.contractStatus == '06'), | ||
| 1210 | 'no-select': (currentStep && currentStep != 4) || (detailType != 'keepAgree' && !currentStep) | ||
| 1211 | }" | ||
| 1212 | @click="(detailType == 'keepAgree' || detailType == 'reject' || (isDetail && detailInfo.contractStatus == '06')) ? handleClickStep(4) : () => { }"> | ||
| 1213 | <div class="triangle-box"> | ||
| 1214 | <div :class="{ | ||
| 1215 | 'triangle': true, 'active': detailType == 'sign' || detailType == 'keepAgree' || detailType == 'reject' || (isDetail && detailInfo.signatureList?.length), | ||
| 1216 | 'no-select': (currentStep && currentStep != 3) || (detailType != 'sign' && !currentStep) | ||
| 1217 | }"> | ||
| 1218 | </div> | ||
| 1219 | </div> | ||
| 1220 | 4、合约履行 | ||
| 1221 | </div> | ||
| 1222 | <div v-show="detailType == 'reject' || (isDetail && detailInfo.contractStatus == '06')" :class="{ | ||
| 1223 | 'bg-gray': true, 'active': detailType == 'reject' || (isDetail && detailInfo.contractStatus == '06'), 'cursor-pointer': detailType == 'reject' || (isDetail && detailInfo.contractStatus == '06'), | ||
| 1224 | 'no-select': (currentStep && currentStep != 5) || (detailType != 'reject' && !currentStep) | ||
| 1225 | }" | ||
| 1226 | @click="(detailType == 'reject' || (isDetail && detailInfo.contractStatus == '06')) ? handleClickStep(5) : () => { }"> | ||
| 1227 | <div class="triangle-box"> | ||
| 1228 | <div | ||
| 1229 | :class="{ 'triangle': true, 'active': detailType == 'keepAgree' || detailType == 'reject' || (isDetail && detailInfo.contractStatus == '06'), 'no-select': (currentStep && currentStep != 4) || (detailType != 'keepAgree' && !currentStep) }"> | ||
| 1230 | </div> | ||
| 1231 | </div> | ||
| 1232 | 5、合约解除 | ||
| 1233 | </div> | ||
| 1234 | </div> | ||
| 1235 | <ContentWrap v-show="currentStep == 1" id="base-info" title="合约信息" expandSwicth style="margin-top: 15px" | ||
| 1236 | :isExpand="expandBase" @expand="(v) => (expandBase = v)" description=""> | ||
| 1237 | <div class="list_panel"> | ||
| 1238 | <div class="list_item"> | ||
| 1239 | <span class="item_label">合约名称:</span> | ||
| 1240 | <span class="item_value"><ellipsis-tooltip :content="detailInfo?.contractName || '--'" | ||
| 1241 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'contractName1'"></ellipsis-tooltip></span> | ||
| 1242 | </div> | ||
| 1243 | <div class="list_item"> | ||
| 1244 | <span class="item_label">签署模式:</span> | ||
| 1245 | <span class="item_value"><ellipsis-tooltip :content="detailInfo?.signModeName || '--'" | ||
| 1246 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'signModeName'"></ellipsis-tooltip></span> | ||
| 1247 | </div> | ||
| 1248 | <div class="list_item"> | ||
| 1249 | <span class="item_label">终止时间:</span> | ||
| 1250 | <span class="item_value"><ellipsis-tooltip :content="detailInfo?.endTime || '--'" class-name="w100f mr8-i" | ||
| 1251 | :refName="'tooltipOver' + 'endTime'"></ellipsis-tooltip></span> | ||
| 1252 | </div> | ||
| 1253 | <div class="list_item is_block"> | ||
| 1254 | <span class="item_label">合约简介:</span> | ||
| 1255 | <span class="item_value">{{ detailInfo.contractAbstract || '--' }}</span> | ||
| 1256 | </div> | ||
| 1257 | </div> | ||
| 1258 | <Table ref="extendTableRef" :tableInfo="extendTableInfo" class="fiveRow-table" /> | ||
| 1259 | </ContentWrap> | ||
| 1260 | <ContentWrap v-show="currentStep == 1" id="product-info" title="合约标的" expandSwicth style="margin-top: 15px" | ||
| 1261 | :isExpand="expandInfo" @expand="(v) => (expandInfo = v)" description=""> | ||
| 1262 | <Table ref="productTableRef" :tableInfo="productTableInfo" class="fiveRow-table" /> | ||
| 1263 | </ContentWrap> | ||
| 1264 | <ContentWrap v-show="currentStep == 1" id="policy-info" title="合约策略" expandSwicth style="margin-top: 15px" | ||
| 1265 | :isExpand="expandPolicy" @expand="(v) => (expandPolicy = v)" description=""> | ||
| 1266 | <div class="h-title">策略执行节点</div> | ||
| 1267 | <Form ref="nodeInfoFormRef" formId="node-info-form" :itemList="nodeInfoFormItems" col="col3" /> | ||
| 1268 | <StrategyTable ref="strategyTableRef" :show-title="true" :is-look="true" :value="detailInfo.policys || []"> | ||
| 1269 | </StrategyTable> | ||
| 1270 | </ContentWrap> | ||
| 1271 | <ContentWrap v-show="detailType == 'consult' && currentStep != 1" id="policy-info-consult" title="合约策略" | ||
| 1272 | expandSwicth style="margin-top: 15px" :isExpand="expandPolicyConsult" @expand="(v) => (expandPolicyConsult = v)" | ||
| 1273 | description=""> | ||
| 1274 | <StrategyTable ref="strategyTableEditRef" :show-title="true" :value="consultDetailInfo?.policys" | ||
| 1275 | :operatorOptionList="operatorOptionList" :actionOptionsList="actionOptionsList" | ||
| 1276 | :constraintOptionsList="constraintOptionsList"></StrategyTable> | ||
| 1277 | </ContentWrap> | ||
| 1278 | <ContentWrap v-show="detailType == 'consult' || currentStep == 2" id="history-info-consult" title="协商记录" | ||
| 1279 | expandSwicth style="margin-top: 15px" :isExpand="expandConsultHistory" | ||
| 1280 | @expand="(v) => (expandConsultHistory = v)" description=""> | ||
| 1281 | <el-timeline style="max-width: 900px"> | ||
| 1282 | <el-timeline-item v-for="(activity, index) in activities" :key="index" :timestamp="activity.timestamp" | ||
| 1283 | :hollow="activity.hollow" :type="activity.type" placement="top"> | ||
| 1284 | <div v-for="(child, childIndex) of activity.children" class="row-per" | ||
| 1285 | :style="{ 'margin-top': childIndex > 0 ? '8px' : '0px' }"> | ||
| 1286 | <div | ||
| 1287 | :class="child.negotiateEntityType == '数据提供方' ? 'label' : (child.negotiateEntityType == '数据服务方' ? 'label2' : 'label1')"> | ||
| 1288 | {{ child.negotiateEntityType }} | ||
| 1289 | </div> | ||
| 1290 | <div style="width: 350px;" class="desc"> <ellipsis-tooltip | ||
| 1291 | :content="'协商主体:' + (child?.negotiateEntityName ?? '--')" class-name="w100f" | ||
| 1292 | :refName="'tooltipOverTenant'"></ellipsis-tooltip></div> | ||
| 1293 | <div style="width: 200px;" class="desc">版本号:<span class="main" @click="clickVersion(child)">{{ | ||
| 1294 | child.version }}</span></div> | ||
| 1295 | <div style="width: 250px;" class="desc">{{ '提交时间:' + child.submitTime }}</div> | ||
| 1296 | </div> | ||
| 1297 | </el-timeline-item> | ||
| 1298 | </el-timeline> | ||
| 1299 | </ContentWrap> | ||
| 1300 | <ContentWrap v-show="!currentStep && detailType == 'sign' || currentStep == 3" id="sign-info" title="合约签署" | ||
| 1301 | expandSwicth style="margin-top: 15px" :isExpand="expandSign" @expand="(v) => (expandSign = v)" description=""> | ||
| 1302 | <template v-for="(item, index) in signDetailInfo"> | ||
| 1303 | <div :class="{ 'h-title': true, 'mt6': index > 0 }">{{ item.executionerTypeName }}</div> | ||
| 1304 | <div class="list_panel"> | ||
| 1305 | <div class="list_item wrap"> | ||
| 1306 | <span class="item_label">签署主体标识</span> | ||
| 1307 | <span class="item_value"><ellipsis-tooltip :content="item?.signatureEntityId || '--'" | ||
| 1308 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'tenantCode'"></ellipsis-tooltip></span> | ||
| 1309 | </div> | ||
| 1310 | <div class="list_item wrap"> | ||
| 1311 | <span class="item_label">签署主体名称</span> | ||
| 1312 | <span class="item_value row"><ellipsis-tooltip :content="item?.signatureEntityName || '--'" | ||
| 1313 | class-name="w100f mr8-i custom" :refName="'tooltipOver' + 'signatureEntityName'"></ellipsis-tooltip> | ||
| 1314 | <div :class="item.executionerTypeCode == '02' ? 'label1' : 'label'">{{ item.executionerTypeName }}</div> | ||
| 1315 | </span> | ||
| 1316 | </div> | ||
| 1317 | <div class="list_item isFile"> | ||
| 1318 | <span class="item_label">身份凭证证书</span> | ||
| 1319 | <template v-if="item?.identityCertificate?.url"> | ||
| 1320 | <span class="item_value link" @click="viewResultVoucherFile(item?.identityCertificate?.url)">查看</span> | ||
| 1321 | </template> | ||
| 1322 | <span v-else class="item_value">--</span> | ||
| 1323 | </div> | ||
| 1324 | <!-- 没有上传就不显示 --> | ||
| 1325 | <div class="list_item isFile"> | ||
| 1326 | <span class="item_label">附件</span> | ||
| 1327 | <template v-if="item?.attachment?.url"> | ||
| 1328 | <showFile :file="[item.attachment]"></showFile> | ||
| 1329 | </template> | ||
| 1330 | <span v-else class="item_value">--</span> | ||
| 1331 | </div> | ||
| 1332 | <div class="list_item isFile"> | ||
| 1333 | <span class="item_label">签署签名</span> | ||
| 1334 | <template v-if="item?.signature?.url"> | ||
| 1335 | <showFile :file="[item.signature]"></showFile> | ||
| 1336 | </template> | ||
| 1337 | <span v-else class="item_value">--</span> | ||
| 1338 | </div> | ||
| 1339 | <div class="list_item wrap"> | ||
| 1340 | <span class="item_label">签署时间</span> | ||
| 1341 | <span class="item_value"><ellipsis-tooltip :content="item?.signatureTime || '--'" class-name="w100f mr8-i" | ||
| 1342 | :refName="'tooltipOver' + 'signatureTime'"></ellipsis-tooltip></span> | ||
| 1343 | </div> | ||
| 1344 | </div> | ||
| 1345 | </template> | ||
| 1346 | <template v-if="detailType == 'sign'"> | ||
| 1347 | <div class="h-title mt6">{{ userData.tenantGuid == detailInfo.dataUserGuid ? '数据使用方' : '数据提供方' }}</div> | ||
| 1348 | <div class="list_panel"> | ||
| 1349 | <div class="list_item wrap"> | ||
| 1350 | <span class="item_label">签署主体标识</span> | ||
| 1351 | <span class="item_value"><ellipsis-tooltip :content="signTenantDetailInfo?.socialCreditCode || '--'" | ||
| 1352 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'tenantCode'"></ellipsis-tooltip></span> | ||
| 1353 | </div> | ||
| 1354 | <div class="list_item wrap"> | ||
| 1355 | <span class="item_label">签署主体名称</span> | ||
| 1356 | <span class="item_value row"><ellipsis-tooltip :content="userData?.tenantName || '--'" | ||
| 1357 | class-name="w100f mr8-i custom" :refName="'tooltipOver' + 'tenantName'"></ellipsis-tooltip> | ||
| 1358 | <div :class="userData.tenantGuid == detailInfo.dataUserGuid ? 'label1' : 'label'">{{ userData.tenantGuid | ||
| 1359 | == detailInfo.dataUserGuid ? '数据使用方' : '数据提供方' }}</div> | ||
| 1360 | </span> | ||
| 1361 | </div> | ||
| 1362 | <div class="list_item isFile"> | ||
| 1363 | <span class="item_label">身份凭证证书</span> | ||
| 1364 | <template v-if="signTenantDetailInfo?.trustedIdentityCredential"> | ||
| 1365 | <span class="item_value link" | ||
| 1366 | @click="viewResultVoucherFile(signTenantDetailInfo?.trustedIdentityCredential)">查看</span> | ||
| 1367 | </template> | ||
| 1368 | <span v-else class="item_value">--</span> | ||
| 1369 | </div> | ||
| 1370 | </div> | ||
| 1371 | <div style="display: flex"> | ||
| 1372 | <Form class="mt6" ref="signInfoFormRef" formId="sign-info-form" :itemList="signInfoFormItems" | ||
| 1373 | :rules="signInfoFormRules" col="col3" style="width: 33.33%;" /> | ||
| 1374 | <div class="sign-main" style="width: 33.33%;"> | ||
| 1375 | <div class="item-label" style="margin-bottom: 2px;">签署签名<span class="required">*</span></div> | ||
| 1376 | <el-button v-show="!signFileUrlInfo?.url" type="primary" :loading="signFileLoading" | ||
| 1377 | @click="geneSignFile">生成签名文件</el-button> | ||
| 1378 | <template v-if="signFileUrlInfo?.url"> | ||
| 1379 | <showFile :file="[signFileUrlInfo]" :show-remove="true" @deleteFile="deleteSignFile"></showFile> | ||
| 1380 | </template> | ||
| 1381 | </div> | ||
| 1382 | </div> | ||
| 1383 | </template> | ||
| 1384 | </ContentWrap> | ||
| 1385 | <el-checkbox style="margin-top: 4px;" v-show="detailType == 'sign' && (!currentStep || currentStep == 3)" | ||
| 1386 | v-model="confirmAuth">确认提交代表您已知晓本次签署行为所包含的责任义务,并授权允许平台使用本次操作的系统日志作为纠纷处理证明。</el-checkbox> | ||
| 1387 | <ContentWrap v-show="!currentStep && detailType == 'keepAgree' || currentStep == 4" id="keep-info" | ||
| 1388 | title="合约执行履约信息" expandSwicth style="margin-top: 15px" :isExpand="expandKeep" @expand="(v) => (expandKeep = v)" | ||
| 1389 | description=""> | ||
| 1390 | <template v-if="execContractTableInfo.data?.length"> | ||
| 1391 | <!-- <div class="h-title">执行信息</div> --> | ||
| 1392 | <el-table ref="execContractTableRef" :data="execContractTableInfo.data" :highlight-current-row="true" stripe | ||
| 1393 | v-loading="execContractTableInfo.loading" border height="100%" tooltip-effect="light" row-key="guid" :style="{ | ||
| 1394 | width: '100%', | ||
| 1395 | height: '300px', | ||
| 1396 | display: 'inline-block', | ||
| 1397 | }"> | ||
| 1398 | <el-table-column type="expand"> | ||
| 1399 | <template #default="scope"> | ||
| 1400 | <div class="h-title mt6">履约证明</div> | ||
| 1401 | <div class="list_panel" style="width: 1000px;"> | ||
| 1402 | <div class="list_item"> | ||
| 1403 | <span class="item_label">日志摘要:</span> | ||
| 1404 | <span class="item_value"><ellipsis-tooltip :content="scope.row?.contractProof?.logHash || '--'" | ||
| 1405 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'logHash'"></ellipsis-tooltip></span> | ||
| 1406 | </div> | ||
| 1407 | <div class="list_item"> | ||
| 1408 | <span class="item_label">区块链交易ID:</span> | ||
| 1409 | <span class="item_value row"><ellipsis-tooltip | ||
| 1410 | :content="scope.row?.contractProof?.blockchainTx || '--'" class-name="w100f mr8-i" | ||
| 1411 | :refName="'tooltipOver' + 'blockchainTx'"></ellipsis-tooltip> | ||
| 1412 | </span> | ||
| 1413 | </div> | ||
| 1414 | <div class="list_item"> | ||
| 1415 | <span class="item_label">发送时间:</span> | ||
| 1416 | <span class="item_value"><ellipsis-tooltip :content="scope.row?.contractProof?.sendTime || '--'" | ||
| 1417 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'sendTime'"></ellipsis-tooltip></span> | ||
| 1418 | </div> | ||
| 1419 | <div class="list_item" style="width: 50%;"> | ||
| 1420 | <span class="item_label">履约连接器签名:</span> | ||
| 1421 | <!-- <template v-if="scope.row?.signature?.url"> | ||
| 1422 | <showFile :file="[execProofDetailInfo.signature]"></showFile> | ||
| 1423 | </template> --> | ||
| 1424 | <span class="item_value">{{ scope.row?.contractProof?.signature || '--' }}</span> | ||
| 1425 | </div> | ||
| 1426 | </div> | ||
| 1427 | </template> | ||
| 1428 | </el-table-column> | ||
| 1429 | <el-table-column v-for="(item, i) in execContractTableInfo.fields" :label="item.label" :width="item.width" | ||
| 1430 | :align="item.align" :prop="item.field" show-overflow-tooltip> | ||
| 1431 | <template #default="scope"> | ||
| 1432 | <span v-if="item.type == 'index'"> | ||
| 1433 | {{ | ||
| 1434 | execContractTableInfo.page.curr !== undefined | ||
| 1435 | ? (execContractTableInfo.page.curr - 1) * execContractTableInfo.page.limit + scope.$index + 1 | ||
| 1436 | : scope.$index + 1 | ||
| 1437 | }} | ||
| 1438 | </span> | ||
| 1439 | <!-- <el-tag v-else-if="item.type == 'tag'" | ||
| 1440 | :type="item.tagType ? item.tagType(scope) : tagType(scope.row, item.field)">{{ | ||
| 1441 | item.getName ? item.getName(scope) : tagMethod(scope.row, item.field) | ||
| 1442 | }}</el-tag> --> | ||
| 1443 | <span v-else> | ||
| 1444 | {{ item.getName ? item.getName(scope) : scope.row[item.field] !== 0 && !scope.row[item.field] | ||
| 1445 | ? | ||
| 1446 | "--" : scope.row[item.field] }} | ||
| 1447 | </span> | ||
| 1448 | </template> | ||
| 1449 | </el-table-column> | ||
| 1450 | </el-table> | ||
| 1451 | <PageNav :class="[execContractTableInfo.page.type]" :pageInfo="execContractTableInfo.page" | ||
| 1452 | @pageChange="pageChange" /> | ||
| 1453 | <!-- <Table ref="execContractTableRef" :tableInfo="execContractTableInfo" class="fiveRow-table" /> --> | ||
| 1454 | </template> | ||
| 1455 | <div class="empty-content" v-if="!execContractTableInfo.data?.length"> | ||
| 1456 | <img src="../../assets/images/empty-data.png" :style="{ width: '168px', height: '96px' }" /> | ||
| 1457 | <div class="empty-text">暂无履约数据</div> | ||
| 1458 | </div> | ||
| 1459 | </ContentWrap> | ||
| 1460 | <ContentWrap v-show="!isDetail && (!currentStep && detailType == 'reject' || currentStep == 5)" id="reject-info" | ||
| 1461 | title="合约解除信息" expandSwicth style="margin-top: 15px" :isExpand="expandReject" | ||
| 1462 | @expand="(v) => (expandReject = v)" description=""> | ||
| 1463 | <Form ref="rejectInfoFormRef" formId="reject-info-form" :itemList="rejectInfoFormItems" | ||
| 1464 | :rules="rejectInfoFormRules" col="col3" @select-change="handleRejectFormSelectChange" /> | ||
| 1465 | </ContentWrap> | ||
| 1466 | <ContentWrap v-show="isDetail && currentStep == 5" id="reject-info" title="合约解除信息" expandSwicth | ||
| 1467 | style="margin-top: 15px" :isExpand="expandReject" @expand="(v) => (expandReject = v)" description=""> | ||
| 1468 | <div class="list_panel"> | ||
| 1469 | <div class="list_item"> | ||
| 1470 | <span class="item_label">解除类型:</span> | ||
| 1471 | <span class="item_value"><ellipsis-tooltip :content="terminateDetailInfo?.terminateTypeCodeName || '--'" | ||
| 1472 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'terminateTypeCodeName'"></ellipsis-tooltip></span> | ||
| 1473 | </div> | ||
| 1474 | <div class="list_item"> | ||
| 1475 | <span class="item_label">合同生效时间:</span> | ||
| 1476 | <span class="item_value row">{{ terminateDetailInfo?.activationTime || '--' }} | ||
| 1477 | </span> | ||
| 1478 | </div> | ||
| 1479 | <div class="list_item"> | ||
| 1480 | <span class="item_label">合同终止时间:</span> | ||
| 1481 | <span class="item_value row">{{ terminateDetailInfo?.scheduledEndTime || '--' }} | ||
| 1482 | </span> | ||
| 1483 | </div> | ||
| 1484 | <div class="list_item" v-if="terminateDetailInfo.terminateTypeCode == 'TQ'"> | ||
| 1485 | <span class="item_label">合同约定终止时间:</span> | ||
| 1486 | <span class="item_value row">{{ terminateDetailInfo?.agreedEndTime || '--' }} | ||
| 1487 | </span> | ||
| 1488 | </div> | ||
| 1489 | <div class="list_item"> | ||
| 1490 | <span class="item_label">合同解除时间:</span> | ||
| 1491 | <span class="item_value row">{{ terminateDetailInfo?.issueTime || '--' }} | ||
| 1492 | </span> | ||
| 1493 | </div> | ||
| 1494 | <div class="list_item is_block" v-if="terminateDetailInfo.terminateTypeCode == 'TQ'"> | ||
| 1495 | <span class="item_label">合约解除原因:</span> | ||
| 1496 | <span class="item_value row">{{ terminateDetailInfo?.issueReason || '--' }} | ||
| 1497 | </span> | ||
| 1498 | </div> | ||
| 1499 | <div class="list_item is_block"> | ||
| 1500 | <span class="item_label">数据处理方式:</span> | ||
| 1501 | <span class="item_value row">{{ terminateDetailInfo?.dataProcessingMethod || '--' }} | ||
| 1502 | </span> | ||
| 1503 | </div> | ||
| 1504 | <div class="list_item is_block"> | ||
| 1505 | <span class="item_label">数据处理指令:</span> | ||
| 1506 | <span class="item_value row">{{ terminateDetailInfo?.dataProcessingInstructions || '--' }} | ||
| 1507 | </span> | ||
| 1508 | </div> | ||
| 1509 | <div class="list_item isFile"> | ||
| 1510 | <span class="item_label">数据处理证明:</span> | ||
| 1511 | <template v-if="terminateDetailInfo?.dataProcessingProof?.url"> | ||
| 1512 | <showFile :file="[terminateDetailInfo?.dataProcessingProof]"></showFile> | ||
| 1513 | </template> | ||
| 1514 | <span v-else class="item_value">--</span> | ||
| 1515 | </div> | ||
| 1516 | </div> | ||
| 1517 | </ContentWrap> | ||
| 1518 | </div> | ||
| 1519 | <div class="tool_btns"> | ||
| 1520 | <div class="btns"> | ||
| 1521 | <el-button v-for="btn in toolBtns" :type="btn.type" :disabled="btn.disabled" :plain="btn.plain" | ||
| 1522 | @click="btnHandles[btn.value]">{{ | ||
| 1523 | btn.label | ||
| 1524 | }}</el-button> | ||
| 1525 | </div> | ||
| 1526 | </div> | ||
| 1527 | <Dialog ref="dialogRef" :dialogInfo="detailDialogInfo" class="policy-table-detail" | ||
| 1528 | @btnClick="handleVersionDialogBtnClick"> | ||
| 1529 | <template #extra-content> | ||
| 1530 | <div v-loading="detailDialogInfo.contentLoading"> | ||
| 1531 | <StrategyTable ref="strategyTableDetailRef" :show-title="true" :is-look="true" :value="versionDetail"> | ||
| 1532 | </StrategyTable> | ||
| 1533 | </div> | ||
| 1534 | </template> | ||
| 1535 | </Dialog> | ||
| 1536 | <ConfirmDialog :visible="confirmDialogInfo.dialogVisible" :type="confirmDialogInfo.type" | ||
| 1537 | :msg="confirmDialogInfo.msg[confirmDialogInfo.type]" @btn-click="handleConfirmDialog"></ConfirmDialog> | ||
| 1538 | <div id="pdf-content" style="display: none;"> | ||
| 1539 | <div class="first-title-row" style="padding: 0px;"> | ||
| 1540 | <div class="title-row" style="align-items: flex-start;"> | ||
| 1541 | <div class="title" style="white-space: pre-wrap;word-break: break-all;">{{ detailInfo?.contractName || '--' }} | ||
| 1542 | </div> | ||
| 1543 | <!-- <el-tag :type="tagType(detailInfo, 'contractStatus')">{{ tagMethod(detailInfo, 'contractStatus') }}</el-tag> --> | ||
| 1544 | </div> | ||
| 1545 | <div class="list_panel two-per"> | ||
| 1546 | <div class="list_item" style=" width: 55%;"> | ||
| 1547 | <span class="item_label">合约编号:</span> | ||
| 1548 | <span class="item_value"><ellipsis-tooltip :content="detailInfo?.contractId || '--'" | ||
| 1549 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'contractId'"></ellipsis-tooltip></span> | ||
| 1550 | </div> | ||
| 1551 | <div class="list_item" style=" width: 45%;"> | ||
| 1552 | <span class="item_label">合约版本:</span> | ||
| 1553 | <span class="item_value">{{ detailInfo?.policys?.at(-1)?.version || 'v1.0.0' }}</span> | ||
| 1554 | </div> | ||
| 1555 | <div class="list_item" style=" width: 55%;"> | ||
| 1556 | <span class="item_label">发起主体:</span> | ||
| 1557 | <span class="item_value">{{ detailInfo?.tenantName || '--' }}</span> | ||
| 1558 | </div> | ||
| 1559 | <div class="list_item" style=" width: 45%;"> | ||
| 1560 | <span class="item_label">创建时间:</span> | ||
| 1561 | <span class="item_value">{{ detailInfo.createTime || '--' }}</span> | ||
| 1562 | </div> | ||
| 1563 | <div class="list_item" style=" width: 55%;"> | ||
| 1564 | <span class="item_label">有效期:</span> | ||
| 1565 | <span class="item_value">{{ !detailInfo.signatureTime ? '--' : (detailInfo.signatureTime + '至' + | ||
| 1566 | detailInfo.endTime) }}</span> | ||
| 1567 | </div> | ||
| 1568 | <div class="list_item" style=" width: 45%;"> | ||
| 1569 | <span class="item_label">签署时间:</span> | ||
| 1570 | <span class="item_value">{{ detailInfo.signatureTime || '--' }}</span> | ||
| 1571 | </div> | ||
| 1572 | </div> | ||
| 1573 | </div> | ||
| 1574 | <div class="empty-div"></div> | ||
| 1575 | <ContentWrap id="base-info" title="合约信息" style="margin-top: 12px" :isExpand="expandBase" | ||
| 1576 | @expand="(v) => (expandBase = v)" description=""> | ||
| 1577 | <div class="list_panel two-per"> | ||
| 1578 | <div class="list_item is_block"> | ||
| 1579 | <span class="item_label">合约名称:</span> | ||
| 1580 | <span class="item_value">{{ detailInfo?.contractName || '--' }}</span> | ||
| 1581 | </div> | ||
| 1582 | <div class="list_item"> | ||
| 1583 | <span class="item_label">签署模式:</span> | ||
| 1584 | <span class="item_value"><ellipsis-tooltip :content="detailInfo?.signModeName || '--'" | ||
| 1585 | class-name="w100f mr8-i" :refName="'tooltipOver' + 'signModeName'"></ellipsis-tooltip></span> | ||
| 1586 | </div> | ||
| 1587 | <div class="list_item"> | ||
| 1588 | <span class="item_label">终止时间:</span> | ||
| 1589 | <span class="item_value"><ellipsis-tooltip :content="detailInfo?.endTime || '--'" class-name="w100f mr8-i" | ||
| 1590 | :refName="'tooltipOver' + 'endTime'"></ellipsis-tooltip></span> | ||
| 1591 | </div> | ||
| 1592 | <div class="list_item is_block"> | ||
| 1593 | <span class="item_label">合约简介:</span> | ||
| 1594 | <span class="item_value">{{ detailInfo.contractAbstract || '--' }}</span> | ||
| 1595 | </div> | ||
| 1596 | </div> | ||
| 1597 | <Table v-if="exportExtendTableInfo.data?.length" ref="extendTableRef" :tableInfo="exportExtendTableInfo" /> | ||
| 1598 | </ContentWrap> | ||
| 1599 | <ContentWrap id="product-info" title="合约标的" style="margin-top: 12px;" :isExpand="expandInfo" | ||
| 1600 | @expand="(v) => (expandInfo = v)" description=""> | ||
| 1601 | <Table ref="productTableRef" :tableInfo="exportProductTableInfo" /> | ||
| 1602 | </ContentWrap> | ||
| 1603 | <ContentWrap id="policy-info" title="合约策略" style="margin-top: 12px;" :isExpand="expandPolicy" | ||
| 1604 | @expand="(v) => (expandPolicy = v)" description=""> | ||
| 1605 | <div class="h-title">策略执行节点</div> | ||
| 1606 | <!-- <Form ref="nodeInfoFormRef" formId="node-info-form" :itemList="nodeInfoFormItems" col="col3" /> --> | ||
| 1607 | <div class="list_panel"> | ||
| 1608 | <div class="list_item wrap" style="width: 20%;"> | ||
| 1609 | <span class="item_label">策略执行者类型</span> | ||
| 1610 | <span class="item_value"><ellipsis-tooltip :content="nodeInfoFormItems[0].default || '--'" | ||
| 1611 | class-name="w100f mr8-i" :refName="'tooltipOver1'"></ellipsis-tooltip></span> | ||
| 1612 | </div> | ||
| 1613 | <div class="list_item wrap" style="width: 40%;"> | ||
| 1614 | <span class="item_label">策略执行者名称</span> | ||
| 1615 | <span class="item_value"><ellipsis-tooltip :content="nodeInfoFormItems[1].default || '--'" | ||
| 1616 | class-name="w100f mr8-i custom" :refName="'tooltipOver2'"></ellipsis-tooltip> | ||
| 1617 | </span> | ||
| 1618 | </div> | ||
| 1619 | <div class="list_item wrap" style="width: 40%;"> | ||
| 1620 | <span class="item_label">策略执行者标识</span> | ||
| 1621 | <span class="item_value"><ellipsis-tooltip :content="nodeInfoFormItems[2].default || '--'" | ||
| 1622 | class-name="w100f mr8-i custom" :refName="'tooltipOver3'"></ellipsis-tooltip> | ||
| 1623 | </span> | ||
| 1624 | </div> | ||
| 1625 | <div class="list_item wrap" style="width: 20%;"> | ||
| 1626 | <span class="item_label">策略执行者类型</span> | ||
| 1627 | <span class="item_value"><ellipsis-tooltip :content="nodeInfoFormItems[3].default || '--'" | ||
| 1628 | class-name="w100f mr8-i" :refName="'tooltipOver4'"></ellipsis-tooltip></span> | ||
| 1629 | </div> | ||
| 1630 | <div class="list_item wrap" style="width: 40%;"> | ||
| 1631 | <span class="item_label">策略执行者名称</span> | ||
| 1632 | <span class="item_value"><ellipsis-tooltip :content="nodeInfoFormItems[4].default || '--'" | ||
| 1633 | class-name="w100f mr8-i custom" :refName="'tooltipOver5'"></ellipsis-tooltip> | ||
| 1634 | </span> | ||
| 1635 | </div> | ||
| 1636 | <div class="list_item wrap" style="width: 40%;"> | ||
| 1637 | <span class="item_label">策略执行者标识</span> | ||
| 1638 | <span class="item_value"><ellipsis-tooltip :content="nodeInfoFormItems[5].default || '--'" | ||
| 1639 | class-name="w100f mr8-i custom" :refName="'tooltipOver6'"></ellipsis-tooltip> | ||
| 1640 | </span> | ||
| 1641 | </div> | ||
| 1642 | </div> | ||
| 1643 | <StrategyTable ref="strategyTableRef" :show-title="true" :is-look="true" :isReport="true" | ||
| 1644 | :value="detailInfo.policys || []"> | ||
| 1645 | </StrategyTable> | ||
| 1646 | </ContentWrap> | ||
| 1647 | <div class="sign-file-main"> | ||
| 1648 | <div class="title-desc">{{ userData.tenantGuid == detailInfo.dataUserGuid ? '数据使用方' : '数据提供方' }}签章:</div> | ||
| 1649 | <div class="title-desc">法人签名:</div> | ||
| 1650 | </div> | ||
| 1651 | </div> | ||
| 1652 | </div> | ||
| 1653 | </template> | ||
| 1654 | |||
| 1655 | <style lang="scss" scoped> | ||
| 1656 | .container_wrap { | ||
| 1657 | overflow: hidden; | ||
| 1658 | |||
| 1659 | .content_main { | ||
| 1660 | height: calc(100% - 45px); | ||
| 1661 | overflow: hidden auto; | ||
| 1662 | |||
| 1663 | &.panel { | ||
| 1664 | padding: 0 16px 16px; | ||
| 1665 | } | ||
| 1666 | } | ||
| 1667 | } | ||
| 1668 | |||
| 1669 | .first-title-row { | ||
| 1670 | background-color: #fff; | ||
| 1671 | padding: 14px 0px 0px 0px; | ||
| 1672 | |||
| 1673 | .title-row { | ||
| 1674 | display: flex; | ||
| 1675 | flex-direction: row; | ||
| 1676 | align-items: center; | ||
| 1677 | |||
| 1678 | .title { | ||
| 1679 | font-size: 18px; | ||
| 1680 | color: #212121; | ||
| 1681 | line-height: 27px; | ||
| 1682 | font-weight: 600; | ||
| 1683 | max-width: calc(100% - 120px); | ||
| 1684 | margin-right: 8px; | ||
| 1685 | } | ||
| 1686 | } | ||
| 1687 | } | ||
| 1688 | |||
| 1689 | .list_panel { | ||
| 1690 | display: flex; | ||
| 1691 | flex-wrap: wrap; | ||
| 1692 | display: flex; | ||
| 1693 | align-items: flex-start; | ||
| 1694 | |||
| 1695 | &.main { | ||
| 1696 | .list_item { | ||
| 1697 | width: 25%; | ||
| 1698 | } | ||
| 1699 | } | ||
| 1700 | |||
| 1701 | &.two-per { | ||
| 1702 | .list_item { | ||
| 1703 | width: 50%; | ||
| 1704 | } | ||
| 1705 | } | ||
| 1706 | |||
| 1707 | .list_item { | ||
| 1708 | width: 33.33%; | ||
| 1709 | line-height: 32px; | ||
| 1710 | font-size: 14px; | ||
| 1711 | color: var(--el-text-color-regular); | ||
| 1712 | display: flex; | ||
| 1713 | justify-content: space-between; | ||
| 1714 | min-width: 120px; | ||
| 1715 | |||
| 1716 | &.wrap { | ||
| 1717 | flex-direction: column; | ||
| 1718 | |||
| 1719 | .item_value { | ||
| 1720 | padding: 0px 4px 0px 0px; | ||
| 1721 | } | ||
| 1722 | } | ||
| 1723 | |||
| 1724 | .item_label { | ||
| 1725 | text-align: left; | ||
| 1726 | } | ||
| 1727 | |||
| 1728 | .item_value { | ||
| 1729 | color: var(--el-color-regular); | ||
| 1730 | padding: 0 4px; | ||
| 1731 | flex: 1; | ||
| 1732 | text-align: justify; | ||
| 1733 | min-width: 0; | ||
| 1734 | |||
| 1735 | &.link { | ||
| 1736 | color: var(--el-color-primary); | ||
| 1737 | cursor: pointer; | ||
| 1738 | } | ||
| 1739 | |||
| 1740 | &.row { | ||
| 1741 | display: flex; | ||
| 1742 | justify-content: flex-start; | ||
| 1743 | align-items: center; | ||
| 1744 | flex-direction: row; | ||
| 1745 | |||
| 1746 | :deep(.custom) { | ||
| 1747 | width: auto; | ||
| 1748 | max-width: calc(100% - 75px); | ||
| 1749 | } | ||
| 1750 | } | ||
| 1751 | } | ||
| 1752 | |||
| 1753 | &.is_block { | ||
| 1754 | width: 100%; | ||
| 1755 | |||
| 1756 | .item_value { | ||
| 1757 | white-space: pre-wrap; | ||
| 1758 | } | ||
| 1759 | } | ||
| 1760 | |||
| 1761 | &.isFile { | ||
| 1762 | // width: 50%; | ||
| 1763 | display: flex; | ||
| 1764 | flex-direction: column; | ||
| 1765 | justify-content: space-between; | ||
| 1766 | |||
| 1767 | .item_label { | ||
| 1768 | // width: 100px; | ||
| 1769 | // text-align: right; | ||
| 1770 | flex-shrink: 0; | ||
| 1771 | } | ||
| 1772 | |||
| 1773 | .item_value { | ||
| 1774 | flex: 1 1 0%; | ||
| 1775 | min-width: 100px; | ||
| 1776 | white-space: pre-wrap; | ||
| 1777 | } | ||
| 1778 | } | ||
| 1779 | } | ||
| 1780 | } | ||
| 1781 | |||
| 1782 | .empty-div { | ||
| 1783 | height: 4px; | ||
| 1784 | background: #E2E7EF; | ||
| 1785 | margin: 12px -16px 0px; | ||
| 1786 | } | ||
| 1787 | |||
| 1788 | .mt6 { | ||
| 1789 | margin-top: 6px; | ||
| 1790 | } | ||
| 1791 | |||
| 1792 | .tool_btns { | ||
| 1793 | height: 44px; | ||
| 1794 | margin: 0 -8px; | ||
| 1795 | display: flex; | ||
| 1796 | justify-content: center; | ||
| 1797 | align-items: center; | ||
| 1798 | border-top: 1px solid #d9d9d9; | ||
| 1799 | } | ||
| 1800 | |||
| 1801 | .h-title { | ||
| 1802 | font-size: 14px; | ||
| 1803 | color: #212121; | ||
| 1804 | font-weight: 600; | ||
| 1805 | margin-bottom: 4px; | ||
| 1806 | } | ||
| 1807 | |||
| 1808 | :deep(.el-tag.el-tag--primary) { | ||
| 1809 | color: #0E5FD8; | ||
| 1810 | background: #F2F9FF; | ||
| 1811 | border: 1px solid rgba(224, 239, 255, 1); | ||
| 1812 | min-width: 56px; | ||
| 1813 | } | ||
| 1814 | |||
| 1815 | .progress { | ||
| 1816 | width: 100%; | ||
| 1817 | display: flex; | ||
| 1818 | justify-content: start; | ||
| 1819 | margin-top: 12px; | ||
| 1820 | margin-bottom: 12px; | ||
| 1821 | } | ||
| 1822 | |||
| 1823 | .progress>div { | ||
| 1824 | width: 25%; | ||
| 1825 | height: 28px; | ||
| 1826 | line-height: 28px; | ||
| 1827 | color: white; | ||
| 1828 | position: relative; | ||
| 1829 | text-align: center; | ||
| 1830 | |||
| 1831 | &.bg-gray { | ||
| 1832 | color: #666; | ||
| 1833 | background-color: #F2F2F2; | ||
| 1834 | } | ||
| 1835 | |||
| 1836 | &.active { | ||
| 1837 | background-color: #5797FF; | ||
| 1838 | color: #fff; | ||
| 1839 | |||
| 1840 | &.no-select { | ||
| 1841 | background-color: #85B8FF; | ||
| 1842 | } | ||
| 1843 | } | ||
| 1844 | |||
| 1845 | } | ||
| 1846 | |||
| 1847 | /* 三角形 */ | ||
| 1848 | .triangle-box { | ||
| 1849 | display: inline-block; | ||
| 1850 | width: 30px; | ||
| 1851 | height: 28px; | ||
| 1852 | overflow: hidden; | ||
| 1853 | position: absolute; | ||
| 1854 | left: 0; | ||
| 1855 | } | ||
| 1856 | |||
| 1857 | .triangle { | ||
| 1858 | transform: rotate(45deg); | ||
| 1859 | transform-origin: left top; | ||
| 1860 | position: absolute; | ||
| 1861 | top: -3px; | ||
| 1862 | left: 0px; | ||
| 1863 | width: 24px; | ||
| 1864 | height: 28px; | ||
| 1865 | border: 3px solid white; | ||
| 1866 | |||
| 1867 | &.active { | ||
| 1868 | background-color: #5797FF; | ||
| 1869 | |||
| 1870 | &.no-select { | ||
| 1871 | background-color: #85B8FF; | ||
| 1872 | } | ||
| 1873 | } | ||
| 1874 | } | ||
| 1875 | |||
| 1876 | .cursor-pointer { | ||
| 1877 | cursor: pointer; | ||
| 1878 | } | ||
| 1879 | |||
| 1880 | :deep(.el-timeline) { | ||
| 1881 | margin-left: -16px; | ||
| 1882 | |||
| 1883 | .el-timeline-item__tail { | ||
| 1884 | height: calc(100% - 18px); | ||
| 1885 | top: 14px; | ||
| 1886 | } | ||
| 1887 | |||
| 1888 | .el-timeline-item__timestamp { | ||
| 1889 | color: #212121; | ||
| 1890 | } | ||
| 1891 | |||
| 1892 | .time-title { | ||
| 1893 | color: #212121; | ||
| 1894 | } | ||
| 1895 | |||
| 1896 | .row-per { | ||
| 1897 | display: flex; | ||
| 1898 | flex-direction: row; | ||
| 1899 | align-items: center; | ||
| 1900 | |||
| 1901 | .desc { | ||
| 1902 | color: #999; | ||
| 1903 | |||
| 1904 | .main { | ||
| 1905 | color: var(--el-color-primary); | ||
| 1906 | cursor: pointer; | ||
| 1907 | } | ||
| 1908 | } | ||
| 1909 | |||
| 1910 | } | ||
| 1911 | } | ||
| 1912 | |||
| 1913 | .label { | ||
| 1914 | width: 70px; | ||
| 1915 | background: #FF854D; | ||
| 1916 | border-radius: 2px; | ||
| 1917 | font-size: 12px; | ||
| 1918 | color: #FFFFFF; | ||
| 1919 | text-align: center; | ||
| 1920 | line-height: 20px; | ||
| 1921 | font-weight: 400; | ||
| 1922 | margin-right: 4px; | ||
| 1923 | white-space: pre; | ||
| 1924 | } | ||
| 1925 | |||
| 1926 | .label1 { | ||
| 1927 | width: 70px; | ||
| 1928 | background: #5797FF; | ||
| 1929 | border-radius: 2px; | ||
| 1930 | font-size: 12px; | ||
| 1931 | color: #FFFFFF; | ||
| 1932 | text-align: center; | ||
| 1933 | line-height: 20px; | ||
| 1934 | font-weight: 400; | ||
| 1935 | margin-right: 4px; | ||
| 1936 | white-space: pre; | ||
| 1937 | } | ||
| 1938 | |||
| 1939 | .label2 { | ||
| 1940 | width: 70px; | ||
| 1941 | background: #40BD6E; | ||
| 1942 | border-radius: 2px; | ||
| 1943 | font-size: 12px; | ||
| 1944 | color: #FFFFFF; | ||
| 1945 | text-align: center; | ||
| 1946 | line-height: 20px; | ||
| 1947 | font-weight: 400; | ||
| 1948 | margin-right: 4px; | ||
| 1949 | white-space: pre; | ||
| 1950 | } | ||
| 1951 | |||
| 1952 | :deep(.policy-table-detail) { | ||
| 1953 | .dialog_content { | ||
| 1954 | padding: 0px 20px 20px; | ||
| 1955 | } | ||
| 1956 | } | ||
| 1957 | |||
| 1958 | .empty-content { | ||
| 1959 | display: flex; | ||
| 1960 | align-items: center; | ||
| 1961 | justify-content: center; | ||
| 1962 | height: 250px; | ||
| 1963 | width: 100%; | ||
| 1964 | flex-direction: column; | ||
| 1965 | |||
| 1966 | .empty-text { | ||
| 1967 | font-size: 14px; | ||
| 1968 | color: #b2b2b2; | ||
| 1969 | } | ||
| 1970 | } | ||
| 1971 | |||
| 1972 | :deep(.dialog-form-inline.col3) { | ||
| 1973 | align-items: flex-start; | ||
| 1974 | } | ||
| 1975 | |||
| 1976 | :deep(.el-table) { | ||
| 1977 | .el-table__expanded-cell { | ||
| 1978 | padding: 16px; | ||
| 1979 | } | ||
| 1980 | } | ||
| 1981 | |||
| 1982 | .sign-main { | ||
| 1983 | .item-label { | ||
| 1984 | line-height: 21px; | ||
| 1985 | color: #666; | ||
| 1986 | } | ||
| 1987 | |||
| 1988 | .required { | ||
| 1989 | color: #fb2323; | ||
| 1990 | margin-left: 2px; | ||
| 1991 | } | ||
| 1992 | } | ||
| 1993 | |||
| 1994 | #pdf-content { | ||
| 1995 | padding: 12px; | ||
| 1996 | width: 780px; | ||
| 1997 | |||
| 1998 | :deep(.el-table .cell) { | ||
| 1999 | white-space: normal; | ||
| 2000 | word-break: break-word; | ||
| 2001 | } | ||
| 2002 | } | ||
| 2003 | |||
| 2004 | .sign-file-main { | ||
| 2005 | display: flex; | ||
| 2006 | flex-direction: row; | ||
| 2007 | width: 100%; | ||
| 2008 | margin-top: 24px; | ||
| 2009 | |||
| 2010 | .title-desc { | ||
| 2011 | width: 50%; | ||
| 2012 | font-size: 18px; | ||
| 2013 | color: #212121; | ||
| 2014 | font-weight: 600; | ||
| 2015 | } | ||
| 2016 | |||
| 2017 | } | ||
| 2018 | |||
| 2019 | .avoid-break { | ||
| 2020 | page-break-inside: avoid; | ||
| 2021 | break-inside: avoid; | ||
| 2022 | } | ||
| 2023 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | <route lang="yaml"> | ||
| 2 | name: smartContractManagement | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="smartContractManagement"> | ||
| 6 | import { ref } from 'vue'; | ||
| 7 | import TableTools from "@/components/Tools/table_tools.vue"; | ||
| 8 | import { | ||
| 9 | getContractPageList, | ||
| 10 | contractStatusList, | ||
| 11 | deleteContract, | ||
| 12 | cancelContract, | ||
| 13 | } from "@/api/modules/dataSmartContract" | ||
| 14 | import useDataSmartContract from "@/store/modules/dataSmartContract"; | ||
| 15 | import { commonPageConfig } from '@/utils/enum'; | ||
| 16 | import { getEnterpriseData } from "@/api/modules/dataIdentify"; | ||
| 17 | |||
| 18 | const userData = JSON.parse(localStorage.userData); | ||
| 19 | const tenantData = JSON.parse(localStorage.tenantInfo); | ||
| 20 | const router = useRouter(); | ||
| 21 | const route = useRoute(); | ||
| 22 | const { proxy } = getCurrentInstance() as any; | ||
| 23 | const dataSmartContractStore = useDataSmartContract(); | ||
| 24 | |||
| 25 | const searchItemList = ref([ | ||
| 26 | { | ||
| 27 | type: "input", | ||
| 28 | label: "", | ||
| 29 | field: "contractName", | ||
| 30 | default: "", | ||
| 31 | placeholder: "合约名称", | ||
| 32 | maxlength: 50, | ||
| 33 | clearable: true, | ||
| 34 | }, | ||
| 35 | { | ||
| 36 | type: 'select', | ||
| 37 | label: '', | ||
| 38 | field: 'contractStatus', | ||
| 39 | default: '', | ||
| 40 | placeholder: '合约状态', | ||
| 41 | options: contractStatusList, | ||
| 42 | filterable: true, | ||
| 43 | clearable: true | ||
| 44 | } | ||
| 45 | ]); | ||
| 46 | |||
| 47 | const tableFields = ref([ | ||
| 48 | { label: "序号", type: "index", width: 56, align: "center" }, | ||
| 49 | { label: "合约名称", field: "contractName", width: 160, }, | ||
| 50 | { label: "签署方式", field: "signModeName", width: 120 }, | ||
| 51 | { label: "合约状态", field: "contractStatus", type: "tag", width: 96, align: 'center' }, | ||
| 52 | { label: "合约编号", field: "contractId", width: 355 }, | ||
| 53 | { label: "发起主体", field: "tenantName", width: 205 }, | ||
| 54 | { label: "创建人", field: "createUserName", width: 130 }, | ||
| 55 | { label: "创建时间", field: "createTime", width: 170 }, | ||
| 56 | { label: "提交企业", field: "submitTenantName", width: 200 }, | ||
| 57 | { label: "提交时间", field: "submitTime", width: 170 }, | ||
| 58 | ]); | ||
| 59 | |||
| 60 | const page = ref({ | ||
| 61 | ...commonPageConfig, | ||
| 62 | contractName: '', | ||
| 63 | contractStatus: '' | ||
| 64 | }); | ||
| 65 | |||
| 66 | const currTableData: any = ref({}); | ||
| 67 | const tableInfo = ref({ | ||
| 68 | id: 'contract-table', | ||
| 69 | rowKey: 'guid', | ||
| 70 | loading: false, | ||
| 71 | fields: tableFields.value, | ||
| 72 | data: [], | ||
| 73 | page: { | ||
| 74 | type: "normal", | ||
| 75 | rows: 0, | ||
| 76 | ...page.value, | ||
| 77 | }, | ||
| 78 | actionInfo: { | ||
| 79 | label: "操作", | ||
| 80 | type: "btn", | ||
| 81 | width: 160, | ||
| 82 | btns: (scope) => { | ||
| 83 | let row = scope.row; | ||
| 84 | let btns: any = []; | ||
| 85 | let contractStatus = row.contractStatus; | ||
| 86 | if (contractStatus == '00') { //撤回状态,如果是合约发起方有重新提交按钮,否则只能查看 | ||
| 87 | if (userData.tenantGuid == row.tenantGuid) { //是本人发起的。 | ||
| 88 | btns.push({ value: 'view', label: '查看', click: () => btnHandles['view'](scope) }); | ||
| 89 | row.isDisable != 'Y' && btns.push({ value: 'edit', label: '重新提交', click: () => btnHandles['edit'](scope) }); | ||
| 90 | btns.push({ value: 'delete', label: '删除', click: () => btnHandles['delete'](scope) }) | ||
| 91 | } else { | ||
| 92 | btns.push({ value: 'view', label: '查看', click: () => btnHandles['view'](scope) }); | ||
| 93 | } | ||
| 94 | } else if (contractStatus == '01') { //发起状态 | ||
| 95 | btns.push({ value: 'edit', label: '编辑', click: () => btnHandles['edit'](scope) }); | ||
| 96 | btns.push({ value: 'delete', label: '删除', click: () => btnHandles['delete'](scope) }) | ||
| 97 | } else if (contractStatus == '02') { // 协商 | ||
| 98 | btns.push({ value: 'view', label: '查看', click: () => btnHandles['view'](scope) }); | ||
| 99 | /** | ||
| 100 | * 1. 中介签署,只需要两方都协商,中介不显示按钮。 | ||
| 101 | * 2. 点对点的话,只有对方需要协商。只要有继续协商变动之后,就需要对方确认。发起方提交后,如果对方还没协商过,发起方就没有协商按钮。 | ||
| 102 | */ | ||
| 103 | if (row.signModeCode == '01') { | ||
| 104 | if (row.negotiateEntityGuid == row.dataProviderGuid && userData.tenantGuid == row.dataUserGuid || (row.negotiateEntityGuid == row.dataUserGuid && userData.tenantGuid == row.dataProviderGuid)) { | ||
| 105 | btns.push({ value: 'consult', label: '协商', click: () => btnHandles['consult'](scope) }); | ||
| 106 | } | ||
| 107 | } else { //中介协商。 | ||
| 108 | if (!row.confirmGuids?.length) { //没有确认guids。 | ||
| 109 | if (row.negotiateEntityGuid != row.dataProviderGuid && row.negotiateEntityGuid != row.dataUserGuid) { //都不是,是中介。 | ||
| 110 | if ((userData.tenantGuid == row.dataUserGuid || userData.tenantGuid == row.dataProviderGuid)) { //中介新建,两方都有。 | ||
| 111 | btns.push({ value: 'consult', label: '协商', click: () => btnHandles['consult'](scope) }); | ||
| 112 | } | ||
| 113 | } | ||
| 114 | } else { //其中一方继续协商或确认都有confirmGuids | ||
| 115 | // 其中一方确认。协商guid还是上次的。 | ||
| 116 | if (!row.confirmGuids.includes(userData.tenantGuid) && (userData.tenantGuid == row.dataUserGuid || userData.tenantGuid == row.dataProviderGuid)) { | ||
| 117 | btns.push({ value: 'consult', label: '协商', click: () => btnHandles['consult'](scope) }); | ||
| 118 | } | ||
| 119 | } | ||
| 120 | } | ||
| 121 | // 合约发起方才有撤回按钮 | ||
| 122 | if (userData.tenantGuid == row.tenantGuid) { | ||
| 123 | btns.push({ value: 'revoke', label: '撤回', click: () => btnHandles['revoke'](scope) }); | ||
| 124 | } | ||
| 125 | } else if (contractStatus == '03') { //签署,签署过的一方不需要显示签署。 | ||
| 126 | btns.push({ value: 'view', label: '查看', click: () => btnHandles['view'](scope) }); | ||
| 127 | if (row.signModeCode == '01') { | ||
| 128 | if (!row.signatureList?.includes(userData.tenantGuid)) { | ||
| 129 | btns.push({ value: 'sign', label: '签署', click: () => btnHandles['sign'](scope) }); | ||
| 130 | } | ||
| 131 | } else { //中介 | ||
| 132 | if (!row.signatureList?.includes(userData.tenantGuid) && (userData.tenantGuid == row.dataUserGuid || userData.tenantGuid == row.dataProviderGuid)) { | ||
| 133 | btns.push({ value: 'sign', label: '签署', click: () => btnHandles['sign'](scope) }); | ||
| 134 | } | ||
| 135 | } | ||
| 136 | // 合约发起方才有撤回按钮 | ||
| 137 | if (userData.tenantGuid == row.tenantGuid) { | ||
| 138 | btns.push({ value: 'revoke', label: '撤回', click: () => btnHandles['revoke'](scope) }); | ||
| 139 | } | ||
| 140 | } else if (contractStatus == '05') { //合约履行中 | ||
| 141 | btns.push({ value: 'view', label: '查看', click: () => btnHandles['view'](scope) }); | ||
| 142 | //合约发起方才有合约解除 | ||
| 143 | if (userData.tenantGuid == row.tenantGuid) { | ||
| 144 | btns.push({ value: 'termination', label: '解除', click: () => btnHandles['termination'](scope) }); | ||
| 145 | } | ||
| 146 | } else if (contractStatus == '06' || contractStatus == '0302') { | ||
| 147 | btns.push({ value: 'view', label: '查看', click: () => btnHandles['view'](scope) }); | ||
| 148 | } | ||
| 149 | return btns; | ||
| 150 | } | ||
| 151 | } | ||
| 152 | }); | ||
| 153 | |||
| 154 | const btnHandles = { | ||
| 155 | edit: (scope) => { | ||
| 156 | router.push({ | ||
| 157 | name: 'smartContractCreate', | ||
| 158 | query: { | ||
| 159 | guid: scope.row.guid, | ||
| 160 | name: scope.row.contractName | ||
| 161 | } | ||
| 162 | }); | ||
| 163 | }, | ||
| 164 | delete: (scope) => { | ||
| 165 | proxy.$openMessageBox("此操作将永久删除, 是否继续?", () => { | ||
| 166 | deleteContract([scope.row.guid]).then((res: any) => { | ||
| 167 | if (res?.code == proxy.$passCode) { | ||
| 168 | page.value.curr = 1; | ||
| 169 | getTableData(); | ||
| 170 | proxy.$ElMessage.success('删除成功'); | ||
| 171 | } else { | ||
| 172 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 173 | } | ||
| 174 | }); | ||
| 175 | }, () => { | ||
| 176 | proxy.$ElMessage.info("已取消"); | ||
| 177 | }) | ||
| 178 | }, | ||
| 179 | consult: (scope) => { | ||
| 180 | router.push({ | ||
| 181 | name: 'smartContractDetail', | ||
| 182 | query: { | ||
| 183 | guid: scope.row.guid, | ||
| 184 | name: scope.row.contractName, | ||
| 185 | type: 'consult' | ||
| 186 | } | ||
| 187 | }); | ||
| 188 | }, | ||
| 189 | sign: (scope) => { | ||
| 190 | router.push({ | ||
| 191 | name: 'smartContractDetail', | ||
| 192 | query: { | ||
| 193 | guid: scope.row.guid, | ||
| 194 | name: scope.row.contractName, | ||
| 195 | type: 'sign' | ||
| 196 | } | ||
| 197 | }); | ||
| 198 | }, | ||
| 199 | revoke: (scope) => { | ||
| 200 | proxy.$openMessageBox("确定撤回该连合约吗?", () => { | ||
| 201 | tableInfo.value.loading = true; | ||
| 202 | cancelContract(scope.row.guid).then((res: any) => { | ||
| 203 | tableInfo.value.loading = false; | ||
| 204 | if (res.code == proxy.$passCode) { | ||
| 205 | proxy.$ElMessage.success('合约撤回成功'); | ||
| 206 | getTableData(); | ||
| 207 | } else { | ||
| 208 | proxy.$ElMessage.error(res.msg); | ||
| 209 | } | ||
| 210 | }); | ||
| 211 | }, () => { | ||
| 212 | proxy.$ElMessage.info("已取消撤回"); | ||
| 213 | }) | ||
| 214 | }, | ||
| 215 | termination: (scope) => {//解除合同 | ||
| 216 | router.push({ | ||
| 217 | name: 'smartContractDetail', | ||
| 218 | query: { | ||
| 219 | guid: scope.row.guid, | ||
| 220 | name: scope.row.contractName, | ||
| 221 | type: 'reject' | ||
| 222 | } | ||
| 223 | }); | ||
| 224 | }, | ||
| 225 | view: (scope) => {//查看 | ||
| 226 | if (scope.row.contractStatus == '05') { | ||
| 227 | router.push({ | ||
| 228 | name: 'smartContractDetail', | ||
| 229 | query: { | ||
| 230 | guid: scope.row.guid, | ||
| 231 | name: scope.row.contractName, | ||
| 232 | type: 'keepAgree', | ||
| 233 | isDetail: 'Y' | ||
| 234 | } | ||
| 235 | }); | ||
| 236 | } else { | ||
| 237 | router.push({ | ||
| 238 | name: 'smartContractDetail', | ||
| 239 | query: { | ||
| 240 | guid: scope.row.guid, | ||
| 241 | name: scope.row.contractName, | ||
| 242 | isDetail: 'Y' | ||
| 243 | } | ||
| 244 | }); | ||
| 245 | } | ||
| 246 | } | ||
| 247 | } | ||
| 248 | |||
| 249 | const toSearch = (val: any, clear: boolean = false) => { | ||
| 250 | if (clear) { | ||
| 251 | searchItemList.value.map((item) => (item.default = "")); | ||
| 252 | page.value.contractName = ''; | ||
| 253 | page.value.contractStatus = ""; | ||
| 254 | } else { | ||
| 255 | page.value.contractName = val.contractName; | ||
| 256 | page.value.contractStatus = val.contractStatus; | ||
| 257 | } | ||
| 258 | getTableData(); | ||
| 259 | }; | ||
| 260 | |||
| 261 | const getTableData = () => { | ||
| 262 | tableInfo.value.loading = true | ||
| 263 | getContractPageList({ | ||
| 264 | pageIndex: page.value.curr, | ||
| 265 | pageSize: page.value.limit, | ||
| 266 | contractName: page.value.contractName, | ||
| 267 | contractStatus: page.value.contractStatus | ||
| 268 | }).then((res: any) => { | ||
| 269 | tableInfo.value.loading = false | ||
| 270 | if (res?.code == proxy.$passCode) { | ||
| 271 | const data = res.data || {} | ||
| 272 | tableInfo.value.data = data.records || [] | ||
| 273 | tableInfo.value.page.limit = data.pageSize | ||
| 274 | tableInfo.value.page.curr = data.pageIndex | ||
| 275 | tableInfo.value.page.rows = data.totalRows | ||
| 276 | } else { | ||
| 277 | res?.msg && proxy.$ElMessage.error(res?.msg) | ||
| 278 | } | ||
| 279 | }).catch(() => { | ||
| 280 | tableInfo.value.loading = false | ||
| 281 | }) | ||
| 282 | }; | ||
| 283 | |||
| 284 | const tablePageChange = (info) => { | ||
| 285 | page.value.curr = Number(info.curr); | ||
| 286 | page.value.limit = Number(info.limit); | ||
| 287 | tableInfo.value.page.curr = page.value.curr; | ||
| 288 | tableInfo.value.page.limit = page.value.limit; | ||
| 289 | getTableData(); | ||
| 290 | }; | ||
| 291 | |||
| 292 | const newCreate = () => { | ||
| 293 | let exec = () => { | ||
| 294 | if (tenantData.isCertification != 'Y' && !currTenantDetailInfo.value.trustedIdentityCredential) { //认证过的 | ||
| 295 | if (userData.superTubeFlag != 'Y') {//平台用户 | ||
| 296 | proxy.$ElMessage.error('请先完成企业认证后再进行创建'); | ||
| 297 | return; | ||
| 298 | } | ||
| 299 | } | ||
| 300 | router.push({ | ||
| 301 | name: 'smartContractCreate' | ||
| 302 | }); | ||
| 303 | } | ||
| 304 | if (psLogon.value) { | ||
| 305 | psLogon.value.then(() => { | ||
| 306 | exec(); | ||
| 307 | }) | ||
| 308 | } else { | ||
| 309 | exec(); | ||
| 310 | } | ||
| 311 | } | ||
| 312 | |||
| 313 | onActivated(() => { | ||
| 314 | if (dataSmartContractStore.isRefresh) {//如果是首次加载,则不需要调用 | ||
| 315 | page.value.curr = 1; | ||
| 316 | getTableData(); | ||
| 317 | dataSmartContractStore.set(false); | ||
| 318 | } | ||
| 319 | }) | ||
| 320 | |||
| 321 | /** 当前会员是否认证信息 */ | ||
| 322 | const currTenantDetailInfo: any = ref({}); | ||
| 323 | |||
| 324 | const psLogon = ref(); | ||
| 325 | |||
| 326 | onBeforeMount(() => { | ||
| 327 | !dataSmartContractStore.isRefresh && toSearch({}) | ||
| 328 | if (tenantData.isCertification != 'Y') { | ||
| 329 | psLogon.value = getEnterpriseData({ | ||
| 330 | logonUser: userData.tenantName == "非认证会员" ? userData.logonUser : tenantData.logonUser | ||
| 331 | }).then((res: any) => { | ||
| 332 | psLogon.value = null; | ||
| 333 | if (res?.code == proxy.$passCode) { | ||
| 334 | currTenantDetailInfo.value = res.data || {}; | ||
| 335 | } else { | ||
| 336 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 337 | } | ||
| 338 | }).catch(() => { | ||
| 339 | psLogon.value = null; | ||
| 340 | }); | ||
| 341 | } | ||
| 342 | }) | ||
| 343 | |||
| 344 | </script> | ||
| 345 | |||
| 346 | <template> | ||
| 347 | <div class="container_wrap"> | ||
| 348 | <div class="table_tool_wrap"> | ||
| 349 | <TableTools :searchItems="searchItemList" :searchId="'contract-search'" @search="toSearch" :init="false" /> | ||
| 350 | <div class="tools_btns"> | ||
| 351 | <el-button type="primary" @click="newCreate">新增</el-button> | ||
| 352 | </div> | ||
| 353 | </div> | ||
| 354 | <div class="table_panel_wrap"> | ||
| 355 | <Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" /> | ||
| 356 | </div> | ||
| 357 | </div> | ||
| 358 | </template> | ||
| 359 | |||
| 360 | <style lang="scss" scoped> | ||
| 361 | .container_wrap { | ||
| 362 | padding: 0px 16px; | ||
| 363 | } | ||
| 364 | |||
| 365 | :deep(.el-tag.el-tag--primary) { | ||
| 366 | color: #0E5FD8; | ||
| 367 | background: #F2F9FF; | ||
| 368 | border: 1px solid rgba(224, 239, 255, 1); | ||
| 369 | } | ||
| 370 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | <route lang="yaml"> | ||
| 2 | name: strategyManagement | ||
| 3 | </route> | ||
| 4 | |||
| 5 | <script lang="ts" setup name="strategyManagement"> | ||
| 6 | import { ref } from 'vue'; | ||
| 7 | import TableTools from "@/components/Tools/table_tools.vue"; | ||
| 8 | import { | ||
| 9 | getPageList, | ||
| 10 | updateTemplateState, | ||
| 11 | savePolicyTemplate, | ||
| 12 | updatePolicyTemplate, | ||
| 13 | deletePolicyTemplate | ||
| 14 | } from "@/api/modules/dataSmartContract"; | ||
| 15 | import { | ||
| 16 | getParamsList | ||
| 17 | } from "@/api/modules/queryService"; | ||
| 18 | import { useValidator } from '@/hooks/useValidator'; | ||
| 19 | |||
| 20 | const { required, regexpValidate } = useValidator(); | ||
| 21 | const router = useRouter(); | ||
| 22 | const route = useRoute(); | ||
| 23 | const { proxy } = getCurrentInstance() as any; | ||
| 24 | |||
| 25 | const policyTypeList: any = ref([]); | ||
| 26 | |||
| 27 | /** 约束运算符字典下拉 */ | ||
| 28 | const operatorOptionList: any = ref([]); | ||
| 29 | |||
| 30 | const searchItemList = ref([ | ||
| 31 | { | ||
| 32 | type: "input", | ||
| 33 | label: "", | ||
| 34 | field: "policyName", | ||
| 35 | default: "", | ||
| 36 | placeholder: "策略名称", | ||
| 37 | maxlength: 50, | ||
| 38 | clearable: true, | ||
| 39 | }, | ||
| 40 | { | ||
| 41 | type: 'tree-select', | ||
| 42 | label: '', | ||
| 43 | field: 'policyTypeCode', | ||
| 44 | default: '', | ||
| 45 | placeholder: '维度类型', | ||
| 46 | options: policyTypeList.value, | ||
| 47 | filterable: true, | ||
| 48 | clearable: true, | ||
| 49 | checkStrictly: true,//只能选择叶子节点。 | ||
| 50 | lazy: false, | ||
| 51 | multiple: false, | ||
| 52 | collapseTagsTooltip: true, | ||
| 53 | collapseTags: true, | ||
| 54 | props: { | ||
| 55 | label: "label", | ||
| 56 | value: "value", | ||
| 57 | children: 'childDictList' | ||
| 58 | }, | ||
| 59 | showCheckbox: false | ||
| 60 | } | ||
| 61 | ]); | ||
| 62 | |||
| 63 | const tableFields = ref([ | ||
| 64 | { label: "序号", type: "index", width: 56, align: "center" }, | ||
| 65 | { label: "策略id", field: "policyId", width: 205, }, | ||
| 66 | { label: "策略名称", field: "policyName", width: 130 }, | ||
| 67 | { label: "策略英文名", field: "policyEnName", width: 140 }, | ||
| 68 | { label: "维度类型", field: "policyTypeCodeName", width: 100 }, | ||
| 69 | { label: '启用状态', width: 96, field: 'bizStatus', type: 'switch', activeText: '启用', inactiveText: '停用', activeValue: 'Y', inactiveValue: 'N', align: 'center' }, | ||
| 70 | { label: "描述", field: "description", width: 200 }, | ||
| 71 | { label: "修改人", field: "updateUserName", width: 130 }, | ||
| 72 | { label: "修改时间", field: "updateTime", width: 170 }, | ||
| 73 | ]); | ||
| 74 | |||
| 75 | const page = ref({ | ||
| 76 | limit: 50, | ||
| 77 | curr: 1, | ||
| 78 | sizes: [ | ||
| 79 | { label: "10", value: 10 }, | ||
| 80 | { label: "50", value: 50 }, | ||
| 81 | { label: "100", value: 100 }, | ||
| 82 | { label: "150", value: 150 }, | ||
| 83 | { label: "200", value: 200 }, | ||
| 84 | ], | ||
| 85 | policyName: '', | ||
| 86 | policyTypeCode: '' | ||
| 87 | }); | ||
| 88 | const currTableData: any = ref({}); | ||
| 89 | const tableInfo = ref({ | ||
| 90 | id: 'value-asset-table', | ||
| 91 | rowKey: 'guid', | ||
| 92 | loading: false, | ||
| 93 | fields: tableFields.value, | ||
| 94 | data: [], | ||
| 95 | page: { | ||
| 96 | type: "normal", | ||
| 97 | rows: 0, | ||
| 98 | ...page.value, | ||
| 99 | }, | ||
| 100 | actionInfo: { | ||
| 101 | label: "操作", | ||
| 102 | type: "btn", | ||
| 103 | width: 100, | ||
| 104 | btns: (scope) => { | ||
| 105 | let row = scope.row; | ||
| 106 | if (row.bizStatus == 'Y') { | ||
| 107 | return [{ | ||
| 108 | label: "查看", value: "view", click: (scope) => { | ||
| 109 | drawerInfo.value.visible = true; | ||
| 110 | drawerInfo.value.type = 'view'; | ||
| 111 | drawerInfo.value.header.title = '查看策略'; | ||
| 112 | drawerInfo.value.footer.visible = false; | ||
| 113 | classEditFormItems.value.forEach(item => { | ||
| 114 | item.default = scope.row[item.field] || ''; | ||
| 115 | item.disabled = true; | ||
| 116 | }); | ||
| 117 | let val = scope.row.policyTypeCode; | ||
| 118 | let selectItem = val && policyTypeList.value.find(p => p.childDictList?.some(c => c.value == val)); | ||
| 119 | classEditFormItems.value.at(-2).visible = selectItem?.value == 'YS'; | ||
| 120 | } | ||
| 121 | }] | ||
| 122 | } else { | ||
| 123 | return [{ | ||
| 124 | label: "编辑", value: "edit", click: (scope) => { | ||
| 125 | currTableData.value = scope.row; | ||
| 126 | drawerInfo.value.visible = true; | ||
| 127 | drawerInfo.value.type = 'edit'; | ||
| 128 | drawerInfo.value.header.title = '编辑策略'; | ||
| 129 | drawerInfo.value.footer.visible = true; | ||
| 130 | classEditFormItems.value.forEach(item => { | ||
| 131 | item.default = scope.row[item.field] || ''; | ||
| 132 | item.disabled = false; | ||
| 133 | }); | ||
| 134 | let val = scope.row.policyTypeCode; | ||
| 135 | let selectItem = val && policyTypeList.value.find(p => p.childDictList?.some(c => c.value == val)); | ||
| 136 | classEditFormItems.value.at(-2).visible = selectItem?.value == 'YS'; | ||
| 137 | } | ||
| 138 | }, { | ||
| 139 | label: "删除", value: "delete", click: (scope) => { | ||
| 140 | proxy.$openMessageBox("此操作将永久删除, 是否继续?", () => { | ||
| 141 | deletePolicyTemplate([scope.row.guid]).then((res: any) => { | ||
| 142 | if (res?.code == proxy.$passCode) { | ||
| 143 | page.value.curr = 1; | ||
| 144 | getTableData(); | ||
| 145 | proxy.$ElMessage.success('删除成功'); | ||
| 146 | } else { | ||
| 147 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 148 | } | ||
| 149 | }); | ||
| 150 | }, () => { | ||
| 151 | proxy.$ElMessage.info("已取消"); | ||
| 152 | }) | ||
| 153 | } | ||
| 154 | }] | ||
| 155 | } | ||
| 156 | } | ||
| 157 | } | ||
| 158 | }); | ||
| 159 | |||
| 160 | const tableSwitchBeforeChange = (scope, field, callback) => { | ||
| 161 | const msg = `确定${scope.row[field] == 'Y' ? '停用' : '启用'}【${scope.row.policyName}】策略?` | ||
| 162 | proxy.$openMessageBox(msg, () => { | ||
| 163 | const state = scope.row[field] == 'Y' ? 'N' : 'Y' | ||
| 164 | const result = tableSwitchChange(state, scope, field) | ||
| 165 | callback(result) | ||
| 166 | }, () => { | ||
| 167 | callback(false) | ||
| 168 | }); | ||
| 169 | } | ||
| 170 | |||
| 171 | const tableSwitchChange = (val, scope, field) => { | ||
| 172 | return new Promise((resolve, reject) => { | ||
| 173 | let params = { | ||
| 174 | guid: scope.row.guid, | ||
| 175 | bizStatus: val | ||
| 176 | } | ||
| 177 | updateTemplateState(params).then((res: any) => { | ||
| 178 | if (res?.code == proxy.$passCode && res?.data) { | ||
| 179 | getTableData(); | ||
| 180 | proxy.$ElMessage({ | ||
| 181 | type: "success", | ||
| 182 | message: `【${scope.row.policyName}】策略${val == 'Y' ? '启用' : '停用'}成功`, | ||
| 183 | }); | ||
| 184 | resolve(true) | ||
| 185 | } else { | ||
| 186 | proxy.$ElMessage({ | ||
| 187 | type: "error", | ||
| 188 | message: res.msg, | ||
| 189 | }); | ||
| 190 | reject(false) | ||
| 191 | } | ||
| 192 | }).catch(() => { | ||
| 193 | reject(false) | ||
| 194 | }) | ||
| 195 | }) | ||
| 196 | } | ||
| 197 | |||
| 198 | const toSearch = (val: any, clear: boolean = false) => { | ||
| 199 | if (clear) { | ||
| 200 | searchItemList.value.map((item) => (item.default = "")); | ||
| 201 | page.value.policyName = ''; | ||
| 202 | page.value.policyTypeCode = ""; | ||
| 203 | } else { | ||
| 204 | page.value.policyName = val.policyName; | ||
| 205 | page.value.policyTypeCode = val.policyTypeCode; | ||
| 206 | } | ||
| 207 | getTableData(); | ||
| 208 | }; | ||
| 209 | |||
| 210 | const getTableData = () => { | ||
| 211 | tableInfo.value.loading = true | ||
| 212 | getPageList({ | ||
| 213 | pageIndex: page.value.curr, | ||
| 214 | pageSize: page.value.limit, | ||
| 215 | policyName: page.value.policyName, | ||
| 216 | policyTypeCode: page.value.policyTypeCode | ||
| 217 | }).then((res: any) => { | ||
| 218 | tableInfo.value.loading = false | ||
| 219 | if (res?.code == proxy.$passCode) { | ||
| 220 | const data = res.data || {} | ||
| 221 | tableInfo.value.data = data.records || [] | ||
| 222 | tableInfo.value.page.limit = data.pageSize | ||
| 223 | tableInfo.value.page.curr = data.pageIndex | ||
| 224 | tableInfo.value.page.rows = data.totalRows | ||
| 225 | } else { | ||
| 226 | proxy.$ElMessage({ | ||
| 227 | type: 'error', | ||
| 228 | message: res.msg, | ||
| 229 | }) | ||
| 230 | } | ||
| 231 | }).catch(() => { | ||
| 232 | tableInfo.value.loading = false | ||
| 233 | }) | ||
| 234 | }; | ||
| 235 | |||
| 236 | const tablePageChange = (info) => { | ||
| 237 | page.value.curr = Number(info.curr); | ||
| 238 | page.value.limit = Number(info.limit); | ||
| 239 | tableInfo.value.page.curr = page.value.curr; | ||
| 240 | tableInfo.value.page.limit = page.value.limit; | ||
| 241 | getTableData(); | ||
| 242 | }; | ||
| 243 | |||
| 244 | const defaultValueInfo = ref({ bizStatus: 'Y' }); | ||
| 245 | |||
| 246 | const newCreate = () => { | ||
| 247 | drawerInfo.value.visible = true; | ||
| 248 | drawerInfo.value.type = 'add'; | ||
| 249 | drawerInfo.value.header.title = '新增策略'; | ||
| 250 | drawerInfo.value.footer.visible = true; | ||
| 251 | classEditFormItems.value.forEach(item => { | ||
| 252 | item.default = defaultValueInfo.value[item.field] || ''; | ||
| 253 | item.disabled = false; | ||
| 254 | }); | ||
| 255 | classEditFormItems.value.at(-2).visible = false; | ||
| 256 | } | ||
| 257 | |||
| 258 | onActivated(() => { | ||
| 259 | }) | ||
| 260 | |||
| 261 | onBeforeMount(() => { | ||
| 262 | toSearch({}); | ||
| 263 | getParamsList({ dictType: '维度类型' }).then((res: any) => { | ||
| 264 | if (res?.code == proxy.$passCode) { | ||
| 265 | const data = res.data || []; | ||
| 266 | policyTypeList.value = data; | ||
| 267 | searchItemList.value[1].options = policyTypeList.value; | ||
| 268 | classEditFormItems.value[0].options = policyTypeList.value; | ||
| 269 | } else { | ||
| 270 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 271 | } | ||
| 272 | }) | ||
| 273 | getParamsList({ dictType: '约束运算符' }).then((res: any) => { | ||
| 274 | if (res?.code == proxy.$passCode) { | ||
| 275 | const data = res.data || []; | ||
| 276 | operatorOptionList.value = data; | ||
| 277 | if (classEditFormItems.value.at(-2)) { | ||
| 278 | classEditFormItems.value.at(-2).options = operatorOptionList.value; | ||
| 279 | } | ||
| 280 | } else { | ||
| 281 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 282 | } | ||
| 283 | }) | ||
| 284 | }) | ||
| 285 | |||
| 286 | const classEditFormItems: any = ref([{ | ||
| 287 | label: '维度类型', | ||
| 288 | type: 'tree-select', | ||
| 289 | placeholder: '请选择', | ||
| 290 | field: 'policyTypeCode', | ||
| 291 | default: '', | ||
| 292 | options: policyTypeList.value, | ||
| 293 | filterable: true, | ||
| 294 | clearable: true, | ||
| 295 | required: true, | ||
| 296 | showAllLevels: false, | ||
| 297 | checkStrictly: false,//只能选择叶子节点。 | ||
| 298 | lazy: false, | ||
| 299 | props: { | ||
| 300 | value: 'value', | ||
| 301 | label: 'label', | ||
| 302 | children: 'childDictList' | ||
| 303 | }, | ||
| 304 | disabled: false, | ||
| 305 | }, { | ||
| 306 | label: '策略名称', | ||
| 307 | type: 'input', | ||
| 308 | field: 'policyName', | ||
| 309 | default: '', | ||
| 310 | maxlength: 50, | ||
| 311 | placeholder: '请输入', | ||
| 312 | required: true, | ||
| 313 | clearable: true, | ||
| 314 | }, { | ||
| 315 | label: '策略英文名', | ||
| 316 | type: 'input', | ||
| 317 | field: 'policyEnName', | ||
| 318 | default: '', | ||
| 319 | maxlength: 50, | ||
| 320 | regexp: /[^A-Za-z0-9_]/g, | ||
| 321 | placeholder: '请输入', | ||
| 322 | required: true, | ||
| 323 | clearable: true, | ||
| 324 | }, { | ||
| 325 | label: '启用状态', | ||
| 326 | type: 'switch', | ||
| 327 | field: 'bizStatus', | ||
| 328 | default: 'Y', | ||
| 329 | placeholder: '请选择', | ||
| 330 | activeValue: 'Y', | ||
| 331 | inactiveValue: 'N', | ||
| 332 | switchWidth: 32, | ||
| 333 | }, { | ||
| 334 | label: '运算符', | ||
| 335 | type: 'select', | ||
| 336 | multiple: true, | ||
| 337 | collapse: true, | ||
| 338 | tagsTooltip: true, | ||
| 339 | placeholder: '默认全部', | ||
| 340 | field: 'constraintOperatorCodes', | ||
| 341 | default: '', | ||
| 342 | options: operatorOptionList.value, | ||
| 343 | filterable: true, | ||
| 344 | clearable: true, | ||
| 345 | required: false, | ||
| 346 | visible: false, | ||
| 347 | disabled: false, | ||
| 348 | }, { | ||
| 349 | label: '策略描述', | ||
| 350 | type: 'textarea', | ||
| 351 | placeholder: '请输入', | ||
| 352 | field: 'description', | ||
| 353 | default: '', | ||
| 354 | block: true, | ||
| 355 | maxlength: 500, | ||
| 356 | clearable: true, | ||
| 357 | required: true, | ||
| 358 | }]); | ||
| 359 | |||
| 360 | const classEditFormRules = ref({ | ||
| 361 | policyTypeCode: [required('请选择维度类型')], | ||
| 362 | policyName: [required('请填写策略名称')], | ||
| 363 | policyEnName: [required('请填写策略英文名')], | ||
| 364 | description: [required('请填写策略描述')] | ||
| 365 | }); | ||
| 366 | |||
| 367 | /** 新增分类的form */ | ||
| 368 | const classEditFormInfo = ref({ | ||
| 369 | type: "form", | ||
| 370 | title: "", | ||
| 371 | col: "span", | ||
| 372 | formInfo: { | ||
| 373 | id: "add-class-form", | ||
| 374 | readonly: false, | ||
| 375 | items: classEditFormItems.value, | ||
| 376 | rules: classEditFormRules.value, | ||
| 377 | }, | ||
| 378 | }); | ||
| 379 | |||
| 380 | /** 新增编辑分类。 */ | ||
| 381 | const drawerInfo = ref({ | ||
| 382 | visible: false, | ||
| 383 | direction: 'rtl', | ||
| 384 | size: 600, | ||
| 385 | header: { | ||
| 386 | title: '新增策略', | ||
| 387 | }, | ||
| 388 | type: '', | ||
| 389 | container: { | ||
| 390 | contents: [classEditFormInfo.value], | ||
| 391 | }, | ||
| 392 | footer: { | ||
| 393 | visible: true, | ||
| 394 | btns: [ | ||
| 395 | { type: 'default', label: '取消', value: 'cancel' }, | ||
| 396 | { type: 'primary', label: '确定', value: 'save', loading: false }, | ||
| 397 | ] | ||
| 398 | } | ||
| 399 | }) | ||
| 400 | |||
| 401 | const handlerDrawerSelectChange = (val, row, info) => { | ||
| 402 | if (row.field == 'policyTypeCode') { | ||
| 403 | let selectItem = val && policyTypeList.value.find(p => p.childDictList?.some(c => c.value == val)); | ||
| 404 | classEditFormItems.value.at(-2).visible = selectItem?.value == 'YS'; | ||
| 405 | classEditFormItems.value.forEach(item => { | ||
| 406 | item.default = info[item.field]; | ||
| 407 | }); | ||
| 408 | } | ||
| 409 | } | ||
| 410 | |||
| 411 | const drawerBtnClick = async (btn, info) => { | ||
| 412 | if (btn.value == 'cancel') { | ||
| 413 | drawerInfo.value.visible = false; | ||
| 414 | } else { | ||
| 415 | let constraintOperatorCodes = info.constraintOperatorCodes || []; | ||
| 416 | if (constraintOperatorCodes?.length) { | ||
| 417 | info.constraintOperatorCodes = constraintOperatorCodes.map(c => { | ||
| 418 | return operatorOptionList.value.find(o => o.value == c) | ||
| 419 | }).sort((a, b) => { | ||
| 420 | return a.orderNum - b.orderNum; | ||
| 421 | }).map(v => { | ||
| 422 | return v.value; | ||
| 423 | }) | ||
| 424 | } | ||
| 425 | drawerInfo.value.footer.btns[1].loading = true; | ||
| 426 | if (drawerInfo.value.type == 'edit') { | ||
| 427 | info.guid = currTableData.value.guid; | ||
| 428 | info.policyId = currTableData.value.policyId; | ||
| 429 | updatePolicyTemplate(info).then((res: any) => { | ||
| 430 | drawerInfo.value.footer.btns[1].loading = false; | ||
| 431 | if (res?.code == proxy.$passCode) { | ||
| 432 | drawerInfo.value.visible = false; | ||
| 433 | getTableData(); | ||
| 434 | proxy.$ElMessage.success('编辑策略成功'); | ||
| 435 | } else { | ||
| 436 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 437 | } | ||
| 438 | }); | ||
| 439 | } else { | ||
| 440 | savePolicyTemplate(info).then((res: any) => { | ||
| 441 | drawerInfo.value.footer.btns[1].loading = false; | ||
| 442 | if (res?.code == proxy.$passCode) { | ||
| 443 | drawerInfo.value.visible = false; | ||
| 444 | page.value.curr = 1; | ||
| 445 | getTableData(); | ||
| 446 | proxy.$ElMessage.success('新增策略成功'); | ||
| 447 | } else { | ||
| 448 | res?.msg && proxy.$ElMessage.error(res?.msg); | ||
| 449 | } | ||
| 450 | }); | ||
| 451 | } | ||
| 452 | } | ||
| 453 | } | ||
| 454 | |||
| 455 | </script> | ||
| 456 | |||
| 457 | <template> | ||
| 458 | <div class="container_wrap"> | ||
| 459 | <div class="table_tool_wrap"> | ||
| 460 | <TableTools :searchItems="searchItemList" :searchId="'settle-asset-search'" @search="toSearch" :init="false" /> | ||
| 461 | <div class="tools_btns"> | ||
| 462 | <el-button type="primary" @click="newCreate">新增</el-button> | ||
| 463 | </div> | ||
| 464 | </div> | ||
| 465 | <div class="table_panel_wrap"> | ||
| 466 | <Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" | ||
| 467 | @tableSwitchBeforeChange="tableSwitchBeforeChange" /> | ||
| 468 | </div> | ||
| 469 | <Drawer :drawerInfo="drawerInfo" @drawerSelectChange="handlerDrawerSelectChange" @drawerBtnClick="drawerBtnClick" | ||
| 470 | ref="drawerRef"></Drawer> | ||
| 471 | </div> | ||
| 472 | </template> | ||
| 473 | |||
| 474 | <style lang="scss" scoped> | ||
| 475 | .container_wrap { | ||
| 476 | padding: 0px 16px; | ||
| 477 | } | ||
| 478 | </style> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or sign in to post a comment