From 8d6ef40d3e0316262a4dca9bbabc81980af3784f Mon Sep 17 00:00:00 2001 From: dap <15891557205@163.com> Date: Thu, 29 May 2025 19:30:57 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=80=82=E9=85=8D=E6=96=B0?= =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=E9=A2=84=E8=A7=88=20=E7=94=B1logicf?= =?UTF-8?q?low=E6=94=B9=E4=B8=BAiframe=20=E7=9C=9F=E6=9C=8D=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/package.json | 1 - .../src/api/workflow/instance/index.ts | 2 +- .../src/api/workflow/instance/model.d.ts | 7 +- .../workflow/components/approval-panel.vue | 7 +- .../workflow/components/flow-preview.vue | 28 ++ .../components/flow-preview/index.vue | 121 --------- .../components/flow-preview/model/between.ts | 21 -- .../components/flow-preview/model/end.ts | 16 -- .../components/flow-preview/model/parallel.ts | 59 ----- .../components/flow-preview/model/serial.ts | 59 ----- .../components/flow-preview/model/skip.ts | 32 --- .../components/flow-preview/model/start.ts | 16 -- .../components/flow-preview/model/tool.ts | 248 ------------------ 13 files changed, 32 insertions(+), 585 deletions(-) create mode 100644 apps/web-antd/src/views/workflow/components/flow-preview.vue delete mode 100644 apps/web-antd/src/views/workflow/components/flow-preview/index.vue delete mode 100644 apps/web-antd/src/views/workflow/components/flow-preview/model/between.ts delete mode 100644 apps/web-antd/src/views/workflow/components/flow-preview/model/end.ts delete mode 100644 apps/web-antd/src/views/workflow/components/flow-preview/model/parallel.ts delete mode 100644 apps/web-antd/src/views/workflow/components/flow-preview/model/serial.ts delete mode 100644 apps/web-antd/src/views/workflow/components/flow-preview/model/skip.ts delete mode 100644 apps/web-antd/src/views/workflow/components/flow-preview/model/start.ts delete mode 100644 apps/web-antd/src/views/workflow/components/flow-preview/model/tool.ts diff --git a/apps/web-antd/package.json b/apps/web-antd/package.json index 170bda60..8a0dc7bd 100644 --- a/apps/web-antd/package.json +++ b/apps/web-antd/package.json @@ -27,7 +27,6 @@ }, "dependencies": { "@ant-design/icons-vue": "^7.0.1", - "@logicflow/core": "^2.0.13", "@tinymce/tinymce-vue": "^6.0.1", "@vben/access": "workspace:*", "@vben/common-ui": "workspace:*", diff --git a/apps/web-antd/src/api/workflow/instance/index.ts b/apps/web-antd/src/api/workflow/instance/index.ts index 774f3999..ed3523d1 100644 --- a/apps/web-antd/src/api/workflow/instance/index.ts +++ b/apps/web-antd/src/api/workflow/instance/index.ts @@ -94,7 +94,7 @@ export function pageByCurrent(params?: PageQuery) { */ export function flowInfo(businessId: string) { return requestClient.get( - `/workflow/instance/flowImage/${businessId}`, + `/workflow/instance/flowHisTaskList/${businessId}`, ); } diff --git a/apps/web-antd/src/api/workflow/instance/model.d.ts b/apps/web-antd/src/api/workflow/instance/model.d.ts index 0cbe92cd..133d06a3 100644 --- a/apps/web-antd/src/api/workflow/instance/model.d.ts +++ b/apps/web-antd/src/api/workflow/instance/model.d.ts @@ -36,11 +36,6 @@ export interface Flow { } export interface FlowInfoResponse { - image: string; + instanceId: string; list: Flow[]; - defChart: { - defJson: Record; - nodeJsonList: Record[]; - skipJsonList: Record[]; - }; } diff --git a/apps/web-antd/src/views/workflow/components/approval-panel.vue b/apps/web-antd/src/views/workflow/components/approval-panel.vue index 5b446fa2..b0a5632f 100644 --- a/apps/web-antd/src/views/workflow/components/approval-panel.vue +++ b/apps/web-antd/src/views/workflow/components/approval-panel.vue @@ -41,8 +41,8 @@ import { import { renderDict } from '#/utils/render'; import { approvalModal, approvalRejectionModal, flowInterfereModal } from '.'; -import FlowPreview from '../components/flow-preview/index.vue'; import ApprovalDetails from './approval-details.vue'; +import FlowPreview from './flow-preview.vue'; import { approveWithReasonModal } from './helper'; import userSelectModal from './user-select-modal.vue'; @@ -443,10 +443,7 @@ async function handleCopy(text: string) { /> - + diff --git a/apps/web-antd/src/views/workflow/components/flow-preview.vue b/apps/web-antd/src/views/workflow/components/flow-preview.vue new file mode 100644 index 00000000..6be8b703 --- /dev/null +++ b/apps/web-antd/src/views/workflow/components/flow-preview.vue @@ -0,0 +1,28 @@ + + + diff --git a/apps/web-antd/src/views/workflow/components/flow-preview/index.vue b/apps/web-antd/src/views/workflow/components/flow-preview/index.vue deleted file mode 100644 index 308f0d1c..00000000 --- a/apps/web-antd/src/views/workflow/components/flow-preview/index.vue +++ /dev/null @@ -1,121 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/workflow/components/flow-preview/model/between.ts b/apps/web-antd/src/views/workflow/components/flow-preview/model/between.ts deleted file mode 100644 index 6b877479..00000000 --- a/apps/web-antd/src/views/workflow/components/flow-preview/model/between.ts +++ /dev/null @@ -1,21 +0,0 @@ -import LogicFlow, { RectNode, RectNodeModel } from '@logicflow/core'; - -class BetweenModel extends RectNodeModel { - override getNodeStyle() { - return super.getNodeStyle(); - } - override initNodeData(data: LogicFlow.NodeConfig) { - super.initNodeData(data); - this.width = 100; - this.height = 80; - this.radius = 5; - } -} - -class BetweenView extends RectNode {} - -export default { - type: 'between', - model: BetweenModel, - view: BetweenView, -}; diff --git a/apps/web-antd/src/views/workflow/components/flow-preview/model/end.ts b/apps/web-antd/src/views/workflow/components/flow-preview/model/end.ts deleted file mode 100644 index b29ef3ed..00000000 --- a/apps/web-antd/src/views/workflow/components/flow-preview/model/end.ts +++ /dev/null @@ -1,16 +0,0 @@ -import LogicFlow, { CircleNode, CircleNodeModel } from '@logicflow/core'; - -class endModel extends CircleNodeModel { - override initNodeData(data: LogicFlow.NodeConfig) { - super.initNodeData(data); - this.r = 20; - } -} - -class endView extends CircleNode {} - -export default { - type: 'end', - model: endModel, - view: endView, -}; diff --git a/apps/web-antd/src/views/workflow/components/flow-preview/model/parallel.ts b/apps/web-antd/src/views/workflow/components/flow-preview/model/parallel.ts deleted file mode 100644 index 84623e75..00000000 --- a/apps/web-antd/src/views/workflow/components/flow-preview/model/parallel.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { GraphModel } from '@logicflow/core'; - -import LogicFlow, { h, PolygonNode, PolygonNodeModel } from '@logicflow/core'; - -class ParallelModel extends PolygonNodeModel { - static extendKey = 'ParallelModel'; - - constructor(data: LogicFlow.NodeConfig, graphModel: GraphModel) { - if (!data.text) { - data.text = ''; - } - if (data.text && typeof data.text === 'string') { - data.text = { - value: data.text, - x: data.x, - y: data.y + 40, - }; - } - super(data, graphModel); - this.points = [ - [25, 0], - [50, 25], - [25, 50], - [0, 25], - ]; - } -} - -class ParallelView extends PolygonNode { - static extendKey = 'ParallelNode'; - - override getShape() { - const { model } = this.props; - const { x, y, width, height, points } = model; - const style = model.getNodeStyle(); - return h( - 'g', - { - transform: `matrix(1 0 0 1 ${x - width / 2} ${y - height / 2})`, - }, - h('polygon', { - ...style, - x, - y, - points, - }), - h('path', { - d: 'm 23,10 0,12.5 -12.5,0 0,5 12.5,0 0,12.5 5,0 0,-12.5 12.5,0 0,-5 -12.5,0 0,-12.5 -5,0 z', - ...style, - }), - ); - } -} - -export default { - type: 'parallel', - view: ParallelView, - model: ParallelModel, -}; diff --git a/apps/web-antd/src/views/workflow/components/flow-preview/model/serial.ts b/apps/web-antd/src/views/workflow/components/flow-preview/model/serial.ts deleted file mode 100644 index 8e78041e..00000000 --- a/apps/web-antd/src/views/workflow/components/flow-preview/model/serial.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { GraphModel } from '@logicflow/core'; - -import LogicFlow, { h, PolygonNode, PolygonNodeModel } from '@logicflow/core'; - -class SerialModel extends PolygonNodeModel { - static extendKey = 'SerialModel'; - - constructor(data: LogicFlow.NodeConfig, graphModel: GraphModel) { - if (!data.text) { - data.text = ''; - } - if (data.text && typeof data.text === 'string') { - data.text = { - value: data.text, - x: data.x, - y: data.y + 40, - }; - } - super(data, graphModel); - this.points = [ - [25, 0], - [50, 25], - [25, 50], - [0, 25], - ]; - } -} - -class SerialView extends PolygonNode { - static extendKey = 'SerialNode'; - - override getShape() { - const { model } = this.props; - const { x, y, width, height, points } = model; - const style = model.getNodeStyle(); - return h( - 'g', - { - transform: `matrix(1 0 0 1 ${x - width / 2} ${y - height / 2})`, - }, - h('polygon', { - ...style, - x, - y, - points, - }), - h('path', { - d: 'm 16,15 7.42857142857143,9.714285714285715 -7.42857142857143,9.714285714285715 3.428571428571429,0 5.714285714285715,-7.464228571428572 5.714285714285715,7.464228571428572 3.428571428571429,0 -7.42857142857143,-9.714285714285715 7.42857142857143,-9.714285714285715 -3.428571428571429,0 -5.714285714285715,7.464228571428572 -5.714285714285715,-7.464228571428572 -3.428571428571429,0 z', - ...style, - }), - ); - } -} - -export default { - type: 'serial', - view: SerialView, - model: SerialModel, -}; diff --git a/apps/web-antd/src/views/workflow/components/flow-preview/model/skip.ts b/apps/web-antd/src/views/workflow/components/flow-preview/model/skip.ts deleted file mode 100644 index 25cde40a..00000000 --- a/apps/web-antd/src/views/workflow/components/flow-preview/model/skip.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { PolylineEdge, PolylineEdgeModel } from '@logicflow/core'; - -class SkipModel extends PolylineEdgeModel { - /** - * 重写此方法,使保存数据是能带上锚点数据。 - */ - override getData() { - const data = super.getData(); - data.sourceAnchorId = this.sourceAnchorId; - data.targetAnchorId = this.targetAnchorId; - return data; - } - - override getEdgeStyle() { - const style = super.getEdgeStyle(); - const { properties } = this; - if (properties.isActived) { - style.strokeDasharray = '4 4'; - } - return style; - } - - override setAttributes() { - this.offset = 20; - } -} - -export default { - type: 'skip', - view: PolylineEdge, - model: SkipModel, -}; diff --git a/apps/web-antd/src/views/workflow/components/flow-preview/model/start.ts b/apps/web-antd/src/views/workflow/components/flow-preview/model/start.ts deleted file mode 100644 index 57f761cd..00000000 --- a/apps/web-antd/src/views/workflow/components/flow-preview/model/start.ts +++ /dev/null @@ -1,16 +0,0 @@ -import LogicFlow, { CircleNode, CircleNodeModel } from '@logicflow/core'; - -class StartModel extends CircleNodeModel { - override initNodeData(data: LogicFlow.NodeConfig) { - super.initNodeData(data); - this.r = 20; - } -} - -class StartView extends CircleNode {} - -export default { - type: 'start', - model: StartModel, - view: StartView, -}; diff --git a/apps/web-antd/src/views/workflow/components/flow-preview/model/tool.ts b/apps/web-antd/src/views/workflow/components/flow-preview/model/tool.ts deleted file mode 100644 index 1de518e9..00000000 --- a/apps/web-antd/src/views/workflow/components/flow-preview/model/tool.ts +++ /dev/null @@ -1,248 +0,0 @@ -/* eslint-disable unicorn/no-array-reduce */ -const NODE_TYPE_MAP = { - 0: 'start', - 1: 'between', - 2: 'end', - 3: 'serial', - 4: 'parallel', -}; - -/** - * 将warm-flow的定义json数据转成LogicFlow支持的数据格式 - * @param {*} json - * @returns LogicFlow的数据 - */ -export const json2LogicFlowJson = (definition: any) => { - const graphData: any = { - nodes: [], - edges: [], - }; - // 解析definition属性 - graphData.flowCode = definition.flowCode; - graphData.flowName = definition.flowName; - graphData.version = definition.version; - graphData.fromCustom = definition.fromCustom; - graphData.fromPath = definition.fromPath; - // 解析节点 - const allSkips = definition.nodeList.reduce((acc: any, node: any) => { - if (node.skipList && Array.isArray(node.skipList)) { - acc.push(...node.skipList); - } - return acc; - }, []); - const allNodes = definition.nodeList; - // 解析节点 - if (allNodes.length > 0) { - for (let i = 0, len = allNodes.length; i < len; i++) { - const node = allNodes[i]; - const lfNode: any = { - text: {}, - properties: {}, - }; - // 处理节点 - lfNode.type = (NODE_TYPE_MAP as any)[node.nodeType]; - lfNode.id = node.nodeCode; - const coordinate = node.coordinate; - if (coordinate) { - const attr = coordinate.split('|'); - const nodeXy = attr[0].split(','); - lfNode.x = Number.parseInt(nodeXy[0]); - lfNode.y = Number.parseInt(nodeXy[1]); - if (attr.length === 2) { - const textXy = attr[1].split(','); - lfNode.text.x = Number.parseInt(textXy[0]); - lfNode.text.y = Number.parseInt(textXy[1]); - } - } - lfNode.text.value = node.nodeName; - lfNode.properties.nodeRatio = node.nodeRatio.toString(); - lfNode.properties.permissionFlag = node.permissionFlag; - lfNode.properties.anyNodeSkip = node.anyNodeSkip; - lfNode.properties.listenerType = node.listenerType; - lfNode.properties.listenerPath = node.listenerPath; - lfNode.properties.formCustom = node.formCustom; - lfNode.properties.formPath = node.formPath; - lfNode.properties.ext = {}; - if (node.ext && typeof node.ext === 'string') { - try { - node.ext = JSON.parse(node.ext); - node.ext.forEach((e: any) => { - lfNode.properties.ext[e.code] = String(e.value).includes(',') - ? e.value.split(',') - : String(e.value); - }); - } catch (error) { - console.error('Error parsing JSON:', error); - } - } - lfNode.properties.style = {}; - if (node.status === 2) { - lfNode.properties.style.fill = '#F0FFD9'; - lfNode.properties.style.stroke = '#9DFF00'; - } - if (node.status === 1) { - lfNode.properties.style.fill = '#FFF8DC'; - lfNode.properties.style.stroke = '#FFCD17'; - } - graphData.nodes.push(lfNode); - } - } - if (allSkips.length > 0) { - // 处理边 - let skipEle = null; - let edge: any = {}; - for (let j = 0, lenn = allSkips.length; j < lenn; j++) { - skipEle = allSkips[j]; - edge = { - text: {}, - properties: {}, - }; - edge.id = skipEle.id; - edge.type = 'skip'; - edge.sourceNodeId = skipEle.nowNodeCode; - edge.targetNodeId = skipEle.nextNodeCode; - edge.text = { value: skipEle.skipName }; - edge.properties.skipCondition = skipEle.skipCondition; - edge.properties.skipName = skipEle.skipName; - edge.properties.skipType = skipEle.skipType; - const expr = skipEle.expr; - if (expr) { - edge.properties.expr = skipEle.expr; - } - const coordinate = skipEle.coordinate; - if (coordinate) { - const coordinateXy = coordinate.split('|'); - edge.pointsList = []; - coordinateXy[0].split(';').forEach((item: any) => { - const pointArr = item.split(','); - edge.pointsList.push({ - x: Number.parseInt(pointArr[0]), - y: Number.parseInt(pointArr[1]), - }); - }); - edge.startPoint = edge.pointsList[0]; - edge.endPoint = edge.pointsList[edge.pointsList.length - 1]; - if (coordinateXy.length > 1) { - const textXy = coordinateXy[1].split(','); - edge.text.x = Number.parseInt(textXy[0]); - edge.text.y = Number.parseInt(textXy[1]); - } - } - graphData.edges.push(edge); - } - } - console.log(graphData); - return graphData; -}; - -/** - * 将LogicFlow的数据转成warm-flow的json定义文件 - * @param {*} data(...definitionInfo,nodes,edges) - * @returns - */ -export const logicFlowJsonToWarmFlow = (data: any) => { - // 先构建成流程对象 - const definition: any = { - nodeList: [], - }; - - /** - * 根据节点的类型值,获取key - * @param {*} mapValue 节点类型映射 - * @returns - */ - const getNodeTypeValue = (mapValue: any) => { - for (const key in NODE_TYPE_MAP) { - if ((NODE_TYPE_MAP as any)[key] === mapValue) { - return key; - } - } - }; - /** - * 根据节点的编码,获取节点的类型 - * @param {*} nodeCode 当前节点名称 - * @returns - */ - const getNodeType = (nodeCode: any) => { - for (const node of definition.nodeList) { - if (nodeCode === node.nodeCode) { - return node.nodeType; - } - } - }; - /** - * 拼接skip坐标 - * @param {*} edge logicFlow的edge - * @returns - */ - const getCoordinate = (edge: any) => { - let coordinate = ''; - for (let i = 0; i < edge.pointsList.length; i++) { - coordinate = `${ - coordinate + Number.parseInt(edge.pointsList[i].x) - },${Number.parseInt(edge.pointsList[i].y)}`; - if (i !== edge.pointsList.length - 1) { - coordinate = `${coordinate};`; - } - } - if (edge.text) { - coordinate = `${coordinate}|${Number.parseInt(edge.text.x)},${Number.parseInt(edge.text.y)}`; - } - return coordinate; - }; - // 流程定义 - definition.id = data.id; - definition.flowCode = data.flowCode; - definition.flowName = data.flowName; - definition.version = data.version; - definition.fromCustom = data.fromCustom; - definition.fromPath = data.fromPath; - // 流程节点 - data.nodes.forEach((anyNode: any) => { - const node: any = {}; - node.nodeType = getNodeTypeValue(anyNode.type); - node.nodeCode = anyNode.id; - if (anyNode.text) { - node.nodeName = anyNode.text.value; - } - node.permissionFlag = anyNode.properties.permissionFlag; - node.nodeRatio = anyNode.properties.nodeRatio; - node.anyNodeSkip = anyNode.properties.anyNodeSkip; - node.listenerType = anyNode.properties.listenerType; - node.listenerPath = anyNode.properties.listenerPath; - node.formCustom = anyNode.properties.formCustom; - node.formPath = anyNode.properties.formPath; - node.ext = []; - for (const key in anyNode.properties.ext) { - if (Object.prototype.hasOwnProperty.call(anyNode.properties.ext, key)) { - const e = anyNode.properties.ext[key]; - node.ext.push({ code: key, value: Array.isArray(e) ? e.join(',') : e }); - } - } - node.ext = JSON.stringify(node.ext); - node.coordinate = `${anyNode.x},${anyNode.y}`; - if (anyNode.text && anyNode.text.x && anyNode.text.y) { - node.coordinate = `${node.coordinate}|${anyNode.text.x},${anyNode.text.y}`; - } - node.handlerType = anyNode.properties.handlerType; - node.handlerPath = anyNode.properties.handlerPath; - node.version = definition.version; - node.skipList = []; - data.edges.forEach((anyEdge: any) => { - if (anyEdge.sourceNodeId === anyNode.id) { - const skip: any = {}; - skip.skipType = anyEdge.properties.skipType; - skip.skipCondition = anyEdge.properties.skipCondition; - skip.skipName = anyEdge?.text?.value || anyEdge.properties.skipName; - skip.nowNodeCode = anyEdge.sourceNodeId; - skip.nowNodeType = getNodeType(skip.nowNodeCode); - skip.nextNodeCode = anyEdge.targetNodeId; - skip.nextNodeType = getNodeType(skip.nextNodeCode); - skip.coordinate = getCoordinate(anyEdge); - node.skipList.push(skip); - } - }); - definition.nodeList.push(node); - }); - return JSON.stringify(definition); -};