d4ed61c5 by lihua

数字合约功能迁移

1 parent 97c3d6c9
......@@ -98,6 +98,9 @@ VITE_APP_DATA_DELIVERY = http://192.168.6.20:38052/
#数据服务接口地址
VITE_APP_SERVICE_BASEURL = ms-daop-trust-api-service
#数字合约接口
VITE_APP_DIGITAL_CONTRACT_URL = ms-daop-trust-data-space-service
# 本地访问地址
# VITE_API_CIRCULATION_URL = http://localhost:9000/circulation
......
......@@ -125,6 +125,9 @@ VITE_APP_PERSONAL_URL = ms-daop-personel-service
#数据服务接口地址
VITE_APP_SERVICE_BASEURL = ms-daop-trust-api-service
#数字合约接口
VITE_APP_DIGITAL_CONTRACT_URL = ms-daop-trust-data-space-service
#流通平台接口地址
VITE_APP_CIRCULATION = http://192.168.6.20:18052/
#数据加工交付
......
......@@ -35,6 +35,7 @@
"file-saver": "^2.0.5",
"hotkeys-js": "^3.10.2",
"html2canvas": "^1.4.1",
"html2pdf.js": "^0.12.1",
"insert-css": "^2.0.0",
"jquery": "^3.7.1",
"jsencrypt": "^3.3.2",
......
......@@ -65,6 +65,9 @@ dependencies:
html2canvas:
specifier: ^1.4.1
version: 1.4.1
html2pdf.js:
specifier: ^0.12.1
version: 0.12.1
insert-css:
specifier: ^2.0.0
version: 2.0.0
......@@ -966,6 +969,11 @@ packages:
regenerator-runtime: 0.14.1
dev: false
/@babel/runtime@7.28.4:
resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==}
engines: {node: '>=6.9.0'}
dev: false
/@babel/template@7.25.9:
resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==}
engines: {node: '>=6.9.0'}
......@@ -1710,6 +1718,10 @@ packages:
resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==}
dev: true
/@types/pako@2.0.4:
resolution: {integrity: sha512-VWDCbrLeVXJM9fihYodcLiIv0ku+AlOa/TQ1SvYOaBuyrSKgEcro95LJyIsJ4vSo6BXIxOKxiJAat04CmST9Fw==}
dev: false
/@types/path-browserify@1.0.3:
resolution: {integrity: sha512-ZmHivEbNCBtAfcrFeBCiTjdIc2dey0l7oCGNGpSuRTy8jP6UVND7oUowlvDujBy8r2Hoa8bfFUOCiPWfmtkfxw==}
dev: true
......@@ -1718,6 +1730,12 @@ packages:
resolution: {integrity: sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==}
dev: true
/@types/raf@3.4.3:
resolution: {integrity: sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==}
requiresBuild: true
dev: false
optional: true
/@types/semver@7.5.8:
resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
dev: true
......@@ -1734,6 +1752,12 @@ packages:
'@types/node': 22.9.3
dev: true
/@types/trusted-types@2.0.7:
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
requiresBuild: true
dev: false
optional: true
/@types/unist@2.0.11:
resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
dev: true
......@@ -2988,6 +3012,22 @@ packages:
resolution: {integrity: sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==}
dev: true
/canvg@3.0.11:
resolution: {integrity: sha512-5ON+q7jCTgMp9cjpu4Jo6XbvfYwSB2Ow3kzHKfIyJfaCAOHLbdKPQqGKgfED/R5B+3TFFfe8pegYA+b423SRyA==}
engines: {node: '>=10.0.0'}
requiresBuild: true
dependencies:
'@babel/runtime': 7.28.4
'@types/raf': 3.4.3
core-js: 3.39.0
raf: 3.4.1
regenerator-runtime: 0.13.11
rgbcolor: 1.0.1
stackblur-canvas: 2.7.0
svg-pathdata: 6.0.3
dev: false
optional: true
/capital-case@1.0.4:
resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==}
dependencies:
......@@ -3959,6 +3999,14 @@ packages:
resolution: {integrity: sha512-m4yreHcUWHBncGVV7U+yQzc12vIlq0jMrtHZ5mW6dQMiL/7skSYNVX9wqKwOtyO9SGCgevrAFEgOCAHmamHTUA==}
dev: false
/dompurify@3.3.0:
resolution: {integrity: sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ==}
requiresBuild: true
optionalDependencies:
'@types/trusted-types': 2.0.7
dev: false
optional: true
/domutils@1.7.0:
resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==}
dependencies:
......@@ -5108,6 +5156,14 @@ packages:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
dev: true
/fast-png@6.4.0:
resolution: {integrity: sha512-kAqZq1TlgBjZcLr5mcN6NP5Rv4V2f22z00c3g8vRrwkcqjerx7BEhPbOnWCPqaHUl2XWQBJQvOT/FQhdMT7X/Q==}
dependencies:
'@types/pako': 2.0.4
iobuffer: 5.4.0
pako: 2.1.0
dev: false
/fast-uri@3.0.3:
resolution: {integrity: sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==}
dev: true
......@@ -5131,6 +5187,10 @@ packages:
resolution: {integrity: sha512-Rr5QlUeGN1mbOHlaqcSYMKVpPbgLy0AWT/W0EHxA6NGI12yO1jpoui2zBBvU2G824ltM6Ut8BFgfHSBGfkmS0A==}
dev: false
/fflate@0.8.2:
resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==}
dev: false
/figures@3.2.0:
resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==}
engines: {node: '>=8'}
......@@ -5780,6 +5840,13 @@ packages:
text-segmentation: 1.0.3
dev: false
/html2pdf.js@0.12.1:
resolution: {integrity: sha512-3rBWQ96H5oOU9jtoz3MnE/epGi27ig9h8aonBk4JTpvUERM3lMRxhIRckhJZEi4wE0YfRINoYOIDY0hLY0CHgQ==}
dependencies:
html2canvas: 1.4.1
jspdf: 3.0.4
dev: false
/htmlparser2@3.10.1:
resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==}
dependencies:
......@@ -5981,6 +6048,10 @@ packages:
engines: {node: '>= 0.10'}
dev: true
/iobuffer@5.4.0:
resolution: {integrity: sha512-DRebOWuqDvxunfkNJAlc3IzWIPD5xVxwUNbHr7xKB8E6aLJxIPfNX3CoMJghcFjpv6RWQsrcJbghtEwSPoJqMA==}
dev: false
/iota-array@1.0.0:
resolution: {integrity: sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==}
dev: true
......@@ -6512,6 +6583,19 @@ packages:
graceful-fs: 4.2.11
dev: true
/jspdf@3.0.4:
resolution: {integrity: sha512-dc6oQ8y37rRcHn316s4ngz/nOjayLF/FFxBF4V9zamQKRqXxyiH1zagkCdktdWhtoQId5K20xt1lB90XzkB+hQ==}
dependencies:
'@babel/runtime': 7.28.4
fast-png: 6.4.0
fflate: 0.8.2
optionalDependencies:
canvg: 3.0.11
core-js: 3.39.0
dompurify: 3.3.0
html2canvas: 1.4.1
dev: false
/jsprim@1.4.2:
resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==}
engines: {node: '>=0.6.0'}
......@@ -7595,6 +7679,10 @@ packages:
engines: {node: '>=6'}
dev: true
/pako@2.1.0:
resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==}
dev: false
/param-case@3.0.4:
resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
dependencies:
......@@ -7760,7 +7848,6 @@ packages:
/performance-now@2.1.0:
resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
dev: true
/picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
......@@ -8087,6 +8174,14 @@ packages:
engines: {node: '>=10'}
dev: true
/raf@3.4.1:
resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==}
requiresBuild: true
dependencies:
performance-now: 2.1.0
dev: false
optional: true
/read-pkg-up@7.0.1:
resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
engines: {node: '>=8'}
......@@ -8224,6 +8319,12 @@ packages:
which-builtin-type: 1.2.0
dev: true
/regenerator-runtime@0.13.11:
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
requiresBuild: true
dev: false
optional: true
/regenerator-runtime@0.14.1:
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
dev: false
......@@ -8388,6 +8489,13 @@ packages:
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
dev: true
/rgbcolor@1.0.1:
resolution: {integrity: sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==}
engines: {node: '>= 0.8.15'}
requiresBuild: true
dev: false
optional: true
/rimraf@3.0.2:
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
deprecated: Rimraf versions prior to v4 are no longer supported
......@@ -8844,6 +8952,13 @@ packages:
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'
dev: true
/stackblur-canvas@2.7.0:
resolution: {integrity: sha512-yf7OENo23AGJhBriGx0QivY5JP6Y1HbrrDI6WLt6C5auYZXlQrheoY8hD4ibekFKz1HOfE48Ww8kMWMnJD/zcQ==}
engines: {node: '>=0.1.14'}
requiresBuild: true
dev: false
optional: true
/static-extend@0.1.2:
resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==}
engines: {node: '>=0.10.0'}
......@@ -9271,6 +9386,13 @@ packages:
- supports-color
dev: true
/svg-pathdata@6.0.3:
resolution: {integrity: sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==}
engines: {node: '>=12.0.0'}
requiresBuild: true
dev: false
optional: true
/svg-tags@1.0.0:
resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
dev: true
......
import request from "@/utils/request";
/** 企业注册认证和连接器 */
/** 企业认证 **/
// 企业认证分页
export const getEnterpriseList = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/page-list`,
method: 'post',
data: params
})
// 企业认证详情
export const getEnterpriseDetail = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/detail`,
method: 'get',
params
})
// 企业认证新增
export const enterpriseSave = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/save`,
method: 'post',
data: params
})
// 企业认证修改
export const enterpriseUpdate = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/update`,
method: 'put',
data: params
})
// 企业认证删除
export const enterpriseDelete = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/delete`,
method: 'delete',
data: params
})
// 企业认证变更删除
export const enterpriseChangeDelete = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/change/delete`,
method: 'delete',
data: params
})
// 企业认证最后一级审批
export const enterpriseApprove = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/last-approve`,
method: 'post',
data: params
})
// 企业认证进度列表
export const getTaskGressList = (params) => request({
url: `${import.meta.env.VITE_APP_PERSONAL_URL}/pending-task/page-list`,
method: 'post',
data: params
})
// 企业认证重新发起
export const getTaskRestart = (params) => request({
url: `${import.meta.env.VITE_APP_PERSONAL_URL}/pending-task/restart`,
method: 'get',
params
})
// 企业认证执行日志
export const getTaskExecutionLog = (params) => request({
url: `${import.meta.env.VITE_APP_PERSONAL_URL}/pending-task/task-info`,
method: 'get',
params
})
// 获取企业认证流程列表
export const getFlowEnterpriseList = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/flow/page-list`,
method: 'post',
data: params
})
// 获取企业信息
export const getUserTenant = () => request({
// url: `http://localhost:9000/master/ms-daop-personel-service/tenant/get-current-user-tenant-from-cache`,
url: `https://sz-lt.zgsjzc.com/master/api/ms-daop-personel-service/tenant/get-current-user-tenant-from-cache`,
method: 'get'
})
// 获取企业信息
export const getEnterpriseData = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/enterprise/detail-by-logonUser`,
method: 'get',
params
})
// 修改需求上架状态
export const updateDemandGrounding = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/demand/update-grounding-pick`,
method: 'post',
data: params
})
/** 数字合约管理 */
import request from "@/utils/request";
export const contractStatusList = [{
value: '01',
label: '发起'
}, {
value: '02',
label: '协商'
}, {
value: '03',
label: '签订'
}, {
value: '0302',
label: '签订失败'
}, {
value: '05',
label: '履行中'
}, {
value: '06',
label: '终止'
}, {
value: '00',
label: '已撤回'
}];
/** 获取策略模板的列表 */
export const getPageList = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/policy-template/page-list`,
method: 'post',
data: params
})
/** 新增策略模板 */
export const savePolicyTemplate = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/policy-template/save`,
method: 'post',
data: params
});
/** 修改策略模板 */
export const updatePolicyTemplate = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/policy-template/update`,
method: 'put',
data: params
});
/** 删除策略模板 */
export const deletePolicyTemplate = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/policy-template/delete`,
method: 'delete',
data: params
});
/** 更新策略模板状态 */
export const updateTemplateState = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/policy-template/update-status`,
method: 'put',
params
});
/** --------------------------- 合约模板管理 -------------------------- */
/** 获取策略模板的列表 */
export const getContractTemplatePageList = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/page-list`,
method: 'post',
data: params
})
/** 新增合约模板状态 */
export const saveContractTemplate = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/save`,
method: 'post',
data: params
});
/** 更新合约模板状态 */
export const updateContractTemplate = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/update`,
method: 'put',
data: params
});
/** 更新合约模板状态 */
export const updateContractTemplateState = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/update-status`,
method: 'put',
params
});
/** 删除策略模板 */
export const deleteContractTemplate = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/delete`,
method: 'delete',
data: params
});
/** 获取策略模板详情 */
export const getContractTemplateDetail = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/detail`,
method: 'get',
params
});
/** 复制合约模板 */
export const copyContractTemplate = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/copy`,
method: 'get',
params
});
/** 获取操作行为下拉列表 */
export const getActionPolicyList = () => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/policy-template/list-by-policy-type?policyType=CZ`,
method: 'get'
});
/** 获取约束条件下拉列表 */
export const getConstraintPolicyList = () => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/policy-template/list-by-policy-type?policyType=YS`,
method: 'get'
});
/** 根据状态获取可用的数字合约模板 */
export const getValidContractTemplateList = () => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-template/list-by-biz-status`,
method: 'get'
});
/** --------------------- 合约管理 ----------------------- */
export const getContractPageList = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/page-list`,
method: 'post',
data: params
})
/** 合约备案列表 */
export const getContractOverviewPageList = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/overview-page-list`,
method: 'post',
data: params
})
/** 获取合约备案的发起主体下拉列表 */
export const getContractOverviewTenantList = () => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/tenant-list`,
method: 'get',
});
/** 获取下拉数据产品列表 */
export const getContractDataProduct = () => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/get-data-product`,
method: 'post'
})
/** 创建合约 */
export const saveContract = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/save`,
method: 'post',
data: params
})
/** 更新合约 */
export const updateContract = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/update`,
method: 'put',
data: params
})
export const deleteContract = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/delete`,
method: 'delete',
data: params
});
export const getContractDetail = (guid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/detail?guid=${guid}`,
method: 'get',
});
/** 查询协商信息详情 */
export const getContractNegotiate = (guid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/get-negotiate?guid=${guid}`,
method: 'post',
});
/** 根据版本获取协商信息 */
export const getContractNegoPlicyByVersion = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/get-policy-by-version?contractGuid=${params.guid}&version=${params.version}`,
method: 'get'
});
/** 拒绝本次合约 */
export const rejectContract = (guid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/reject?guid=${guid}`,
method: 'post',
});
/** 确认本次合约 */
export const confirmContract = (guid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/confirm?guid=${guid}`,
method: 'post',
});
/** 继续本地合约协商 */
export const continueContractNegotiate = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/continue-negotiate`,
method: 'post',
data: params
});
/** 获取可选的企业下拉列表,认证过之后带标识的 */
export const getContractTenantList = () => request({
url: `${import.meta.env.VITE_APP_PERSONAL_URL}/tenant/get-social-credit-code-tenant`,
method: 'post'
})
/** 撤回合约 */
export const cancelContract = (guid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/canal?guid=${guid}`,
method: 'post',
});
/** 签署合约 */
export const signContract = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-signature/save`,
method: 'post',
data: params
});
/** 获取签署合约详情 */
export const getSignListInfo = (guid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-signature/list-by-contract-guid?contractGuid=${guid}`,
method: 'post',
});
/** ----------------- 合约履约信息 ----------------- */
export const getContractProof = (guid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/proof-execution/proof-by-contract-guid?contractGuid=${guid}`,
method: 'get'
});
/** 获取履约签名 */
export const getContractExecList = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/proof-execution/execution-list-by-contract-guid`,
method: 'post',
data: params
});
/** 解除合同 */
export const terminateContract = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-terminate/save`,
method: 'post',
data: params
});
/** 获取终止合约信息 */
export const getTerminateDetailInfo = (guid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-terminate/detail?contractGuid=${guid}`,
method: 'get'
});
/** 日志管理-操作记录 */
export const getContractOperationLog = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-operation-log/page-list`,
method: 'post',
data: params
})
/** 操作记录详情 */
export const getContractOperationLogDetail = (guid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-operation-log/detail?guid=${guid}`,
method: 'get'
})
/** 日志管理-过程记录 */
export const getContractProcessLog = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-process-log/page-list`,
method: 'post',
data: params
})
export const getContractProcessLogDetail = (guid) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-process-log/detail?guid=${guid}`,
method: 'get'
})
/** ------------ 合约统计记录 -------------- */
/** 获取备案统计 */
export const getContractStatis = () => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract/get-contract-statistics`,
method: 'get'
})
export const getContractMonthStatis = () => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-signature/get-month-signature`,
method: 'get'
})
/** 获取合约履行异常预警记录 */
export const getLogTableList = (params) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-process-log/page-abnormal-warning`,
method: 'post',
data: params
})
/** 生成数字签名文件 */
export const getSignatureFile = (params, data) => request({
url: `${import.meta.env.VITE_APP_DIGITAL_CONTRACT_URL}/contract-signature/get-signature-base?pageIndex=${data.pageIndex}&yPosition=${data.yPosition}`,
method: 'post',
data: params,
headers: {
'Content-Type': 'multipart/form-data'
}
})
......@@ -364,3 +364,30 @@ a {
.mb10 {
margin-bottom: 10px;
}
.el-tabs.log-tabs {
height: 100%;
.el-tabs__header {
margin-bottom: 0;
}
.el-tabs__item {
height: 32px;
padding: 0px;
width: 90px;
&:last-child {
width: 90px;
}
}
.el-tabs__content {
height: calc(100% - 32px);
}
.el-tab-pane {
padding: 0px 16px;
height: 100%;
}
}
\ No newline at end of file
......
......@@ -24,8 +24,7 @@ const props = defineProps({
const emits = defineEmits(["expand"]);
// const isExpanded = ref(true);
const isExpanded = ref(props.isExpand);
const isExpanded = ref(true);
watch(
() => props.isExpand,
......@@ -47,10 +46,14 @@ const expandSwicthHandler = () => {
</script>
<template>
<ElCard class="v-content-wrap" shadow="never" :body-style="{
<ElCard
class="v-content-wrap"
shadow="never"
:body-style="{
padding: `0px`,
height: `${isExpanded ? contentHeight + 28 : 0}px`,
}">
}"
>
<template v-if="title" #header>
<div class="card-title" @click="expandSwicthHandler">
<span v-if="expandSwicth" style="padding-right: 5px; cursor: pointer">
......@@ -101,7 +104,6 @@ const expandSwicthHandler = () => {
color: var(--el-text-color-primary);
line-height: 21px;
font-weight: 600;
flex-shrink: 0;
}
.desc {
......
......@@ -9,6 +9,18 @@ export const useValidator = () => {
}
}
const requiredFiles = (message?: string) => {
return {
validator: (rule: any, value: any, callback: any) => {
if (!value?.length) {
callback(new Error('请上传文件'))
} else {
callback();
}
}, trigger: 'change'
}
}
// element scrollToError的优化
const scrollToError = () => {
nextTick(() => {
......@@ -175,6 +187,111 @@ export const useValidator = () => {
trigger: "blur",
};
}
/** 验证输入的多个IP地址 */
const validateIPList = (): FormItemRule => {
return {
validator: (rule: any, value: any, callback: any) => {
let ips = value?.split(",");
if (!ips) {
callback(new Error(`请填写合法的IP地址`));
return;
}
for (const ipV of ips) {
let ip = ipV.trim();
if (!ip || (!ipRegex.v4().test(ip) && !ipRegex.v6().test(ip))) {
callback(new Error(`请填写合法的IP地址`));
return;
}
}
callback();
},
trigger: "blur",
};
};
/** 验证输入的多个域名 */
const validateDomainList = (): FormItemRule => {
return {
validator: (rule: any, value: any, callback: any) => {
let domains = value?.split(",");
if (!domains) {
callback(new Error(`请填写合法的IP地址`));
return;
}
// 简单的域名验证正则表达式
const domainRegex =
/^(?!-)(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.?)+[a-zA-Z]{2,}$/;
// 更严格的正则,符合RFC标准
const strictDomainRegex =
/^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\.)+[A-Za-z]{2,}$/;
// 国际化域名支持(Punycode编码)
const idnRegex =
/^(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,})$/;
for (const dv of domains) {
let domain = dv.trim();
if (!domain) {
callback(new Error("请填写合法的域名,不能包含连续的逗号"));
return;
}
// 检查长度限制
if (domain.length > 253) {
callback(new Error("单个域名长度不能超过253个字符"));
return;
}
// 检查是否以点开头或结尾
if (domain.startsWith(".") || domain.endsWith(".")) {
callback(new Error("域名不能以点开头或结尾"));
return;
}
// 检查连续的点
if (domain.includes("..")) {
callback(new Error("域名不能包含连续的点"));
return;
}
// 验证每个标签(以点分隔的部分)
const labels = domain.split(".");
const tld = labels[labels.length - 1];
// 检查顶级域名(TLD)不能全是数字
if (/^\d+$/.test(tld)) {
callback(new Error("顶级域名不能全是数字"));
return;
}
// 检查每个标签的长度和内容
for (let i = 0; i < labels.length; i++) {
const label = labels[i];
// 标签长度检查
if (label.length < 1 || label.length > 63) {
callback(new Error(`标签"${label}"长度必须在1-63个字符之间`));
return;
}
// 标签内容检查
if (!/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$/.test(label)) {
callback(new Error(`标签"${label}"格式不正确`));
return;
}
}
// 使用正则表达式验证
if (!strictDomainRegex.test(domain) && !idnRegex.test(domain)) {
callback(new Error(`域名格式不符合规范`));
return;
}
}
callback();
},
trigger: "blur",
};
};
return {
required,
......@@ -184,6 +301,9 @@ export const useValidator = () => {
description,
chOrEnPreffix,
scrollToError,
checkExistName
checkExistName,
requiredFiles,
validateIPList,
validateDomainList
}
}
......
import type { RouteRecordRaw } from 'vue-router'
function Layout() {
return import('@/layouts/index.vue')
}
const routes: RouteRecordRaw[] = [
{
path: '/data-smart-contract/strategy-management',
component: Layout,
meta: {
title: '策略管理',
icon: 'sidebar-videos',
},
children: [{
path: '',
name: 'strategyManagement',
component: () => import('@/views/data_smart_contract/strategyManagement.vue'),
meta: {
title: '',
sidebar: false,
breadcrumb: false,
cache: true,
editPage: true
},
}]
},
{
path: '/data-smart-contract/contract-template',
component: Layout,
meta: {
title: '合约模板',
icon: 'sidebar-videos',
},
children: [{
path: '',
name: 'contractTemplateManagement',
component: () => import('@/views/data_smart_contract/contractTemplateManagement.vue'),
meta: {
title: '',
sidebar: false,
breadcrumb: false,
cache: true
},
}, {
path: 'contract-template-create',
name: 'contractTemplateCreate',
component: () => import('@/views/data_smart_contract/contractTemplateCreate.vue'),
meta: {
title: '新建合约模板',
sidebar: false,
breadcrumb: false,
cache: true,
editPage: true,
reuse: true
},
beforeEnter: (to, from) => {
to.meta.title = !to.query.guid ? '新建合约模板' : `编辑-${to.query.name}`;
to.meta.editPage = true;
}
}]
},
{
path: '/data-smart-contract/contract-manage',
component: Layout,
meta: {
title: '合约管理',
icon: 'sidebar-videos',
},
children: [{
path: '',
name: 'smartContractManagement',
component: () => import('@/views/data_smart_contract/smartContractManagement.vue'),
meta: {
title: '',
sidebar: false,
breadcrumb: false,
cache: true,
editPage: true
},
}, {
path: 'samart-contract-create',
name: 'smartContractCreate',
component: () => import('@/views/data_smart_contract/smartContractCreate.vue'),
meta: {
title: '新建合约',
sidebar: false,
breadcrumb: false,
cache: true,
editPage: true,
reuse: true
},
beforeEnter: (to, from) => {
to.meta.title = !to.query.guid ? '新建合约' : `编辑合约-${to.query.name}`;
to.meta.editPage = true;
}
}, {
path: 'smart-contract-detail',
name: 'smartContractDetail',
component: () => import('@/views/data_smart_contract/smartContractDetail.vue'),
meta: {
title: '合约详情-',
sidebar: false,
breadcrumb: false,
cache: true,
editPage: true,
reuse: true
},
beforeEnter: (to, from) => {
if (to.query.type == 'consult') {
to.meta.title = `合约协商-${to.query.name}`;
} else if (to.query.type == 'sign') {
to.meta.title = `合约签署-${to.query.name}`;
} else if (to.query.type == 'reject') {
to.meta.title = `合约解除-${to.query.name}`;
} else {
to.meta.title = `合约详情-${to.query.name}`;
}
}
}]
},
{
path: '/data-smart-contract/contract-record-manage',
component: Layout,
meta: {
title: '合约备案',
icon: 'sidebar-videos',
},
children: [{
path: '',
name: 'contractRecordManage',
component: () => import('@/views/data_smart_contract/contractRecordManage.vue'),
meta: {
title: '',
sidebar: false,
breadcrumb: false,
cache: true,
editPage: true
},
}]
},
{
path: '/data-smart-contract/contract-log-manage',
component: Layout,
meta: {
title: '合约日志管理',
icon: 'sidebar-videos',
},
children: [{
path: '',
name: 'contractLogManage',
component: () => import('@/views/data_smart_contract/contractLogManage.vue'),
meta: {
title: '',
sidebar: false,
breadcrumb: false,
cache: true,
editPage: true
},
}]
},
{
path: '/data-smart-contract/exec-cnt-index',
component: Layout,
meta: {
title: '合约履行监测',
icon: 'sidebar-videos',
},
children: [{
path: '',
name: 'execCntIndex',
component: () => import('@/views/data_smart_contract/execCntIndex.vue'),
meta: {
title: '',
sidebar: false,
breadcrumb: false,
cache: true,
editPage: true
},
}]
},
]
export default routes
\ No newline at end of file
......@@ -2,8 +2,8 @@ import { setupLayouts } from 'virtual:meta-layouts'
import generatedRoutes from 'virtual:generated-pages'
import type { RouteRecordRaw } from 'vue-router'
import DataAssess from './modules/dataAsset';
import DataAssetRegistry from './modules/dataAssetRegistry';
import DataService from './modules/dataService';
import DataSmartContract from './modules/dataSmartContract';
import useSettingsStore from '@/store/modules/settings'
......@@ -92,6 +92,7 @@ const systemRoutes: RouteRecordRaw[] = [
const asyncRoutes: RouteRecordRaw[] = [
...DataAssess,
...DataService,
...DataSmartContract,
// ...DataAssetRegistry,
]
......
const useDataSmartContract = defineStore(
'isRefresh',
() => {
const isRefresh = ref<boolean>(false)
function set(v: boolean) {
isRefresh.value = v;
}
return {
isRefresh,
set,
}
},
)
export default useDataSmartContract
\ No newline at end of file
......@@ -4,7 +4,7 @@ import router from '@/router'
import { ElMessage } from 'element-plus'
import apiUser from '@/api/modules/user'
import { getCurrentTime } from '@/utils/common'
import { getSystemMenu, getUserInfo, getTokenByCode, loginOut, refreshToken, editPasswordInterface, getCurrentUserInfo } from '@/api/modules/queryService'
import { getSystemMenu, getUserInfo, getTokenByCode, loginOut, refreshToken, editPasswordInterface, getCurrentUserInfo, getTenantDetailInfo } from '@/api/modules/queryService'
const useUserStore = defineStore(
// 唯一ID
......@@ -54,6 +54,13 @@ const useUserStore = defineStore(
currentTenantGuid.value = res.data.tenantInfoList && res.data.tenantInfoList.length ? res.data.tenantInfoList[0].guid : '';
localStorage.setItem('currentTenantGuid', currentTenantGuid.value);
let currentTenant = res.data.tenantInfoList?.[0];
getTenantDetailInfo(currentTenantGuid.value).then((res: any) => {
if (res.code == '00000') {
localStorage.setItem('tenantInfo', JSON.stringify(res.data));
} else {
ElMessage.error(res.msg)
}
})
return getCurrentUserInfo({tenantGuid: currentTenantGuid.value}).then((res: any) => {
console.log(res, 'getCurrentUserInfo');
if (res.code == '00000') {
......
......@@ -565,7 +565,33 @@ export const tagType = (row, type): any => {
break
default:state = "info"
}
}else if(type=="releaseStatus") {
} else if (type == 'contractStatus') {
switch(row[type]) {
case '01':
state = 'primary'
break;
case '02':
state = 'primary'
break;
case '03':
state = 'primary'
break;
case '0301':
state = 'success'
break;
case '0302':
state = 'danger'
break;
case '05':
state = 'warning'
break;
case '06':
case '00':
state = 'info'
break;
default: state = 'info'
}
} else if(type=="releaseStatus") {
switch (row[type]) {
case 1:
state = 'info'; //待发布
......@@ -889,7 +915,35 @@ export const tagMethod = (row, type) => {
break;
default: tag = "待发布"
}
}else if (type == 'success') {
} else if (type == 'contractStatus') {
switch(row[type]) {
case '00':
tag = '已撤回'
break;
case '01':
tag = '发起'
break;
case '02':
tag = '协商'
break;
case '03':
tag = '签订'
break;
case '0301':
tag = '签订成功'
break;
case '0302':
tag = '签订失败'
break;
case '05':
tag = '履行中'
break;
case '06':
tag = '终止'
break;
default: tag = "发起"
}
} else if (type == 'success') {
switch (row[type]) {
case true:
tag = '成功'
......
......@@ -21,6 +21,7 @@ import {
} from "@/api/modules/dataService";
import useDataServiceStore from "@/store/modules/dataService";
import useUserStore from "@/store/modules/user";
import { changeNum } from '@/utils/common';
const router = useRouter();
const dataServiceStore = useDataServiceStore();
......@@ -162,17 +163,21 @@ const tableInfo = ref({
{
label: "平均响应时间(s)", field: "averageRespTime", width: 130, align: 'right', type: 'chnum'
},
{
label: "绑定连接器数", field: "bindingCount", width: 130, align: 'right', type: "text_btn", value: "detail", click: (scope) => {
if (!scope.row.bindingCount) {
proxy.$ElMessage.warning('当前没有绑定连接器');
return;
}
//TODO, 查看连接器信息。
}, getName: (scope) => {
return scope.row.bindingCount != null ? changeNum(scope.row.bindingCount ?? 0) : '--';
}
},
{ label: "API请求路径", field: "requestUrl", width: TableColumnWidth.DESCRIPTION },
{
label: '状态', field: 'apiState', type: 'switch', activeText: '启用', inactiveText: '停用', activeValue: 1, inactiveValue: 0, switchWidth: 56, width: 96, align: 'center'
// , isDisabled: (scope) => {
// if (scope.row.apiState == 1) {//被授权的不能禁用。
// return true;
// }
// return scope.row.approveState != 'Y';//正在审批中的不能停用。草稿中的不能启用。
// }
},
// { label: "审批状态", field: "approveState", type: "tag", width: TableColumnWidth.STATE, align: 'center' },
{ label: "API描述", field: "apiDescription", width: TableColumnWidth.DESCRIPTION },
{ label: "修改人", field: "updateUserName", width: TableColumnWidth.USERNAME },
{ label: "修改时间", field: "updateTime", width: 170 },
......
<script lang="ts" setup name="confirmDialog">
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
type: {
type: String,
default: 'success'
},
msg: {
type: String,
default: ''
}
});
const dialogVisible = computed(() => {
return props.visible;
});
const emits = defineEmits([
"btnClick",
]);
const cancelDialog = () => {
emits("btnClick", 'cancel');
}
const submit = () => {
emits("btnClick", 'submit');
}
const dialogClose = () => {
emits("btnClick", 'cancel');
}
const imgSrc = computed(() => {
return new URL(`../../../assets/images/confirmType/${props.type}.png`, import.meta.url).href;
})
</script>
<template>
<el-dialog v-model="dialogVisible" title="规则详情" width="460" :modal="true" :close-on-click-modal="true"
destroy-on-close align-center @close="dialogClose">
<div class="content">
<img class="header-img" :src="imgSrc"></img>
<div class="title" v-html="msg"></div>
</div>
<div class="dialog-footer">
<el-button @click="cancelDialog">取消</el-button>
<el-button @click="submit" type="primary" v-preReClick>确定</el-button>
</div>
</el-dialog>
</template>
<style lang="scss" scoped>
.content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.header-img {
width: 126px;
height: 72px;
margin-bottom: 12px;
}
.title {
width: 364px;
font-size: 16px;
color: #212121;
text-align: center;
line-height: 24px;
font-weight: 400;
margin-bottom: 32px;
white-space: pre-line;
}
}
.dialog-footer {
width: 100%;
display: flex;
justify-content: center;
flex-direction: row;
margin-bottom: 12px;
}
</style>
\ No newline at end of file
<script lang="ts" setup name="showFile">
import { onUploadFilePreview, onUploadFileDownload } from '@/api/modules/common';
const props = defineProps({
file: {
type: Array<any>,
default: []
},
showRemove: {
type: Boolean,
default: false,
}
});
const emits = defineEmits(['deleteFile'])
const handleUploadFileRemove = (file) => {
emits("deleteFile");
}
</script>
<template>
<span v-for="(item) in (file || [])" class="item_value" :style="{ 'padding-left': '0px' }">
<div class="file-operate">
<template
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'">
<img class="file-img" src="../../../assets/images/excel.png" />
</template>
<template
v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'doc' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'docx'">
<img class="file-img" src="../../../assets/images/word.png" />
</template>
<template v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'zip'">
<img class="file-img" src="../../../assets/images/zip.png" />
</template>
<template v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'rar'">
<img class="file-img" src="../../../assets/images/RAR.png" />
</template>
<template v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'pdf'">
<img class="file-img" src="../../../assets/images/PDF.png" />
</template>
<template v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'png'">
<img class="file-img" src="../../../assets/images/png.png" />
</template>
<template
v-else-if="item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'jpg' || item.name.substring(item.name.lastIndexOf('.') + 1).toLowerCase() == 'jpeg'">
<img class="file-img" src="../../../assets/images/jpg.png" />
</template>
<div v-if="props.showRemove" :style="{ right: '72px' }" class="file-preview"
@click="handleUploadFileRemove(item)">删除
</div>
<div class="file-name" :style="{ width: showRemove ? 'calc(100% - 150px)' : 'calc(100% - 120px)' }"><ellipsis-tooltip :content="item.name ?? ''" class-name="w100f"
refName="tooltipOver"></ellipsis-tooltip></div>
<div :style="{ right: '36px' }"
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'"
class="file-preview" @click="onUploadFilePreview(item)">查看</div>
<div :style="{ right: '0px' }" class="file-preview" @click="onUploadFileDownload(item)">下载</div>
</div>
</span>
</template>
<style lang="scss" scoped>
.file-operate {
display: flex;
align-items: center;
position: relative;
.file-img {
width: 24px;
height: 24px;
}
&:hover {
background-color: #f5f5f5;
}
.file-name {
width: calc(100% - 120px);
color: var(--el-color-regular);
margin-left: 4px;
}
.file-preview {
position: absolute;
cursor: pointer;
color: var(--el-color-primary);
margin-right: 8px;
}
}
</style>
\ No newline at end of file
<route lang="yaml">
name: contractRecordManage
</route>
<script lang="ts" setup name="contractRecordManage">
import { ref } from 'vue';
import TableTools from "@/components/Tools/table_tools.vue";
import {
getContractOverviewPageList,
getContractOverviewTenantList
} from "@/api/modules/dataSmartContract"
import useDataSmartContract from "@/store/modules/dataSmartContract";
import { commonPageConfig } from '@/utils/enum';
const userData = JSON.parse(localStorage.userData);
const router = useRouter();
const route = useRoute();
const { proxy } = getCurrentInstance() as any;
const dataSmartContractStore = useDataSmartContract();
/** 发起主体下拉列表数据 */
const initiatorListData: any = ref([]);
const searchItemList = ref([
{
type: "input",
label: "",
field: "contractName",
default: "",
placeholder: "合约名称",
maxlength: 50,
clearable: true,
},
{
type: 'select',
label: '',
field: 'initiatorGuid',
default: '',
placeholder: '发起主体',
props: {
value: 'tenantGuid',
label: 'tenantName'
},
options: initiatorListData.value,
filterable: true,
clearable: true
},
{
type: 'date-time',
label: '',
field: 'signatureTime',
default: [],
defaultStartTime: new Date(2000, 1, 1, 0, 0, 0),
defaultEndTime: new Date(2000, 1, 1, 23, 59, 59),
startPlaceholder: '签署开始时间',
endPlaceholder: '签署结束时间',
clearable: true
},
]);
const tableFields = ref([
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "合约名称", field: "contractName", width: 160, },
{ label: "签署方式", field: "signModeName", width: 120 },
{ label: "产品名称", field: "productName", width: 180 },
{ label: "合约编号", field: "contractId", width: 355 },
{ label: "发起主体", field: "tenantName", width: 205 },
{ label: "签署时间", field: "signatureTime", width: 170 }
]);
const page = ref({
...commonPageConfig,
contractName: '',
initiatorGuid: '',
signatureTime: [],
});
const currTableData: any = ref({});
const tableInfo = ref({
id: 'contract-table',
rowKey: 'guid',
loading: false,
fields: tableFields.value,
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
label: "操作",
type: "btn",
width: 80,
btns: (scope) => {
let row = scope.row;
let btns: any = [];
btns.push({
value: 'view', label: '查看', click: () => {
if (scope.row.contractStatus == '05') {
router.push({
name: 'smartContractDetail',
query: {
guid: scope.row.guid,
name: scope.row.contractName,
type: 'keepAgree',
isDetail: 'Y'
}
});
} else {
router.push({
name: 'smartContractDetail',
query: {
guid: scope.row.guid,
name: scope.row.contractName,
isDetail: 'Y'
}
});
}
}
});
return btns;
}
}
});
const toSearch = (val: any, clear: boolean = false) => {
if (clear) {
searchItemList.value.map((item) => (item.default = ""));
page.value.contractName = '';
page.value.initiatorGuid = '';
page.value.signatureTime = [];
} else {
page.value.contractName = val.contractName;
page.value.initiatorGuid = val.initiatorGuid;
page.value.signatureTime = val.signatureTime;
}
getTableData();
};
const getTableData = () => {
getContractOverviewTenantList().then((res: any) => {
if (res?.code == proxy.$passCode) {
initiatorListData.value = res.data || [];
searchItemList.value[1].options = initiatorListData.value;
} else {
res?.msg && proxy.$ElMessage.error(res?.msg)
}
})
tableInfo.value.loading = true
getContractOverviewPageList({
pageIndex: page.value.curr,
pageSize: page.value.limit,
contractName: page.value.contractName,
initiatorGuid: page.value.initiatorGuid,
signatureStartTime: page.value.signatureTime?.[0],
signatureEndTime: page.value.signatureTime?.[1]
}).then((res: any) => {
tableInfo.value.data = [];
if (res?.code == proxy.$passCode) {
const data = res.data || {};
tableInfo.value.loading = false
tableInfo.value.data = data.records || []
tableInfo.value.page.limit = data.pageSize
tableInfo.value.page.curr = data.pageIndex
tableInfo.value.page.rows = data.totalRows
} else {
res?.msg && proxy.$ElMessage.error(res?.msg)
tableInfo.value.loading = false
}
}).catch(() => {
tableInfo.value.loading = false
})
};
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
tableInfo.value.page.curr = page.value.curr;
tableInfo.value.page.limit = page.value.limit;
getTableData();
};
onActivated(() => {
if (dataSmartContractStore.isRefresh) {//如果是首次加载,则不需要调用
page.value.curr = 1;
getTableData();
dataSmartContractStore.set(false);
}
})
onBeforeMount(() => {
!dataSmartContractStore.isRefresh && toSearch({})
})
</script>
<template>
<div class="container_wrap">
<div class="table_tool_wrap">
<TableTools :searchItems="searchItemList" :searchId="'contract-search'" @search="toSearch" :init="false" />
</div>
<div class="table_panel_wrap">
<Table :tableInfo="tableInfo" @tablePageChange="tablePageChange" />
</div>
</div>
</template>
<style lang="scss" scoped>
.container_wrap {
padding: 0px 16px;
.table_panel_wrap {
height: calc(100% - 44px);
}
}
:deep(.el-tag.el-tag--primary) {
color: #0E5FD8;
background: #F2F9FF;
border: 1px solid rgba(224, 239, 255, 1);
}
</style>
\ No newline at end of file
<route lang="yaml">
name: contractTemplateCreate
</route>
<script lang="ts" setup name="contractTemplateCreate">
import { useValidator } from "@/hooks/useValidator";
import useUserStore from "@/store/modules/user";
import useDataSmartContract from "@/store/modules/dataSmartContract";
import {
getContractTemplateDetail,
getActionPolicyList,
getConstraintPolicyList,
updateContractTemplate,
saveContractTemplate,
} from "@/api/modules/dataSmartContract"
import {
getParamsList
} from "@/api/modules/queryService";
import StrategyTable from "./components/strategyTable.vue";
const { required } = useValidator();
const router = useRouter();
const route = useRoute();
const { proxy } = getCurrentInstance() as any;
const userStore = useUserStore();
const dataSmartContract = useDataSmartContract();
const fullPath = route.fullPath;
const fullscreenLoading = ref(false);
const expandBase = ref(false);
const expandInfo = ref(false);
const baseInfoFormRef = ref();
const baseInfoFormItems = ref([{
type: 'input',
label: '合约模板名称',
field: 'templateName',
default: '',
placeholder: '请输入',
maxlength: 50,
clearable: true,
required: true
}, {
type: 'input',
label: '版本',
field: 'version',
default: 'v1.0.0',
placeholder: '-',
disabled: true,
clearable: true,
required: false
}, {
type: 'input',
label: '合约模板编号',
field: 'templateId',
default: '',
placeholder: '自动生成',
disabled: true,
clearable: true,
required: false
}, {
label: '启用状态',
type: 'switch',
field: 'bizStatus',
default: 'Y',
placeholder: '请选择',
activeValue: 'Y',
inactiveValue: 'N',
switchWidth: 32,
}, {
label: '模板描述',
type: 'textarea',
placeholder: '请输入',
field: 'description',
default: '',
block: true,
maxlength: 500,
clearable: true,
required: false,
}]);
const baseInfoFormRules = ref({
templateName: [required("请填写合约模板名称")],
});
const strategyTableRef = ref();
const cancel = () => {
proxy.$openMessageBox(
"当前页面尚未保存,确定放弃修改吗?",
() => {
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
router.push({
name: "contractTemplateManagement",
});
},
() => {
proxy.$ElMessage.info("已取消");
}
);
}
const submit = () => {
baseInfoFormRef.value.ruleFormRef?.validate((valid, errorItem) => {
if (valid) {
let validate = strategyTableRef.value?.validateValue();
if (!validate) {
expandInfo.value = true;
return;
}
let params = { ...baseInfoFormRef.value.formInline };
params.policyRQVOS = strategyTableRef.value.strategyData?.map((d, index) => {
return Object.assign({}, d, { orderNum: index + 1 })
});
if (route.query.guid) {
params.guid = route.query.guid;
fullscreenLoading.value = true;
updateContractTemplate(params).then((res: any) => {
fullscreenLoading.value = false;
if (res?.code == proxy.$passCode) {
proxy.$ElMessage.success('编辑合约模板成功');
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
router.push({
name: "contractTemplateManagement",
});
dataSmartContract.set(true);
} else {
res?.msg && proxy.$ElMessage.error(res?.msg);
}
}).catch(() => {
fullscreenLoading.value = false;
});
} else {
fullscreenLoading.value = true;
delete params.version;
saveContractTemplate(params).then((res: any) => {
fullscreenLoading.value = false;
if (res?.code == proxy.$passCode) {
proxy.$ElMessage.success('新建合约模板成功');
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
router.push({
name: "contractTemplateManagement",
});
dataSmartContract.set(true);
} else {
res?.msg && proxy.$ElMessage.error(res?.msg);
}
}).catch(() => {
fullscreenLoading.value = false;
});
}
} else {
expandBase.value = true;
var obj = Object.keys(errorItem);
baseInfoFormRef.value.ruleFormRef?.scrollToField(obj[0]);
}
})
}
const detailInfo: any = ref({});
/** 约束运算符字典下拉 */
const operatorOptionList: any = ref([]);
/** 约束行为下拉列表 */
const constraintOptionsList: any = ref([]);
/** 策略操作行为下拉列表 */
const actionOptionsList: any = ref([]);
onBeforeMount(() => {
if (route.query.guid) {
fullscreenLoading.value = true;
getContractTemplateDetail({ guid: route.query.guid }).then((res: any) => {
fullscreenLoading.value = false;
if (res?.code == proxy.$passCode) {
detailInfo.value = res.data || {};
baseInfoFormItems.value.forEach(item => {
item.default = detailInfo.value[item.field] || "";
});
} else {
res?.msg && proxy.$ElMessage.error(res?.msg);
}
});
}
getParamsList({ dictType: '约束运算符' }).then((res: any) => {
if (res?.code == proxy.$passCode) {
const data = res.data || [];
operatorOptionList.value = data;
} else {
res?.msg && proxy.$ElMessage.error(res?.msg);
}
})
getActionPolicyList().then((res: any) => {
if (res?.code == proxy.$passCode) {
const data = res.data || [];
actionOptionsList.value = data;
} else {
res?.msg && proxy.$ElMessage.error(res?.msg);
}
})
getConstraintPolicyList().then((res: any) => {
if (res?.code == proxy.$passCode) {
const data = res.data || [];
constraintOptionsList.value = data;
} else {
res?.msg && proxy.$ElMessage.error(res?.msg);
}
})
})
</script>
<template>
<div class="container_wrap full" v-loading="fullscreenLoading">
<div class="content_main panel">
<ContentWrap title="模板信息" expandSwicth style="margin-top: 15px" :isExpand="expandBase"
@expand="(v) => (expandBase = v)" description="">
<Form ref="baseInfoFormRef" formId="base-info-form" :itemList="baseInfoFormItems" :rules="baseInfoFormRules"
col="col3" />
</ContentWrap>
<ContentWrap title="策略信息" expandSwicth style="margin-top: 15px" :isExpand="expandInfo"
@expand="(v) => (expandInfo = v)" description="">
<StrategyTable ref="strategyTableRef" :value="detailInfo.policyRSVOS || (route.query.guid ? [] : [{
index: 1,
action: '',
children: [{ childIndex: 1 }]
}])" :operatorOptionList="operatorOptionList" :actionOptionsList="actionOptionsList"
:constraintOptionsList="constraintOptionsList"></StrategyTable>
</ContentWrap>
</div>
<div class="tool_btns">
<div class="btns">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="submit">确定</el-button>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.container_wrap {
overflow: hidden;
.content_main {
height: calc(100% - 45px);
overflow: hidden auto;
&.panel {
padding: 0 16px 16px;
}
}
}
.tool_btns {
height: 44px;
margin: 0 -8px;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid #d9d9d9;
}
:deep(.strategyTable.el-table) {
.cell {
padding: 0px 10px;
}
& td.el-table__cell {
padding: 2px 0px;
height: 36px;
}
}
</style>
<route lang="yaml">
name: contractTemplateManagement
</route>
<script lang="ts" setup name="contractTemplateManagement">
import { ref } from 'vue';
import TableTools from "@/components/Tools/table_tools.vue";
import {
getContractTemplatePageList,
copyContractTemplate,
deleteContractTemplate,
updateContractTemplateState
} from "@/api/modules/dataSmartContract"
import useDataSmartContract from "@/store/modules/dataSmartContract";
import { commonPageConfig } from '@/utils/enum';
import { useValidator } from "@/hooks/useValidator";
const router = useRouter();
const route = useRoute();
const { proxy } = getCurrentInstance() as any;
const dataSmartContractStore = useDataSmartContract();
const { required } = useValidator();
const searchItemList = ref([
{
type: "input",
label: "",
field: "templateName",
default: "",
placeholder: "合约模板名称",
maxlength: 50,
clearable: true,
},
{
type: 'select',
label: '',
field: 'bizStatus',
default: '',
placeholder: '启用状态',
options: [
{ label: '启用', value: 'Y' },
{ label: '停用', value: 'N' },
],
filterable: true,
clearable: true
}
]);
const tableFields = ref([
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "合约模板名称", field: "templateName", width: 220, },
{ label: "版本号", field: "version", width: 100 },
{ label: '启用状态', width: 96, field: 'bizStatus', type: 'switch', activeText: '启用', inactiveText: '停用', activeValue: 'Y', inactiveValue: 'N', align: 'center' },
{ label: "合约模板编号", field: "templateId", width: 190 },
{ label: "修改人", field: "updateUserName", width: 130 },
{ label: "修改时间", field: "updateTime", width: 170 },
]);
const page = ref({
...commonPageConfig,
templateName: '',
bizStatus: ''
});
const currTableData: any = ref({});
const tableInfo = ref({
id: 'contract-template-table',
rowKey: 'guid',
loading: false,
fields: tableFields.value,
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
label: "操作",
type: "btn",
width: 140,
btns: (scope) => {
let row = scope.row;
return [{
value: 'edit', label: '编辑', click: (scope) => {
router.push({
name: 'contractTemplateCreate',
query: {
guid: scope.row.guid,
name: scope.row.templateName
}
});
}
}, {
value: 'copy', label: '复制', click: copyTemplate
}, {
value: 'delete', label: '删除', click: (scope) => {
proxy.$openMessageBox("此操作将永久删除, 是否继续?", () => {
deleteContractTemplate([scope.row.guid]).then((res: any) => {
if (res?.code == proxy.$passCode) {
page.value.curr = 1;
getTableData();
proxy.$ElMessage.success('删除成功');
} else {
res?.msg && proxy.$ElMessage.error(res?.msg);
}
});
}, () => {
proxy.$ElMessage.info("已取消");
})
}
}]
}
}
});
const tableSwitchBeforeChange = (scope, field, callback) => {
const msg = `确定${scope.row[field] == 'Y' ? '停用' : '启用'}${scope.row.templateName}】?`
proxy.$openMessageBox(msg, () => {
const state = scope.row[field] == 'Y' ? 'N' : 'Y'
const result = tableSwitchChange(state, scope, field)
callback(result)
}, () => {
callback(false)
});
}
const tableSwitchChange = (val, scope, field) => {
return new Promise((resolve, reject) => {
let params = {
guid: scope.row.guid,
bizStatus: val
}
updateContractTemplateState(params).then((res: any) => {
if (res?.code == proxy.$passCode && res.data) {
getTableData();
proxy.$ElMessage({
type: "success",
message: `【${scope.row.templateName}${val == 'Y' ? '启用' : '停用'}成功`,
});
resolve(true)
} else {
res?.msg && proxy.$ElMessage.error(res?.msg)
reject(false)
}
}).catch(() => {
reject(false)
})
})
}
const copyTemplate = (scope) => {
currTableData.value = scope.row;
copyFormItems.value[0].default = scope.row.templateName + '_copy';
copyDialogInfo.value.formInfo.items = copyFormItems.value;
copyDialogInfo.value.visible = true;
}
const toSearch = (val: any, clear: boolean = false) => {
if (clear) {
searchItemList.value.map((item) => (item.default = ""));
page.value.templateName = '';
page.value.bizStatus = "";
} else {
page.value.templateName = val.templateName;
page.value.bizStatus = val.bizStatus;
}
getTableData();
};
const getTableData = () => {
tableInfo.value.loading = true
getContractTemplatePageList({
pageIndex: page.value.curr,
pageSize: page.value.limit,
templateName: page.value.templateName,
bizStatus: page.value.bizStatus
}).then((res: any) => {
tableInfo.value.loading = false
if (res?.code == proxy.$passCode) {
const data = res.data || {}
tableInfo.value.data = data.records || []
tableInfo.value.page.limit = data.pageSize
tableInfo.value.page.curr = data.pageIndex
tableInfo.value.page.rows = data.totalRows
} else {
res?.msg && proxy.$ElMessage.error(res?.msg)
}
}).catch(() => {
tableInfo.value.loading = false
})
};
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
tableInfo.value.page.curr = page.value.curr;
tableInfo.value.page.limit = page.value.limit;
getTableData();
};
const newCreate = () => {
router.push({
name: 'contractTemplateCreate'
});
}
onActivated(() => {
if (dataSmartContractStore.isRefresh) {//如果是首次加载,则不需要调用
page.value.curr = 1;
getTableData();
dataSmartContractStore.set(false);
}
})
onBeforeMount(() => {
!dataSmartContractStore.isRefresh && toSearch({})
})
/** -------------- 复制功能 ------------------- */
const copyFormItems = ref([{
type: 'input',
label: '合约模板名称',
field: 'templateName',
default: '',
block: true,
placeholder: '请输入',
maxlength: 50,
clearable: true,
required: true
}]);
const copyFormRules = ref({
templateName: [required("请填写合约模板名称")],
});
const copyDialogInfo = ref({
visible: false,
size: 480,
title: "复制合约模板",
type: 'add',
formInfo: {
id: 'copy-form',
items: copyFormItems.value,
rules: copyFormRules.value
},
btns: {
submit: (btn, info) => {
info.guid = currTableData.value.guid;
copyDialogInfo.value.submitBtnLoading = true;
copyContractTemplate(info).then((res: any) => {
copyDialogInfo.value.submitBtnLoading = false;
if (res.code == proxy.$passCode) {
page.value.curr = 1;
getTableData();
proxy.$ElMessage({
type: 'success',
message: `【${info.templateName}】复制成功`
})
copyDialogInfo.value.visible = false;
} else {
proxy.$ElMessage.error(res.msg);
}
})
},
cancel: () => {
copyDialogInfo.value.visible = false;
}
},
submitBtnLoading: false
});
</script>
<template>
<div class="container_wrap">
<div class="table_tool_wrap">
<TableTools :searchItems="searchItemList" :searchId="'settle-asset-search'" @search="toSearch" :init="false" />
<div class="tools_btns">
<el-button type="primary" @click="newCreate">新增</el-button>
</div>
</div>
<div class="table_panel_wrap">
<Table :tableInfo="tableInfo" @tablePageChange="tablePageChange"
@tableSwitchBeforeChange="tableSwitchBeforeChange" />
</div>
<!-- 复制对话框 -->
<Dialog_form :dialogConfigInfo="copyDialogInfo" />
</div>
</template>
<style lang="scss" scoped>
.container_wrap {
padding: 0px 16px;
}
</style>
\ No newline at end of file
<route lang="yaml">
name: execCntIndex
</route>
<script lang="ts" setup name="execCntIndex">
import { changeNum } from '@/utils/common'
import {
getContractStatis,
getContractMonthStatis,
getLogTableList
} from "@/api/modules/dataSmartContract";
import * as echarts from 'echarts';
import { commonPageConfig } from '@/utils/enum';
const { proxy } = getCurrentInstance() as any;
const detailInfo: any = ref({});
const logTableInfo: any = ref({
id: "plan-detail-table",
loading: false,
// height: 'auto',
// minPanelHeight: '60px',
// minHeight: '60px',
// maxHeight: '250px',
fields: [
{ label: "序号", type: "index", width: 56, align: "center", fixed: true },
{ label: "合约标识", field: "contractId", width: 355 },
{ label: "合约名称", field: "contractName", width: 140 },
{ label: "执行策略id", field: "strategyId", width: 260 },
{ label: "执行时间", field: "operationTime", width: 170 },
{ label: "执行节点标识", field: "executionEntityId", width: 180 },
{ label: "上报时间", field: "operationTime", width: 170 },
{ label: "异常类型", field: "executionResult", width: 120 },
],
data: [],
page: {
type: "normal",
rows: 0,
...commonPageConfig,
},
actionInfo: {
show: false
}
});
const pageChange = (info) => {
logTableInfo.value.page.curr = Number(info.curr);
logTableInfo.value.page.limit = Number(info.limit);
getLogTableListData(true);
};
const getLogTableListData = (isPage = false) => {
isPage && (logTableInfo.value.loading = true);
return getLogTableList({
pageIndex: logTableInfo.value.page.curr,
pageSize: logTableInfo.value.page.limit,
}).then((res: any) => {
logTableInfo.value.loading = false;
if (res?.code == proxy.$passCode) {
const data = res.data || {};
logTableInfo.value.data = data.records || []
logTableInfo.value.page.limit = data.pageSize
logTableInfo.value.page.curr = data.pageIndex
logTableInfo.value.page.rows = data.totalRows
} else {
res?.msg && proxy.$ElMessage.error(res?.msg)
}
})
}
let barChart: any = null;
const barChartData: any = ref([]);
onMounted(() => {
barChart = echarts.init(document.getElementById('bar'));
setBarChartOption(barChart);
})
watch(() => barChartData.value, (val) => {
setBarChartOption(barChart);
}, {
deep: true
})
/** 设置柱形图option,默认只 展示12次的 */
const setBarChartOption = (barChart) => {
return new Promise((resolve, reject) => {
if (!barChartData.value || !Object.keys(barChartData.value).length) {
let option1 = {
title: [
{
text: "",
left: "30px",
top: "30px",
},
{
text: "暂无数据",
left: "center",
top: "center",
textStyle: {
fontFamily: 'SimSun',
fontStyle: "normal",
fontWeight: "400",
fontSize: 18,
color: '#999'
},
},
],
};
barChart.setOption(option1, true);
window.addEventListener("resize", () => {
barChart.resize();
});
return;
}
let getLast12Months = () => {
const months: any = [];
const currentDate = new Date();
for (let i = 11; i >= 0; i--) {
const targetDate = new Date(currentDate);
targetDate.setMonth(targetDate.getMonth() - i);
const year = targetDate.getFullYear();
const month = String(targetDate.getMonth() + 1).padStart(2, '0');
months.push(`${year}-${month}`);
}
return months;
}
// 使用示例
const last12Months = getLast12Months();
let itemXAxisData: any = last12Months;
let itemYAxisData: any = last12Months.map(v => {
return barChartData.value[v] || 0;
});
let option = {
textStyle: {
fontFamily: 'SimSun'
},
color: ['#5B8FF9', '#FF4E00', '#867EEC', '#FDBC3E', '#F48A64', '#276FF5', '#46D0B5'],
title: {
show: false,
left: '30px',
top: '30px',
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
},
textStyle: {
align: 'left'
},
},
legend: {
show: false,
right: 0,
textStyle: {
fontSize: 14
},
},
grid: {
left: 30,
right: 60,
bottom: 5,
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
nameTextStyle: {
color: '#000000'
},
axisLabel: {
interval: 'auto',
textStyle: {
color: '#000000'
},
},
axisTick: {
show: false,
},
axisLine: {
lineStyle: {
color: '#d9d9d9'
}
},
data: itemXAxisData
},
yAxis: {
type: 'value',
name: '',
min: 0,
minInterval: 1,
nameTextStyle: {
color: '#000000'
},
axisLabel: {
textStyle: {
color: '#000000'
}
},
axisLine: {
//y轴
show: false
}
},
series: [{
name: '已签署合约数',
type: 'line',
data: itemYAxisData,
label: {
show: false,
},
tooltip: {
valueFormatter: function (value) {
return changeNum(value, 0);
}
},
yAxisIndex: 0
}]
};
option && barChart.setOption(option, true);
barChart.on('finished', () => {
resolve(true);
});
window.addEventListener('resize', () => {
barChart.resize();
});
});
}
const fullscreenloading = ref(false);
onBeforeMount(() => {
fullscreenloading.value = true;
let ps1 = getContractStatis().then((res: any) => {
if (res?.code == proxy.$passCode) {
detailInfo.value = res.data || {};
} else {
res?.msg && proxy.$ElMessage.error(res?.msg)
}
})
let ps2 = getContractMonthStatis().then((res: any) => {
if (res?.code == proxy.$passCode) {
barChartData.value = res.data || {};
} else {
res?.msg && proxy.$ElMessage.error(res?.msg)
}
})
let ps3 = getLogTableListData();
Promise.all([ps1, ps2, ps3]).then(() => {
fullscreenloading.value = false;
}).catch(() => {
fullscreenloading.value = false;
})
})
</script>
<template>
<div class="content-main" v-loading="fullscreenloading">
<div class="title">合约备案执行统计</div>
<div class="kpi-content">
<div class="border-content">
<span class="text">备案合约数</span>
<span class="number num-color">{{ detailInfo.registerNum != null ? changeNum(detailInfo.registerNum ?? 0) : '--'
}}<span class="unit" v-show="detailInfo.registerNum != null"></span></span>
</div>
<div class="border-content ml16">
<span class="text">备案策略数</span>
<span class="number num-color">{{ detailInfo.registerPolicyNum != null ? changeNum(detailInfo.registerPolicyNum
?? 0) : '--'
}}<span class="unit" v-show="detailInfo.registerPolicyNum != null"></span></span>
</div>
<div class="border-content ml16">
<span class="text">策略执行数</span>
<span class="number num-color">{{ detailInfo.registerPolicyExecutionNum != null ?
(changeNum(detailInfo.registerPolicyExecutionNum ?? 0)) :
'--'
}}<span class="unit" v-show="detailInfo.registerPolicyExecutionNum != null"></span></span>
</div>
<div class="border-content ml16">
<span class="text">签署合约主体数</span>
<span class="number num-color">{{ detailInfo.registerSignatureNum != null ?
changeNum(detailInfo.registerSignatureNum ?? 0) : '--'
}}<span class="unit" v-show="detailInfo.registerSignatureNum != null"></span></span>
</div>
<div class="border-content ml16">
<span class="text">策略执行节点数</span>
<span class="number num-color">{{ detailInfo.registerExecutionNodeNum != null ?
changeNum(detailInfo.registerExecutionNodeNum ?? 0) : '--'
}}<span class="unit" v-show="detailInfo.registerExecutionNodeNum != null"></span></span>
</div>
</div>
<div class="title">合约履行异常预警记录</div>
<Table class="table-h" :tableInfo="logTableInfo" @tablePageChange="pageChange" />
<div class="title">近12个月备案合约趋势</div>
<div class="content-chart-bar" id="bar">
</div>
</div>
</template>
<style lang="scss" scoped>
.content-main {
height: 100%;
overflow-y: auto;
overflow-x: hidden;
padding: 0px 16px 16px;
}
.title {
line-height: 24px;
font-size: 16px;
color: #212121;
font-weight: 600;
margin-top: 12px;
margin-bottom: 8px;
}
.kpi-content {
display: flex;
flex-direction: row;
}
.border-content {
height: 76px;
display: flex;
flex-direction: column;
align-items: flex-start;
padding-left: 16px;
justify-content: center;
border: 1px solid #d9d9d9;
//width: 160px;
flex: 1;
min-width: 150px;
border-radius: 2px;
.number {
line-height: 30px;
font-weight: 700;
font-size: 20px;
.unit {
font-size: 18px;
font-weight: 400;
}
}
.num-color {
color: #212121;
}
.text {
font-size: 14px;
color: #666666;
display: flex;
.el-icon {
color: #b2b2b2;
}
}
}
.ml16 {
margin-left: 16px;
}
.content-chart-bar {
height: 300px;
border: 1px solid #d9d9d9;
padding: 8px;
}
.table-h {
height: 300px !important;
}
</style>
\ No newline at end of file
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!