|
|
@@ -1,15 +1,20 @@
|
|
|
<template>
|
|
|
- <div class="process">
|
|
|
+ <div class="relative flex size-full items-center justify-center">
|
|
|
<TeleportContainer />
|
|
|
- <div class="process-chart">
|
|
|
- <workflowChart
|
|
|
- :ID="ID"
|
|
|
- :data="state.workflowData"
|
|
|
- ref="ref_workflow"
|
|
|
- @save="onSave"
|
|
|
- />
|
|
|
+ <div class="relative z-1 size-full">
|
|
|
+ <workflowChart :ID="ID" :data="state.workflowData" ref="ref_workflow" />
|
|
|
+ <div class="absolute top-4 left-4 flex items-center gap-4">
|
|
|
+ <CzrButton type="primary" title="保存" @click="onSave" />
|
|
|
+ <div class="flex items-center text-[var(--czr-error-color)]">
|
|
|
+ <SvgIcon name="czr_tip" color="var(--czr-error-color)" class="mr-1" />
|
|
|
+ 有未保存的修改
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <div class="panel">
|
|
|
+ <div
|
|
|
+ class="absolute top-0 top-4 right-4 z-2 flex gap-2.5"
|
|
|
+ style="height: calc(100% - 2rem)"
|
|
|
+ >
|
|
|
<workflowPanel />
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -27,13 +32,14 @@ import {
|
|
|
import workflowChart from './chart/index.vue'
|
|
|
import workflowPanel from './chart/panel-index.vue'
|
|
|
import { getTeleport } from '@antv/x6-vue-shape'
|
|
|
-import { useAppStore, useDictionaryStore, useWorkflowStore } from '@/stores'
|
|
|
+import { useAppStore, useDictionaryStore, useProcessStore } from '@/stores'
|
|
|
import { debounce } from 'lodash'
|
|
|
+import { ElLoading } from 'element-plus'
|
|
|
|
|
|
const DictionaryStore = useDictionaryStore()
|
|
|
const AppStore = useAppStore()
|
|
|
const TeleportContainer = getTeleport()
|
|
|
-const WorkflowStore = useWorkflowStore()
|
|
|
+const ProcessStore = useProcessStore()
|
|
|
const emit = defineEmits(['autoSave'])
|
|
|
const props = defineProps({
|
|
|
ID: {},
|
|
|
@@ -41,7 +47,6 @@ const props = defineProps({
|
|
|
const { proxy }: any = getCurrentInstance()
|
|
|
const state: any = reactive({
|
|
|
workflowData: null,
|
|
|
- uniqueHash: '',
|
|
|
})
|
|
|
const ref_workflow = ref()
|
|
|
|
|
|
@@ -49,99 +54,155 @@ const autoSave = debounce(() => {
|
|
|
onSave()
|
|
|
}, 5000)
|
|
|
watch(
|
|
|
- () => WorkflowStore.autoSaveFlag,
|
|
|
+ () => ProcessStore.autoSaveFlag,
|
|
|
() => {
|
|
|
autoSave()
|
|
|
},
|
|
|
)
|
|
|
const onSave = () => {
|
|
|
- // const data = ref_workflow.value.toJSON()
|
|
|
- // const offset = WorkflowStore.graph.translate()
|
|
|
- // const res: any = {
|
|
|
- // conversationVariables: [],
|
|
|
- // environmentVariables: handleEnv(WorkflowStore.envVars.vars),
|
|
|
- // hash: state.uniqueHash,
|
|
|
- // graph: {
|
|
|
- // nodes: [],
|
|
|
- // edges: [],
|
|
|
- // viewport: {
|
|
|
- // zoom: WorkflowStore.graph.zoom(),
|
|
|
- // x: offset.tx,
|
|
|
- // y: offset.ty,
|
|
|
- // },
|
|
|
- // },
|
|
|
- // }
|
|
|
- // JSON.parse(JSON.stringify(data.cells)).forEach((cell: any) => {
|
|
|
- // if (cell.shape === 'process-node') {
|
|
|
- // const node: any = {
|
|
|
- // id: cell.id,
|
|
|
- // type: cell.data.workflowData.type,
|
|
|
- // position: cell.position,
|
|
|
- // data: handleNodeSubmit(cell.data.workflowData),
|
|
|
- // }
|
|
|
- // delete node.data.edgeSource
|
|
|
- // delete node.data.inVars
|
|
|
- // res.graph.nodes.push(node)
|
|
|
- // } else if (cell.shape === 'edge') {
|
|
|
- // const edge: any = {
|
|
|
- // target: cell.target.cell,
|
|
|
- // source: cell.source.cell,
|
|
|
- // }
|
|
|
- // if (!cell.source.port.includes('end')) {
|
|
|
- // edge.sourceHandle = cell.source.port
|
|
|
- // }
|
|
|
- // res.graph.edges.push(edge)
|
|
|
- // }
|
|
|
- // })
|
|
|
- // const loading = ElLoading.service({
|
|
|
- // text: '自动保存中……',
|
|
|
- // background: 'rgba(0, 0,0, 0.3)',
|
|
|
- // })
|
|
|
- // workflowDraftSave(props.ID, res)
|
|
|
- // .then(({ data }: any) => {
|
|
|
- // loading.close()
|
|
|
- // state.uniqueHash = data.uniqueHash
|
|
|
- // emit('autoSave', data.updateTime)
|
|
|
- // })
|
|
|
- // .catch(() => {})
|
|
|
- // .finally(() => {})
|
|
|
+ const data = ref_workflow.value.toJSON()
|
|
|
+ const offset = ProcessStore.graph.translate()
|
|
|
+ const res: any = {
|
|
|
+ graph: {
|
|
|
+ nodes: [],
|
|
|
+ edges: [],
|
|
|
+ viewport: {
|
|
|
+ zoom: ProcessStore.graph.zoom(),
|
|
|
+ x: offset.tx,
|
|
|
+ y: offset.ty,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+ JSON.parse(JSON.stringify(data.cells)).forEach((cell: any) => {
|
|
|
+ if (cell.shape === 'edge') {
|
|
|
+ const edge: any = {
|
|
|
+ id: cell.id,
|
|
|
+ target: cell.target.cell,
|
|
|
+ source: cell.source.cell,
|
|
|
+ }
|
|
|
+ res.graph.edges.push(edge)
|
|
|
+ } else {
|
|
|
+ const node: any = {
|
|
|
+ id: cell.id,
|
|
|
+ type: cell.data.workflowData.type,
|
|
|
+ position: cell.position,
|
|
|
+ data: cell.data.workflowData,
|
|
|
+ }
|
|
|
+ res.graph.nodes.push(node)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ const loading = ElLoading.service({
|
|
|
+ text: '保存中……',
|
|
|
+ background: 'rgba(0, 0,0, 0.3)',
|
|
|
+ })
|
|
|
+ console.log(res)
|
|
|
+ loading.close()
|
|
|
}
|
|
|
const initData = () => {
|
|
|
state.workflowData = {
|
|
|
nodes: [],
|
|
|
edges: [],
|
|
|
}
|
|
|
-
|
|
|
- // workflowDraftDetail(props.ID)
|
|
|
- // .then(({ data }: any) => {
|
|
|
- // emit('autoSave', data.updateTime)
|
|
|
- // state.uniqueHash = data.uniqueHash
|
|
|
- // WorkflowStore.$patch(
|
|
|
- // (s: any) => (s.envVars.vars = data.environmentVariables || []),
|
|
|
- // )
|
|
|
- // if (data.graph.viewport) {
|
|
|
- // const graph = {
|
|
|
- // viewport: data.graph.viewport,
|
|
|
- // nodes: formatNodes(data.graph.nodes),
|
|
|
- // edges: formatEdges(data.graph.edges),
|
|
|
- // }
|
|
|
- // state.workflowData = graph
|
|
|
- // } else {
|
|
|
- // state.workflowData = {
|
|
|
- // nodes: [],
|
|
|
- // edges: [],
|
|
|
- // }
|
|
|
- // }
|
|
|
- // // state.workflowData = {
|
|
|
- // // nodes: [],
|
|
|
- // // edges: [],
|
|
|
- // // }
|
|
|
- // })
|
|
|
- // .catch(() => {})
|
|
|
- // .finally(() => {})
|
|
|
- // const d = data0
|
|
|
- // WorkflowStore.$patch((s: any) => (s.envVars.vars = d.envVars || []))
|
|
|
- // state.workflowData = d.graph
|
|
|
+ const data = {
|
|
|
+ graph: {
|
|
|
+ nodes: [
|
|
|
+ {
|
|
|
+ id: '56ad6c45-c8b5-4add-b39a-48ecf4c11b3d',
|
|
|
+ type: 'start',
|
|
|
+ position: {
|
|
|
+ x: 23,
|
|
|
+ y: 35,
|
|
|
+ },
|
|
|
+ data: {
|
|
|
+ id: '56ad6c45-c8b5-4add-b39a-48ecf4c11b3d',
|
|
|
+ title: '发起',
|
|
|
+ edgeSource: null,
|
|
|
+ edgeTarget: ['c9102b83-cda6-495f-b8c0-4d3a85fa26db'],
|
|
|
+ type: 'start',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'cbec7e8f-c094-440a-bbc5-714c032196eb',
|
|
|
+ type: 'end',
|
|
|
+ position: {
|
|
|
+ x: 23,
|
|
|
+ y: 477,
|
|
|
+ },
|
|
|
+ data: {
|
|
|
+ id: 'cbec7e8f-c094-440a-bbc5-714c032196eb',
|
|
|
+ title: '结束',
|
|
|
+ edgeSource: ['3f2a36d7-94f6-404c-bcc1-c3392d0ee626'],
|
|
|
+ edgeTarget: null,
|
|
|
+ type: 'end',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '3f2a36d7-94f6-404c-bcc1-c3392d0ee626',
|
|
|
+ type: 'approval',
|
|
|
+ position: {
|
|
|
+ x: 260,
|
|
|
+ y: 350,
|
|
|
+ },
|
|
|
+ data: {
|
|
|
+ id: '3f2a36d7-94f6-404c-bcc1-c3392d0ee626',
|
|
|
+ title: '审批节点',
|
|
|
+ edgeSource: ['c9102b83-cda6-495f-b8c0-4d3a85fa26db'],
|
|
|
+ edgeTarget: ['cbec7e8f-c094-440a-bbc5-714c032196eb'],
|
|
|
+ type: 'approval',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'c9102b83-cda6-495f-b8c0-4d3a85fa26db',
|
|
|
+ type: 'approval',
|
|
|
+ position: {
|
|
|
+ x: -240,
|
|
|
+ y: 210,
|
|
|
+ },
|
|
|
+ data: {
|
|
|
+ id: 'c9102b83-cda6-495f-b8c0-4d3a85fa26db',
|
|
|
+ title: '审批节点',
|
|
|
+ edgeSource: ['56ad6c45-c8b5-4add-b39a-48ecf4c11b3d'],
|
|
|
+ edgeTarget: ['3f2a36d7-94f6-404c-bcc1-c3392d0ee626'],
|
|
|
+ type: 'approval',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ edges: [
|
|
|
+ {
|
|
|
+ id: '4baed89d-c158-4359-85f4-3bd12519e4b0',
|
|
|
+ target: 'cbec7e8f-c094-440a-bbc5-714c032196eb',
|
|
|
+ source: '3f2a36d7-94f6-404c-bcc1-c3392d0ee626',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '931f583d-4cd0-4e2e-ae9b-06e780f07fa7',
|
|
|
+ target: 'c9102b83-cda6-495f-b8c0-4d3a85fa26db',
|
|
|
+ source: '56ad6c45-c8b5-4add-b39a-48ecf4c11b3d',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 'e1c401eb-a538-46f8-ac45-6c6deaf90338',
|
|
|
+ target: '3f2a36d7-94f6-404c-bcc1-c3392d0ee626',
|
|
|
+ source: 'c9102b83-cda6-495f-b8c0-4d3a85fa26db',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ viewport: {
|
|
|
+ zoom: 1,
|
|
|
+ x: 616,
|
|
|
+ y: 86,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+ if (data.graph.viewport) {
|
|
|
+ state.workflowData = {
|
|
|
+ viewport: data.graph.viewport,
|
|
|
+ nodes: formatNodes(data.graph.nodes),
|
|
|
+ edges: formatEdges(data.graph.edges),
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ state.workflowData = {
|
|
|
+ nodes: [],
|
|
|
+ edges: [],
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
const formatNodes = (arr) => {
|
|
|
return arr.map((node: any) => {
|
|
|
@@ -157,9 +218,9 @@ const formatNodes = (arr) => {
|
|
|
const formatEdges = (arr) => {
|
|
|
return arr.map((edge: any) => {
|
|
|
const obj = {
|
|
|
+ id: edge.id,
|
|
|
source: edge.source,
|
|
|
target: edge.target,
|
|
|
- port: edge.sourceHandle || null,
|
|
|
}
|
|
|
return obj
|
|
|
})
|
|
|
@@ -171,52 +232,4 @@ onMounted(() => {
|
|
|
const initDictionary = () => {}
|
|
|
</script>
|
|
|
|
|
|
-<style lang="scss" scoped>
|
|
|
-.process {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- position: relative;
|
|
|
- position: relative;
|
|
|
- .process-chart {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- z-index: 1;
|
|
|
- }
|
|
|
- .operations {
|
|
|
- position: absolute;
|
|
|
- top: 10px;
|
|
|
- right: 10px;
|
|
|
- z-index: 2;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 10px;
|
|
|
- > div {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- background-color: rgba(255, 255, 255, 0.95);
|
|
|
- box-shadow: 0 0px 8px rgba(0, 0, 0, 0.1);
|
|
|
- border-radius: 6px;
|
|
|
- padding: 4px;
|
|
|
- > div {
|
|
|
- min-width: 24px;
|
|
|
- height: 24px;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- .panel {
|
|
|
- z-index: 2;
|
|
|
- position: absolute;
|
|
|
- right: 0;
|
|
|
- bottom: 0;
|
|
|
- display: flex;
|
|
|
- gap: 10px;
|
|
|
- height: calc(100% - 10px - 32px - 10px);
|
|
|
- }
|
|
|
-}
|
|
|
-</style>
|
|
|
+<style lang="scss" scoped></style>
|