123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- <template>
- <div class="FL-container getting-started">
- <!-- 辅助工具栏 -->
- <Control class="demo-control" v-if="lf.container" :lf="lf as LogicFlow" @catData="$_catData" @saveModel="$_saveModel"></Control>
- <!-- 画布 -->
- <div class="app-content" ref="logicFlowContainerRef"></div>
- <!-- 属性面板 -->
- <el-drawer :title="t('message.flowModel.setNodeProps')" v-model="dialogVisible" direction="rtl" size="900px" :before-close="closeDialog">
- <PropertyDialog v-if="dialogVisible" :nodeData="clickNode" :lf="lf as LogicFlow" @setPropertiesFinish="closeDialog"></PropertyDialog>
- </el-drawer>
- <!-- 数据查看面板 -->
- <el-dialog :title="t('message.flowModel.data')" v-model="dataVisible" width="50%">
- <DataDialog :graphData="graphData"></DataDialog>
- </el-dialog>
- </div>
- </template>
- <script setup lang="ts">
- import LogicFlow from '@logicflow/core'
- import { DndPanel, Menu, MiniMap, SelectionSelect, Snapshot } from '@logicflow/extension'
- import '@logicflow/core/lib/style/index.css'
- import '@logicflow/extension/lib/style/index.css'
- import { onMounted, ref, watch } from 'vue'
- import Control from '/@/components/gFlow/Control.vue'
- import { setPatternItems, setTheme } from '/@/components/gFlow/config'
- import {
- registerConcurrent,
- registerCondition,
- registerEnd,
- registerPush,
- registerStart,
- registerUserTask,
- registerWebHook,
- } from '/@/components/gFlow/registerNode'
- import PropertyDialog from '/@/components/gFlow/propertySetting/PropertyDialog.vue'
- import DataDialog from '/@/components/gFlow/DataDialog.vue'
- import { useRoute } from 'vue-router'
- import { ElMessage } from 'element-plus'
- import { useI18n } from 'vue-i18n'
- import { getNodeData, saveModeNode } from '/@/api/flow/flowModel'
- import {
- FlowCheckRuleDept,
- FlowCheckRuleDeptLeader,
- FlowCheckRulePost,
- FlowCheckRuleRole,
- FlowCheckRuleUser
- } from '/@/components/gFlow/consts'
- import GraphConfigData = LogicFlow.GraphConfigData
- const route = useRoute()
- const { t,locale } = useI18n()
- const modelId = ref(0)
- const logicFlowContainerRef = ref()
- const lf = ref<LogicFlow>({} as LogicFlow)
- const dataVisible = ref(false)
- const graphData = ref<GraphConfigData>()
- const addPanelStyle = ref({
- top: '0',
- left: '0',
- })
- const showAddPanel = ref(false)
- const addClickNode = ref<any>()
- const clickNode = ref({})
- const dialogVisible = ref(false)
- const moveData = ref({})
- onMounted(() => {
- if (route.query.id) {
- modelId.value = parseInt(route.query.id as string)
- } else {
- ElMessage.error(t('message.flowModel.paramError'))
- return
- }
- lf.value = new LogicFlow({
- container: logicFlowContainerRef.value,
- grid: true,
- plugins: [DndPanel, SelectionSelect, Snapshot, Menu, MiniMap],
- pluginsOptions: {
- miniMap: {
- isShowHeader: false,
- isShowCloseIcon: true,
- headerTitle: t('message.flowModel.miniMap'),
- },
- },
- })
- registerNode()
- initLF()
- })
- //注册节点信息
- const registerNode = () => {
- const logicFlow = lf.value as LogicFlow
- registerStart(logicFlow)
- registerEnd(logicFlow)
- registerConcurrent(logicFlow)
- registerPush(logicFlow)
- registerCondition(logicFlow)
- registerUserTask(logicFlow)
- registerWebHook(logicFlow)
- }
- const initLF = () => {
- const logicFlow = lf.value as LogicFlow
- setPatternItems(logicFlow,t)
- setTheme(logicFlow)
- $_render()
- $_LfEvent()
- }
- watch(locale,()=> {
- setPatternItems(lf.value as LogicFlow,t)
- })
- const $_render = () => {
- //获取节点数据
- getNodeData(modelId.value).then((res: any) => {
- const nodes = (res.nodes ?? []).map((item: any) => {
- const node = {
- id: item.nodeId,
- type: item.nodeType,
- x: item.nodePosition.x,
- y: item.nodePosition.y,
- text: item.nodeText ?? {},
- properties: {
- text: item.nodeText?.value,
- actionRule: item.nodeActionRule,
- approveRule: item.nodeRule,
- notice: item.notice ?? [],
- rollback: item.rollback,
- nodeExt: item.nodeExt ?? [],
- deptProv: item.deptProv ?? 1,
- // WebHook 配置 - 从后端数据构建 webhook 对象
- webhook: JSON.parse(item.ext ?? '{}'),
- // 动态判断配置
- dynamicJudge: JSON.parse(item.ext ?? '{}')?.userId,
- },
- }
- setReceiver(node, item.nodeReceiver)
- return node
- })
- const edges = (res.edges ?? []).map((item: any) => {
- return {
- id: item.id,
- type: item.lineType,
- sourceNodeId: item.sourceNodeId,
- targetNodeId: item.targetNodeId,
- startPoint: item.startPoint,
- endPoint: item.endPoint,
- properties: item.properties,
- pointsList: item.pointsList,
- text: item.text,
- }
- })
- lf.value.render({ nodes, edges })
- $_LfEvent()
- })
- }
- const setReceiver = (node: any, receivers: Array<string>) => {
- switch (node.properties.actionRule) {
- case FlowCheckRuleRole: //角色
- node.properties.roleIds = receivers
- break
- case FlowCheckRuleDept: //部门
- case FlowCheckRuleDeptLeader: //部门负责人
- node.properties.deptIds = receivers
- break
- case FlowCheckRuleUser: //指定人员
- node.properties.userIds = receivers
- break
- case FlowCheckRulePost: //岗位
- node.properties.postIds = receivers
- }
- }
- const $_catData = () => {
- graphData.value = lf.value.getGraphData() as GraphConfigData
- dataVisible.value = true
- }
- const $_saveModel = () => {
- const data = lf.value.getGraphData() as any
- const nodes = data.nodes.map((item: any) => {
- return {
- nodeId: item.id,
- modelId: modelId.value,
- nodeType: item.type,
- nodePosition: { x: item.x, y: item.y },
- nodeText: item.text,
- nodeActionRule: item.properties?.actionRule,
- nodeReceiver: getNodeReceiver(item.properties?.actionRule, item),
- nodeRule: item.properties?.approveRule,
- notice: item.properties?.notice,
- rollback: item.properties?.rollback,
- nodeExt: item.properties?.nodeExt,
- deptProv: item.properties?.deptProv,
- ext: JSON.stringify({
- // WebHook 相关配置 - 整合到 webhook 对象中
- ...item.properties?.webhook,
- userId: item.properties?.dynamicJudge,
- }),
- }
- })
- const edges = data.edges.map((item: any) => {
- return {
- modelId: modelId.value,
- lineType: item.type,
- sourceNodeId: item.sourceNodeId,
- targetNodeId: item.targetNodeId,
- startPoint: item.startPoint,
- endPoint: item.endPoint,
- properties: item.properties,
- text: item.text,
- pointsList: item.pointsList,
- }
- })
- const postData = {
- modelId: modelId.value,
- nodes: nodes,
- edges: edges,
- }
- saveModeNode(postData)
- .then(() => {
- ElMessage.success(t('message.flowModel.saveSuccess'))
- })
- .catch(() => ElMessage.error(t('message.flowModel.exportFailed')))
- }
- const $_LfEvent = () => {
- const logicFlow = lf.value as LogicFlow
- logicFlow.on('node:click', (data) => {
- console.log('node:click', data)
- clickNode.value = data.data
- dialogVisible.value = true
- })
- logicFlow.on('edge:click', ({ data }) => {
- console.log('edge:click', data)
- //this.$data.clickNode = data;
- //this.$data.dialogVisible = true;
- })
- logicFlow.on('element:click', () => {
- hideAddPanel()
- })
- logicFlow.on('edge:add', ({ data }) => {
- console.log('edge:add', data)
- })
- logicFlow.on('node:mousemove', ({ data }) => {
- console.log('node:mousemove')
- moveData.value = data
- })
- logicFlow.on('blank:click', () => {
- hideAddPanel()
- })
- logicFlow.on('connection:not-allowed', (data) => {
- console.log('connection:not-allowed', data)
- })
- logicFlow.on('node:mousemove', () => {
- console.log('on mousemove')
- })
- }
- const hideAddPanel = () => {
- showAddPanel.value = false
- addPanelStyle.value.top = '0'
- addPanelStyle.value.left = '0'
- addClickNode.value = null
- }
- const closeDialog = () => {
- dialogVisible.value = false
- }
- const getNodeReceiver = (rule: number, item: any) => {
- switch (rule) {
- case FlowCheckRuleRole: //角色
- return item.properties.roleIds
- case FlowCheckRuleDept: //部门
- case FlowCheckRuleDeptLeader: //部门负责人
- return item.properties.deptIds
- case FlowCheckRuleUser: //指定人员
- return item.properties.userIds
- case FlowCheckRulePost: //岗位
- return item.properties.postIds
- }
- return []
- }
- </script>
- <style scoped lang="scss">
- .FL-container {
- width: 100%;
- overflow: hidden;
- .app-content {
- height: calc(100vh - 120px);
- }
- }
- .demo-control {
- position: absolute;
- top: 20px;
- right: 50px;
- z-index: 2;
- }
- </style>
|