diff --git a/package.json b/package.json index 1c295de00..89477d4c5 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "animate.css": "^4.1.1", "axios": "^1.6.8", "benz-amr-recorder": "^1.1.5", - "bpmn-js-token-simulation": "^0.10.0", + "bpmn-js-token-simulation": "^0.36.0", "camunda-bpmn-moddle": "^7.0.1", "cropperjs": "^1.6.1", "crypto-js": "^4.2.0", @@ -47,7 +47,7 @@ "driver.js": "^1.3.1", "echarts": "^5.5.0", "echarts-wordcloud": "^2.1.0", - "element-plus": "2.8.4", + "element-plus": "2.9.1", "fast-xml-parser": "^4.3.2", "highlight.js": "^11.9.0", "jsencrypt": "^3.3.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 226b5c237..ec016eb17 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,8 +45,8 @@ dependencies: specifier: ^1.1.5 version: 1.1.5 bpmn-js-token-simulation: - specifier: ^0.10.0 - version: 0.10.0 + specifier: ^0.36.0 + version: 0.36.0 camunda-bpmn-moddle: specifier: ^7.0.1 version: 7.0.1 @@ -72,8 +72,8 @@ dependencies: specifier: ^2.1.0 version: 2.1.0(echarts@5.5.1) element-plus: - specifier: 2.8.4 - version: 2.8.4(vue@3.5.12) + specifier: 2.9.1 + version: 2.9.1(vue@3.5.12) fast-xml-parser: specifier: ^4.3.2 version: 4.5.0 @@ -149,6 +149,9 @@ dependencies: vue-types: specifier: ^5.1.1 version: 5.1.3(vue@3.5.12) + vue3-signature: + specifier: ^0.2.4 + version: 0.2.4(vue@3.5.12) vuedraggable: specifier: ^4.1.0 version: 4.1.0(vue@3.5.12) @@ -2122,7 +2125,7 @@ packages: '@form-create/element-ui': 3.2.14(vue@3.5.12) '@form-create/utils': 3.2.14 codemirror: 6.65.7 - element-plus: 2.8.4(vue@3.5.12) + element-plus: 2.9.1(vue@3.5.12) vue: 3.5.12(typescript@5.3.3) vuedraggable: 4.1.0(vue@3.5.12) transitivePeerDependencies: @@ -4581,12 +4584,14 @@ packages: min-dom: 4.2.1 dev: true - /bpmn-js-token-simulation@0.10.0: - resolution: {integrity: sha512-QuZQ/KVXKt9Vl+XENyOBoTW2Aw+uKjuBlKdCJL6El7AyM7DkJ5bZkSYURshId1SkBDdYg2mJ1flSmsrhGuSfwg==, tarball: https://registry.npmmirror.com/bpmn-js-token-simulation/-/bpmn-js-token-simulation-0.10.0.tgz} + /bpmn-js-token-simulation@0.36.0: + resolution: {integrity: sha512-vz+RHlbZCev/6dzk6FhJRz8M0aZ1GL7Xrza0ecWqeg4tHbgPozgyOm3tXTz75XdtOwRVVBzmCjcciXQX7A55wQ==, tarball: https://registry.npmmirror.com/bpmn-js-token-simulation/-/bpmn-js-token-simulation-0.36.0.tgz} + engines: {node: '>= 16'} dependencies: - min-dash: 3.8.1 - min-dom: 0.2.0 - svg.js: 2.7.1 + inherits-browser: 0.1.0 + min-dash: 4.2.2 + min-dom: 4.2.1 + randomcolor: 0.6.2 dev: false /bpmn-js@17.11.1: @@ -4927,51 +4932,13 @@ packages: dot-prop: 5.3.0 dev: true - /component-classes@1.2.6: - resolution: {integrity: sha512-hPFGULxdwugu1QWW3SvVOCUHLzO34+a2J6Wqy0c5ASQkfi9/8nZcBB0ZohaEbXOQlCflMAEMmEWk7u7BVs4koA==, tarball: https://registry.npmmirror.com/component-classes/-/component-classes-1.2.6.tgz} - dependencies: - component-indexof: 0.0.3 - dev: false - - /component-closest@0.1.4: - resolution: {integrity: sha512-NF9hMj6JKGM5sb6wP/dg7GdJOttaIH9PcTsUNdWcrvu7Kw/5R5swQAFpgaYEHlARrNMyn4Wf7O1PlRej+pt76Q==, tarball: https://registry.npmmirror.com/component-closest/-/component-closest-0.1.4.tgz} - dependencies: - component-matches-selector: 0.1.7 - dev: false - - /component-delegate@0.2.4: - resolution: {integrity: sha512-OlpcB/6Fi+kXQPh/TfXnSvvmrU04ghz7vcJh/jgLF0Ni+I+E3WGlKJQbBGDa5X+kVUG8WxOgjP+8iWbz902fPg==, tarball: https://registry.npmmirror.com/component-delegate/-/component-delegate-0.2.4.tgz} - dependencies: - component-closest: 0.1.4 - component-event: 0.1.4 - dev: false - /component-emitter@1.3.1: resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==, tarball: https://registry.npmmirror.com/component-emitter/-/component-emitter-1.3.1.tgz} dev: true - /component-event@0.1.4: - resolution: {integrity: sha512-GMwOG8MnUHP1l8DZx1ztFO0SJTFnIzZnBDkXAj8RM2ntV2A6ALlDxgbMY1Fvxlg6WPQ+5IM/a6vg4PEYbjg/Rw==, tarball: https://registry.npmmirror.com/component-event/-/component-event-0.1.4.tgz} - dev: false - /component-event@0.2.1: resolution: {integrity: sha512-wGA++isMqiDq1jPYeyv2as/Bt/u+3iLW0rEa+8NQ82jAv3TgqMiCM+B2SaBdn2DfLilLjjq736YcezihRYhfxw==, tarball: https://registry.npmmirror.com/component-event/-/component-event-0.2.1.tgz} - /component-indexof@0.0.3: - resolution: {integrity: sha512-puDQKvx/64HZXb4hBwIcvQLaLgux8o1CbWl39s41hrIIZDl1lJiD5jc22gj3RBeGK0ovxALDYpIbyjqDUUl0rw==, tarball: https://registry.npmmirror.com/component-indexof/-/component-indexof-0.0.3.tgz} - dev: false - - /component-matches-selector@0.1.7: - resolution: {integrity: sha512-Yb2+pVBvrqkQVpPaDBF0DYXRreBveXJNrpJs9FnFu8PF6/5IIcz5oDZqiH9nB5hbD2/TmFVN5ZCxBzqu7yFFYQ==, tarball: https://registry.npmmirror.com/component-matches-selector/-/component-matches-selector-0.1.7.tgz} - dependencies: - component-query: 0.0.3 - global-object: 1.0.0 - dev: false - - /component-query@0.0.3: - resolution: {integrity: sha512-VgebQseT1hz1Ps7vVp2uaSg+N/gsI5ts3AZUSnN6GMA2M82JH7o+qYifWhmVE/e8w/H48SJuA3nA9uX8zRe95Q==, tarball: https://registry.npmmirror.com/component-query/-/component-query-0.0.3.tgz} - dev: false - /compute-scroll-into-view@1.0.20: resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==, tarball: https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz} dev: false @@ -5521,6 +5488,10 @@ packages: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==, tarball: https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz} dev: true + /default-passive-events@2.0.0: + resolution: {integrity: sha512-eMtt76GpDVngZQ3ocgvRcNCklUMwID1PaNbCNxfpDXuiOXttSh0HzBbda1HU9SIUsDc02vb7g9+3I5tlqe/qMQ==, tarball: https://registry.npmmirror.com/default-passive-events/-/default-passive-events-2.0.0.tgz} + dev: false + /define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==, tarball: https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.4.tgz} engines: {node: '>= 0.4'} @@ -5795,8 +5766,8 @@ packages: resolution: {integrity: sha512-nz88NNBsD7kQSAGGJyp8hS6xSPtWwqNogA0mjtc2nUYeEf3nURK9qpV18TuBdDmEDgVWotS8Wkzf+V52dSQ/LQ==, tarball: https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.67.tgz} dev: true - /element-plus@2.8.4(vue@3.5.12): - resolution: {integrity: sha512-ZlVAdUOoJliv4kW3ntWnnSHMT+u/Os7mXJjk2xzOlqNeHaI2/ozlF+R58ZCEak8ZnDi6+5A2viWEYRsq64IuiA==, tarball: https://registry.npmmirror.com/element-plus/-/element-plus-2.8.4.tgz} + /element-plus@2.9.1(vue@3.5.12): + resolution: {integrity: sha512-9Agqf/jt4Ugk7EZ6C5LME71sgkvauPCsnvJN12Xid2XVobjufxMGpRE4L7pS4luJMOmFAH3J0NgYEGZT5r+NDg==, tarball: https://registry.npmmirror.com/element-plus/-/element-plus-2.9.1.tgz} peerDependencies: vue: ^3.2.0 dependencies: @@ -6674,10 +6645,6 @@ packages: global-prefix: 3.0.0 dev: true - /global-object@1.0.0: - resolution: {integrity: sha512-mSPSkY6UsHv6hgW0V2dfWBWTS8TnPnLx3ECVNoWp6rBI2Bg66VYoqGoTFlH/l7XhAZ/l+StYlntXlt87BEeCcg==, tarball: https://registry.npmmirror.com/global-object/-/global-object-1.0.0.tgz} - dev: false - /global-prefix@3.0.0: resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==, tarball: https://registry.npmmirror.com/global-prefix/-/global-prefix-3.0.0.tgz} engines: {node: '>=6'} @@ -7899,10 +7866,6 @@ packages: engines: {node: '>=18'} dev: true - /min-dash@3.8.1: - resolution: {integrity: sha512-evumdlmIlg9mbRVPbC4F5FuRhNmcMS5pvuBUbqb1G9v09Ro0ImPEgz5n3khir83lFok1inKqVDjnKEg3GpDxQg==, tarball: https://registry.npmmirror.com/min-dash/-/min-dash-3.8.1.tgz} - dev: false - /min-dash@4.2.2: resolution: {integrity: sha512-qbhSYUxk6mBaF096B3JOQSumXbKWHenmT97cSpdNzgkWwGjhjhE/KZODCoDNhI2I4C9Cb6R/Q13S4BYkUSXoXQ==, tarball: https://registry.npmmirror.com/min-dash/-/min-dash-4.2.2.tgz} @@ -7912,18 +7875,6 @@ packages: dom-walk: 0.1.2 dev: false - /min-dom@0.2.0: - resolution: {integrity: sha512-VmxugbnAcVZGqvepjhOA4d4apmrpX8mMaRS+/jo0dI5Yorzrr4Ru9zc9KVALlY/+XakVCb8iQ+PYXljihQcsNw==, tarball: https://registry.npmmirror.com/min-dom/-/min-dom-0.2.0.tgz} - dependencies: - component-classes: 1.2.6 - component-closest: 0.1.4 - component-delegate: 0.2.4 - component-event: 0.1.4 - component-matches-selector: 0.1.7 - component-query: 0.0.3 - domify: 1.4.2 - dev: false - /min-dom@4.2.1: resolution: {integrity: sha512-TMoL8SEEIhUWYgkj7XMSgxmwSyGI+4fP2KFFGnN3FbHfbGHVdsLYSz8LoIsgPhz4dWRmLvxWWSMgzZMJW5sZuA==, tarball: https://registry.npmmirror.com/min-dom/-/min-dom-4.2.1.tgz} dependencies: @@ -8714,6 +8665,10 @@ packages: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, tarball: https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz} dev: true + /randomcolor@0.6.2: + resolution: {integrity: sha512-Mn6TbyYpFgwFuQ8KJKqf3bqqY9O1y37/0jgSK/61PUxV4QfIMv0+K2ioq8DfOjkBslcjwSzRfIDEXfzA9aCx7A==, tarball: https://registry.npmmirror.com/randomcolor/-/randomcolor-0.6.2.tgz} + dev: false + /rd@2.0.1: resolution: {integrity: sha512-/XdKU4UazUZTXFmI0dpABt8jSXPWcEyaGdk340KdHnsEOdkTctlX23aAK7ChQDn39YGNlAJr1M5uvaKt4QnpNw==, tarball: https://registry.npmmirror.com/rd/-/rd-2.0.1.tgz} dependencies: @@ -9128,6 +9083,10 @@ packages: engines: {node: '>=14'} dev: true + /signature_pad@3.0.0-beta.4: + resolution: {integrity: sha512-cOf2NhVuTiuNqe2X/ycEmizvCDXk0DoemhsEpnkcGnA4kS5iJYTCqZ9As7tFBbsch45Q1EdX61833+6sjJ8rrw==, tarball: https://registry.npmmirror.com/signature_pad/-/signature_pad-3.0.0-beta.4.tgz} + dev: false + /sirv@2.0.4: resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==, tarball: https://registry.npmmirror.com/sirv/-/sirv-2.0.4.tgz} engines: {node: '>= 10'} @@ -9561,10 +9520,6 @@ packages: resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==, tarball: https://registry.npmmirror.com/svg-tags/-/svg-tags-1.0.0.tgz} dev: true - /svg.js@2.7.1: - resolution: {integrity: sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==, tarball: https://registry.npmmirror.com/svg.js/-/svg.js-2.7.1.tgz} - dev: false - /svgo@2.8.0: resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==, tarball: https://registry.npmmirror.com/svgo/-/svgo-2.8.0.tgz} engines: {node: '>=10.13.0'} @@ -10324,6 +10279,16 @@ packages: vue: 3.5.12(typescript@5.3.3) dev: false + /vue3-signature@0.2.4(vue@3.5.12): + resolution: {integrity: sha512-XFwwFVK9OG3F085pKIq2SlNVqx32WdFH+TXbGEWc5FfEKpx8oMmZuAwZZ50K/pH2FgmJSE8IRwU9DDhrLpd6iA==, tarball: https://registry.npmmirror.com/vue3-signature/-/vue3-signature-0.2.4.tgz} + peerDependencies: + vue: ^3.2.0 + dependencies: + default-passive-events: 2.0.0 + signature_pad: 3.0.0-beta.4 + vue: 3.5.12(typescript@5.3.3) + dev: false + /vue@3.5.12(typescript@5.3.3): resolution: {integrity: sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==, tarball: https://registry.npmmirror.com/vue/-/vue-3.5.12.tgz} peerDependencies: diff --git a/src/api/bpm/model/index.ts b/src/api/bpm/model/index.ts index 0c499dbad..63b6af6ad 100644 --- a/src/api/bpm/model/index.ts +++ b/src/api/bpm/model/index.ts @@ -72,3 +72,7 @@ export const deleteModel = async (id: number) => { export const deployModel = async (id: number) => { return await request.post({ url: '/bpm/model/deploy?id=' + id }) } + +export const cleanModel = async (id: number) => { + return await request.delete({ url: '/bpm/model/clean?id=' + id }) +} diff --git a/src/api/bpm/processInstance/index.ts b/src/api/bpm/processInstance/index.ts index f97270f93..9a99a91e2 100644 --- a/src/api/bpm/processInstance/index.ts +++ b/src/api/bpm/processInstance/index.ts @@ -36,6 +36,7 @@ export type ApprovalTaskInfo = { assigneeUser: User status: number reason: string + signPicUrl: string } // 审批节点信息 @@ -89,7 +90,7 @@ export const getProcessInstanceCopyPage = async (params: any) => { // 获取审批详情 export const getApprovalDetail = async (params: any) => { - return await request.get({ url: 'bpm/process-instance/get-approval-detail' , params }) + return await request.get({ url: 'bpm/process-instance/get-approval-detail', params }) } // 获取表单字段权限 diff --git a/src/api/login/index.ts b/src/api/login/index.ts index 33fddcabd..8c69d9bc9 100644 --- a/src/api/login/index.ts +++ b/src/api/login/index.ts @@ -22,11 +22,6 @@ export const register = (data: RegisterVO) => { return request.post({ url: '/system/auth/register', data }) } -// 刷新访问令牌 -export const refreshToken = () => { - return request.post({ url: '/system/auth/refresh-token?refreshToken=' + getRefreshToken() }) -} - // 使用租户名,获得租户编号 export const getTenantIdByName = (name: string) => { return request.get({ url: '/system/tenant/get-id-by-name?name=' + name }) @@ -76,12 +71,17 @@ export const socialAuthRedirect = (type: number, redirectUri: string) => { }) } // 获取验证图片以及 token -export const getCode = (data) => { +export const getCode = (data: any) => { debugger return request.postOriginal({ url: 'system/captcha/get', data }) } // 滑动或者点选验证 -export const reqCheck = (data) => { +export const reqCheck = (data: any) => { return request.postOriginal({ url: 'system/captcha/check', data }) } + +// 通过短信重置密码 +export const smsResetPassword = (data: any) => { + return request.post({ url: '/system/auth/sms-reset-password', data }) +} diff --git a/src/components/Echart/src/Echart.vue b/src/components/Echart/src/Echart.vue index fd3342dd0..bf22b864e 100644 --- a/src/components/Echart/src/Echart.vue +++ b/src/components/Echart/src/Echart.vue @@ -9,6 +9,10 @@ import { useAppStore } from '@/store/modules/app' import { isString } from '@/utils/is' import { useDesign } from '@/hooks/web/useDesign' +import 'echarts/lib/component/markPoint' +import 'echarts/lib/component/markLine' +import 'echarts/lib/component/markArea' + defineOptions({ name: 'EChart' }) const { getPrefixCls, variables } = useDesign() diff --git a/src/components/RouterSearch/index.vue b/src/components/RouterSearch/index.vue index ed2a08cc2..42a41744d 100644 --- a/src/components/RouterSearch/index.vue +++ b/src/components/RouterSearch/index.vue @@ -79,9 +79,14 @@ function remoteMethod(data) { function handleChange(path) { router.push({ path }) + hiddenSearch() hiddenTopSearch() } +function hiddenSearch() { + showSearch.value = false +} + function hiddenTopSearch() { showTopSearch.value = false } diff --git a/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue b/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue index c94998d53..e575c36cc 100644 --- a/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue +++ b/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue @@ -46,7 +46,7 @@
延迟器
-
+
@@ -67,12 +67,13 @@ import { ApproveMethodType, AssignEmptyHandlerType, AssignStartUserHandlerType, + ConditionType, NODE_DEFAULT_NAME, NodeType, RejectHandlerType, SimpleFlowNode } from './consts' -import { generateUUID } from '@/utils' +import {generateUUID} from '@/utils' defineOptions({ name: 'NodeHandler' @@ -164,9 +165,24 @@ const addNode = (type: number) => { type: NodeType.CONDITION_NODE, childNode: undefined, conditionSetting: { - defaultFlow: false - }, - + defaultFlow: false, + conditionType: ConditionType.RULE, + conditionGroups: { + and: true, + conditions: [ + { + and: true, + rules: [ + { + opCode: '==', + leftSide: '', + rightSide: '' + } + ] + } + ] + } + } }, { id: 'Flow_' + generateUUID(), @@ -221,9 +237,24 @@ const addNode = (type: number) => { type: NodeType.CONDITION_NODE, childNode: undefined, conditionSetting: { - defaultFlow: false + defaultFlow: false, + conditionType: ConditionType.RULE, + conditionGroups: { + and: true, + conditions: [ + { + and: true, + rules: [ + { + opCode: '==', + leftSide: '', + rightSide: '' + } + ] + } + ] + } } - }, { id: 'Flow_' + generateUUID(), @@ -249,14 +280,13 @@ const addNode = (type: number) => { } emits('update:childNode', data) } - if (type === NodeType.ROUTE_BRANCH_NODE) { + if (type === NodeType.ROUTER_BRANCH_NODE) { const data: SimpleFlowNode = { id: 'GateWay_' + generateUUID(), - name: NODE_DEFAULT_NAME.get(NodeType.ROUTE_BRANCH_NODE) as string, + name: NODE_DEFAULT_NAME.get(NodeType.ROUTER_BRANCH_NODE) as string, showText: '', - type: NodeType.ROUTE_BRANCH_NODE, - childNode: props.childNode, - defaultFlowId: 'Flow_' + generateUUID() + type: NodeType.ROUTER_BRANCH_NODE, + childNode: props.childNode } emits('update:childNode', data) } diff --git a/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue b/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue index 4c87d5b07..26ef13dd5 100644 --- a/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue +++ b/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue @@ -45,8 +45,8 @@ @update:flow-node="handleModelValueUpdate" /> - @@ -73,7 +73,7 @@ import ExclusiveNode from './nodes/ExclusiveNode.vue' import ParallelNode from './nodes/ParallelNode.vue' import InclusiveNode from './nodes/InclusiveNode.vue' import DelayTimerNode from './nodes/DelayTimerNode.vue' -import RouteNode from './nodes/RouteNode.vue' +import RouterNode from './nodes/RouterNode.vue' import { SimpleFlowNode, NodeType } from './consts' import { useWatchNode } from './node' defineOptions({ diff --git a/src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue b/src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue index a6c7a37ed..70eade33f 100644 --- a/src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue +++ b/src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue @@ -40,7 +40,7 @@ defineOptions({ name: 'SimpleProcessDesigner' }) -const emits = defineEmits(['success', 'init-finished']) // 保存成功事件 +const emits = defineEmits(['success']) // 保存成功事件 const props = defineProps({ modelId: { @@ -59,13 +59,10 @@ const props = defineProps({ startUserIds: { type: Array, required: false - }, - value: { - type: [String, Object], - required: false } }) +const processData = inject('processData') as Ref const loading = ref(false) const formFields = ref([]) const formType = ref(20) @@ -76,9 +73,6 @@ const deptOptions = ref([]) // 部门列表 const deptTreeOptions = ref() const userGroupOptions = ref([]) // 用户组列表 -// 添加当前值的引用 -const currentValue = ref() - provide('formFields', formFields) provide('formType', formType) provide('roleList', roleOptions) @@ -88,7 +82,8 @@ provide('deptList', deptOptions) provide('userGroupList', userGroupOptions) provide('deptTree', deptTreeOptions) provide('startUserIds', props.startUserIds) - +provide('tasks', []) +provide('processInstance', {}) const message = useMessage() // 国际化 const processNodeTree = ref() provide('processNodeTree', processNodeTree) @@ -113,70 +108,13 @@ const updateModel = () => { } } -// 加载流程数据 -const loadProcessData = async (data: any) => { - try { - if (data) { - const parsedData = typeof data === 'string' ? JSON.parse(data) : data - processNodeTree.value = parsedData - currentValue.value = parsedData - // 确保数据加载后刷新视图 - await nextTick() - if (simpleProcessModelRef.value?.refresh) { - await simpleProcessModelRef.value.refresh() - } - } - } catch (error) { - console.error('加载流程数据失败:', error) - } -} - -// 监听属性变化 -watch( - () => props.value, - async (newValue, oldValue) => { - if (newValue && newValue !== oldValue) { - await loadProcessData(newValue) - } - }, - { immediate: true, deep: true } -) - -// 监听流程节点树变化,自动保存 -watch( - () => processNodeTree.value, - async (newValue, oldValue) => { - if (newValue && oldValue && JSON.stringify(newValue) !== JSON.stringify(oldValue)) { - await saveSimpleFlowModel(newValue) - } - }, - { deep: true } -) - const saveSimpleFlowModel = async (simpleModelNode: SimpleFlowNode) => { if (!simpleModelNode) { return } - // 校验节点 - errorNodes = [] - validateNode(simpleModelNode, errorNodes) - if (errorNodes.length > 0) { - errorDialogVisible.value = true - return - } - try { - if (props.modelId) { - // 编辑模式 - const data = { - id: props.modelId, - simpleModel: simpleModelNode - } - await updateBpmSimpleModel(data) - } - // 无论是编辑还是新建模式,都更新当前值并触发事件 - currentValue.value = simpleModelNode + processData.value = simpleModelNode emits('success', simpleModelNode) } catch (error) { console.error('保存失败:', error) @@ -247,61 +185,18 @@ onMounted(async () => { deptTreeOptions.value = handleTree(deptOptions.value as DeptApi.DeptVO[], 'id') // 获取用户组列表 userGroupOptions.value = await UserGroupApi.getUserGroupSimpleList() - // 加载流程数据 - if (props.modelId) { - // 获取 SIMPLE 设计器模型 - const result = await getBpmSimpleModel(props.modelId) - if (result) { - await loadProcessData(result) - } else { - updateModel() - } - } else if (props.value) { - await loadProcessData(props.value) + if (processData.value) { + processNodeTree.value = processData?.value } else { updateModel() } } finally { loading.value = false - emits('init-finished') } }) const simpleProcessModelRef = ref() -/** 获取当前流程数据 */ -const getCurrentFlowData = async () => { - try { - if (simpleProcessModelRef.value) { - const data = await simpleProcessModelRef.value.getCurrentFlowData() - if (data) { - currentValue.value = data - return data - } - } - return currentValue.value - } catch (error) { - console.error('获取流程数据失败:', error) - return currentValue.value - } -} - -// 刷新方法 -const refresh = async () => { - try { - if (currentValue.value) { - await loadProcessData(currentValue.value) - } - } catch (error) { - console.error('刷新失败:', error) - } -} - -defineExpose({ - getCurrentFlowData, - updateModel, - loadProcessData, - refresh -}) +defineExpose({}) diff --git a/src/components/SimpleProcessDesignerV2/src/SimpleProcessModel.vue b/src/components/SimpleProcessDesignerV2/src/SimpleProcessModel.vue index ccd1f10d2..8f0a2916b 100644 --- a/src/components/SimpleProcessDesignerV2/src/SimpleProcessModel.vue +++ b/src/components/SimpleProcessDesignerV2/src/SimpleProcessModel.vue @@ -3,6 +3,22 @@
+ + 导出 + + + 导入 + + + {{ scaleValue }}% @@ -34,6 +50,8 @@ import ProcessNodeTree from './ProcessNodeTree.vue' import { SimpleFlowNode, NodeType, NODE_DEFAULT_TEXT } from './consts' import { useWatchNode } from './node' import { ZoomOut, ZoomIn, ScaleToOriginal } from '@element-plus/icons-vue' +import { isString } from '@/utils/is' +import download from '@/utils/download' defineOptions({ name: 'SimpleProcessModel' @@ -52,7 +70,7 @@ const props = defineProps({ }) const emits = defineEmits<{ - 'save': [node: SimpleFlowNode | undefined] + save: [node: SimpleFlowNode | undefined] }>() const processNodeTree = useWatchNode(props) @@ -85,6 +103,16 @@ const processReZoom = () => { const errorDialogVisible = ref(false) let errorNodes: SimpleFlowNode[] = [] +const saveSimpleFlowModel = async () => { + errorNodes = [] + validateNode(processNodeTree.value, errorNodes) + if (errorNodes.length > 0) { + errorDialogVisible.value = true + return + } + emits('save', processNodeTree.value) +} + // 校验节点设置。 暂时以 showText 为空 未节点错误配置 const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNode[]) => { if (node) { @@ -143,6 +171,28 @@ const getCurrentFlowData = async () => { defineExpose({ getCurrentFlowData }) + +/** 导出 JSON */ +const exportJson = () => { + download.json(new Blob([JSON.stringify(processNodeTree.value)]), 'model.json') +} + +/** 导入 JSON */ +const refFile = ref() +const importJson = () => { + refFile.value.click() +} +const importLocalFile = () => { + const file = refFile.value.files[0] + const reader = new FileReader() + reader.readAsText(file) + reader.onload = function () { + if (isString(this.result)) { + processNodeTree.value = JSON.parse(this.result) + emits('save', processNodeTree.value) + } + } +} diff --git a/src/components/SimpleProcessDesignerV2/src/consts.ts b/src/components/SimpleProcessDesignerV2/src/consts.ts index ffc37b800..089a63924 100644 --- a/src/components/SimpleProcessDesignerV2/src/consts.ts +++ b/src/components/SimpleProcessDesignerV2/src/consts.ts @@ -48,7 +48,7 @@ export enum NodeType { /** * 路由分支节点 */ - ROUTE_BRANCH_NODE = 54 + ROUTER_BRANCH_NODE = 54 } export enum NodeId { @@ -110,10 +110,12 @@ export interface SimpleFlowNode { // 延迟设置 delaySetting?: DelaySetting // 路由分支 - routerGroups?: RouteCondition[] + routerGroups?: RouterCondition[] defaultFlowId?: string // 签名 signEnable?: boolean + // 审批意见 + reasonRequire?: boolean } // 候选人策略枚举 ( 用于审批节点。抄送节点 ) export enum CandidateStrategy { @@ -447,8 +449,6 @@ export enum OperationButtonType { * 条件规则结构定义 */ export type ConditionRule = { - type: number - opName: string opCode: string leftSide: string rightSide: string @@ -479,7 +479,7 @@ NODE_DEFAULT_TEXT.set(NodeType.COPY_TASK_NODE, '请配置抄送人') NODE_DEFAULT_TEXT.set(NodeType.CONDITION_NODE, '请设置条件') NODE_DEFAULT_TEXT.set(NodeType.START_USER_NODE, '请设置发起人') NODE_DEFAULT_TEXT.set(NodeType.DELAY_TIMER_NODE, '请设置延迟器') -NODE_DEFAULT_TEXT.set(NodeType.ROUTE_BRANCH_NODE, '请设置路由节点') +NODE_DEFAULT_TEXT.set(NodeType.ROUTER_BRANCH_NODE, '请设置路由节点') export const NODE_DEFAULT_NAME = new Map() NODE_DEFAULT_NAME.set(NodeType.USER_TASK_NODE, '审批人') @@ -487,7 +487,7 @@ NODE_DEFAULT_NAME.set(NodeType.COPY_TASK_NODE, '抄送人') NODE_DEFAULT_NAME.set(NodeType.CONDITION_NODE, '条件') NODE_DEFAULT_NAME.set(NodeType.START_USER_NODE, '发起人') NODE_DEFAULT_NAME.set(NodeType.DELAY_TIMER_NODE, '延迟器') -NODE_DEFAULT_NAME.set(NodeType.ROUTE_BRANCH_NODE, '路由分支') +NODE_DEFAULT_NAME.set(NodeType.ROUTER_BRANCH_NODE, '路由分支') // 候选人策略。暂时不从字典中取。 后续可能调整。控制显示顺序 export const CANDIDATE_STRATEGY: DictDataVO[] = [ @@ -668,7 +668,7 @@ export const DELAY_TYPE = [ /** * 路由分支结构定义 */ -export type RouteCondition = { +export type RouterCondition = { nodeId: string conditionType: ConditionType conditionExpression: string diff --git a/src/components/SimpleProcessDesignerV2/src/node.ts b/src/components/SimpleProcessDesignerV2/src/node.ts index ea983ce91..bc8d8a112 100644 --- a/src/components/SimpleProcessDesignerV2/src/node.ts +++ b/src/components/SimpleProcessDesignerV2/src/node.ts @@ -148,6 +148,7 @@ export type UserTaskFormType = { taskCompleteListenerHeader?: ListenerParam[] taskCompleteListenerBody?: ListenerParam[] signEnable: boolean + reasonRequire: boolean } export type CopyTaskFormType = { diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue index 7c45e1bf6..f22168bd0 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue @@ -26,127 +26,11 @@
-
- 未满足其它条件时,将进入此分支(该分支不可编辑和删除) -
+
未满足其它条件时,将进入此分支(该分支不可编辑和删除)
- - - - - {{ dict.label }} - - - - - - - - -
-
-
条件组关系
- -
-
- - -
- -
- - -
-
- - - -
-
- - - -
-
- -
-
- -
-
- -
-
-
-
-
- -
-
-
+
- - - - - diff --git a/src/views/bpm/model/editor/index.vue b/src/views/bpm/model/editor/index.vue index 37eff739e..50386487b 100644 --- a/src/views/bpm/model/editor/index.vue +++ b/src/views/bpm/model/editor/index.vue @@ -12,10 +12,12 @@ :additionalModel="controlForm.additionalModel" :model="model" @save="save" + :process-id="modelKey" + :process-name="modelName" /> () @@ -51,10 +53,13 @@ const formType = ref(20) provide('formFields', formFields) provide('formType', formType) -const xmlString = ref('') // BPMN XML +// 注入流程数据 +const xmlString = inject('processData') as Ref +// 注入模型数据 +const modelData = inject('modelData') as Ref + const modeler = shallowRef() // BPMN Modeler const processDesigner = ref() -const isModelerReady = ref(false) const controlForm = ref({ simulation: true, labelEditing: false, @@ -65,154 +70,26 @@ const controlForm = ref({ }) const model = ref() // 流程模型的信息 -// 初始化 bpmnInstances -const initBpmnInstances = () => { - if (!modeler.value) return false - try { - const instances = { - modeler: modeler.value, - modeling: modeler.value.get('modeling'), - moddle: modeler.value.get('moddle'), - eventBus: modeler.value.get('eventBus'), - bpmnFactory: modeler.value.get('bpmnFactory'), - elementFactory: modeler.value.get('elementFactory'), - elementRegistry: modeler.value.get('elementRegistry'), - replace: modeler.value.get('replace'), - selection: modeler.value.get('selection') - } - - // 检查所有实例是否都存在 - return Object.values(instances).every((instance) => instance) - } catch (error) { - console.error('初始化 bpmnInstances 失败:', error) - return false - } -} - /** 初始化 modeler */ -const initModeler = async (item) => { - try { - modeler.value = item - // 等待 modeler 初始化完成 - await nextTick() - - // 确保 modeler 的所有实例都已经准备好 - if (initBpmnInstances()) { - isModelerReady.value = true - emit('init-finished') - - // 初始化完成后,设置初始值 - if (props.modelId) { - // 编辑模式 - const data = await ModelApi.getModel(props.modelId) - model.value = { - ...data, - bpmnXml: undefined // 清空 bpmnXml 属性 - } - xmlString.value = data.bpmnXml || getDefaultBpmnXml(data.key, data.name) - } else if (props.modelKey && props.modelName) { - // 新建模式 - xmlString.value = props.value || getDefaultBpmnXml(props.modelKey, props.modelName) - model.value = { - key: props.modelKey, - name: props.modelName - } as ModelApi.ModelVO - } - - // 导入XML并刷新视图 - await nextTick() - try { - await modeler.value.importXML(xmlString.value) - if (processDesigner.value?.refresh) { - processDesigner.value.refresh() - } - } catch (error) { - console.error('导入XML失败:', error) - } - } else { - console.error('modeler 实例未完全初始化') - } - } catch (error) { - console.error('初始化 modeler 失败:', error) - } -} - -/** 获取默认的BPMN XML */ -const getDefaultBpmnXml = (key: string, name: string) => { - return ` - - - - - -` +const initModeler = async (item: any) => { + //先初始化模型数据 + model.value = modelData.value + modeler.value = item } /** 添加/修改模型 */ const save = async (bpmnXml: string) => { try { xmlString.value = bpmnXml - if (props.modelId) { - // 编辑模式 - const data = { - ...model.value, - bpmnXml: bpmnXml - } as unknown as ModelApi.ModelVO - await ModelApi.updateModelBpmn(data) - emit('success') - } else { - // 新建模式,直接返回XML - emit('success', bpmnXml) - } + emit('success', bpmnXml) } catch (error) { console.error('保存失败:', error) message.error('保存失败') } } -// 监听 key、name 和 value 的变化 -watch( - [() => props.modelKey, () => props.modelName, () => props.value], - async ([newKey, newName, newValue]) => { - if (!props.modelId && isModelerReady.value) { - let shouldRefresh = false - - if (newKey && newName) { - const newXml = newValue || getDefaultBpmnXml(newKey, newName) - if (newXml !== xmlString.value) { - xmlString.value = newXml - shouldRefresh = true - } - model.value = { - ...model.value, - key: newKey, - name: newName - } as ModelApi.ModelVO - } else if (newValue && newValue !== xmlString.value) { - xmlString.value = newValue - shouldRefresh = true - } - - if (shouldRefresh) { - // 确保更新后重新渲染 - await nextTick() - if (processDesigner.value?.refresh) { - try { - await modeler.value?.importXML(xmlString.value) - processDesigner.value.refresh() - } catch (error) { - console.error('导入XML失败:', error) - } - } - } - } - }, - { deep: true } -) - // 在组件卸载时清理 onBeforeUnmount(() => { - isModelerReady.value = false modeler.value = null // 清理全局实例 const w = window as any @@ -220,55 +97,6 @@ onBeforeUnmount(() => { w.bpmnInstances = null } }) - -/** 获取 XML 字符串 */ -const saveXML = async () => { - if (!modeler.value) { - return { xml: xmlString.value } - } - try { - const result = await modeler.value.saveXML({ format: true }) - xmlString.value = result.xml - return result - } catch (error) { - console.error('获取XML失败:', error) - return { xml: xmlString.value } - } -} - -/** 获取SVG字符串 */ -const saveSVG = async () => { - if (!modeler.value) { - return { svg: undefined } - } - try { - return await modeler.value.saveSVG() - } catch (error) { - console.error('获取SVG失败:', error) - return { svg: undefined } - } -} - -/** 刷新视图 */ -const refresh = async () => { - if (processDesigner.value?.refresh && modeler.value) { - try { - await modeler.value.importXML(xmlString.value) - processDesigner.value.refresh() - } catch (error) { - console.error('刷新视图失败:', error) - } - } -} - -// 暴露必要的属性和方法给父组件 -defineExpose({ - modeler, - isModelerReady, - saveXML, - saveSVG, - refresh -}) diff --git a/src/views/bpm/simple/SimpleModelDesign.vue b/src/views/bpm/simple/SimpleModelDesign.vue index e07a04c98..09e5a688e 100644 --- a/src/views/bpm/simple/SimpleModelDesign.vue +++ b/src/views/bpm/simple/SimpleModelDesign.vue @@ -4,9 +4,7 @@ :model-id="modelId" :model-key="modelKey" :model-name="modelName" - :value="currentValue" @success="handleSuccess" - @init-finished="handleInit" :start-user-ids="startUserIds" ref="designerRef" /> @@ -19,136 +17,22 @@ defineOptions({ name: 'SimpleModelDesign' }) -const props = defineProps<{ +defineProps<{ modelId?: string modelKey?: string modelName?: string - value?: any startUserIds?: number[] }>() -const emit = defineEmits(['success', 'init-finished']) +const emit = defineEmits(['success']) const designerRef = ref() -const isInitialized = ref(false) -const currentValue = ref('') - -// 初始化或更新当前值 -const initOrUpdateValue = async () => { - if (props.value) { - currentValue.value = props.value - // 如果设计器已经初始化,立即加载数据 - if (isInitialized.value && designerRef.value) { - try { - await designerRef.value.loadProcessData(props.value) - await nextTick() - if (designerRef.value.refresh) { - await designerRef.value.refresh() - } - } catch (error) { - console.error('加载流程数据失败:', error) - } - } - } -} - -// 监听属性变化 -watch( - [() => props.modelKey, () => props.modelName, () => props.value], - async ([newKey, newName, newValue], [oldKey, oldName, oldValue]) => { - if (designerRef.value && isInitialized.value) { - try { - if (newKey && newName && (newKey !== oldKey || newName !== oldName)) { - await designerRef.value.updateModel(newKey, newName) - } - if (newValue && newValue !== oldValue) { - currentValue.value = newValue - await designerRef.value.loadProcessData(newValue) - await nextTick() - if (designerRef.value.refresh) { - await designerRef.value.refresh() - } - } - } catch (error) { - console.error('更新流程数据失败:', error) - } - } - }, - { deep: true, immediate: true } -) - -// 初始化完成回调 -const handleInit = async () => { - try { - isInitialized.value = true - emit('init-finished') - - // 等待下一个tick,确保设计器已经准备好 - await nextTick() - - // 初始化完成后,设置初始值 - if (props.modelKey && props.modelName) { - await designerRef.value.updateModel(props.modelKey, props.modelName) - } - if (props.value) { - currentValue.value = props.value - await designerRef.value.loadProcessData(props.value) - // 再次刷新确保数据正确加载 - await nextTick() - if (designerRef.value.refresh) { - await designerRef.value.refresh() - } - } - } catch (error) { - console.error('初始化流程数据失败:', error) - } -} // 修改成功回调 const handleSuccess = (data?: any) => { - console.warn('handleSuccess', data) - if (data && data !== currentValue.value) { - currentValue.value = data + console.info('handleSuccess', data) + if (data) { emit('success', data) } } - -/** 获取当前流程数据 */ -const getCurrentFlowData = async () => { - try { - if (designerRef.value) { - const data = await designerRef.value.getCurrentFlowData() - if (data) { - currentValue.value = data - } - return data - } - return currentValue.value || undefined - } catch (error) { - console.error('获取流程数据失败:', error) - return currentValue.value || undefined - } -} - -// 组件创建时初始化数据 -onMounted(() => { - initOrUpdateValue() -}) - -// 组件卸载前保存数据 -onBeforeUnmount(async () => { - try { - const data = await getCurrentFlowData() - if (data) { - emit('success', data) - } - } catch (error) { - console.error('保存数据失败:', error) - } -}) - -defineExpose({ - getCurrentFlowData, - refresh: () => designerRef.value?.refresh?.() -}) diff --git a/src/views/infra/build/index.vue b/src/views/infra/build/index.vue index ed1091e7b..260b8b7a0 100644 --- a/src/views/infra/build/index.vue +++ b/src/views/infra/build/index.vue @@ -135,7 +135,8 @@ const makeTemplate = () => { /** 复制 **/ const copy = async (text: string) => { - const { copy, copied, isSupported } = useClipboard({ source: text }) + const textToCopy = JSON.stringify(text, null, 2) + const { copy, copied, isSupported } = useClipboard({ source: textToCopy }) if (!isSupported) { message.error(t('common.copyError')) } else { @@ -149,17 +150,18 @@ const copy = async (text: string) => { /** * 代码高亮 */ -const highlightedCode = (code) => { +const highlightedCode = (code: string) => { // 处理语言和代码 let language = 'json' if (formType.value === 2) { language = 'xml' } + // debugger if (!isString(code)) { - code = JSON.stringify(code) + code = JSON.stringify(code, null, 2) } // 高亮 - const result = hljs.highlight(language, code, true) + const result = hljs.highlight(code, { language: language, ignoreIllegals: true }) return result.value || ' ' } diff --git a/src/views/infra/file/index.vue b/src/views/infra/file/index.vue index 3fcda6e8d..e67ad51b7 100644 --- a/src/views/infra/file/index.vue +++ b/src/views/infra/file/index.vue @@ -95,6 +95,9 @@ />