Pre Merge pull request !624 from Lesan/feature/bpm
commit
a7f29cfcb7
|
|
@ -72,3 +72,10 @@ export const deleteModel = async (id: number) => {
|
||||||
export const deployModel = async (id: number) => {
|
export const deployModel = async (id: number) => {
|
||||||
return await request.post({ url: '/bpm/model/deploy?id=' + id })
|
return await request.post({ url: '/bpm/model/deploy?id=' + id })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const getProcessListByProcessType = async (processType) => {
|
||||||
|
return await request.get({
|
||||||
|
url: '/bpm/model/list-all-simple?processType=' + processType
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
<svg t="1734419297528" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4299" width="200" height="200"><path d="M375.466667 213.333333a85.333333 85.333333 0 1 1-85.333334 85.333334 85.333333 85.333333 0 0 1 85.333334-85.333334m0-85.333333a170.666667 170.666667 0 1 0 170.666666 170.666667 170.666667 170.666667 0 0 0-170.666666-170.666667z" fill="#ffffff" p-id="4300"></path><path d="M716.8 597.333333m-85.333333 0a85.333333 85.333333 0 1 0 170.666666 0 85.333333 85.333333 0 1 0-170.666666 0Z" fill="#ffffff" p-id="4301"></path><path d="M716.8 853.333333m-85.333333 0a85.333333 85.333333 0 1 0 170.666666 0 85.333333 85.333333 0 1 0-170.666666 0Z" fill="#ffffff" p-id="4302"></path><path d="M418.133333 384h-85.333333v426.666667a85.333333 85.333333 0 0 0 85.333333 85.333333V384zM674.133333 554.666667h-256v85.333333h256v-85.333333zM674.133333 810.666667h-256v85.333333h256v-85.333333z" fill="#ffffff" p-id="4303"></path></svg>
|
||||||
|
After Width: | Height: | Size: 971 B |
|
|
@ -39,6 +39,13 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="handler-item-text">包容分支</div>
|
<div class="handler-item-text">包容分支</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- TODO @芋艿:这里需要换一下子流程的图标~ -->
|
||||||
|
<div class="handler-item" @click="addNode(NodeType.CHILD_PROCESS_NODE)">
|
||||||
|
<div class="handler-item-icon copy">
|
||||||
|
<span class="iconfont icon-size icon-copy"></span>
|
||||||
|
</div>
|
||||||
|
<div class="handler-item-text">子流程</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<div class="add-icon"><Icon icon="ep:plus" /></div>
|
<div class="add-icon"><Icon icon="ep:plus" /></div>
|
||||||
|
|
@ -208,6 +215,16 @@ const addNode = (type: number) => {
|
||||||
}
|
}
|
||||||
emits('update:childNode', data)
|
emits('update:childNode', data)
|
||||||
}
|
}
|
||||||
|
if (type === NodeType.CHILD_PROCESS_NODE) {
|
||||||
|
const data: SimpleFlowNode = {
|
||||||
|
id: 'Activity_' + generateUUID(),
|
||||||
|
name: NODE_DEFAULT_NAME.get(NodeType.CHILD_PROCESS_NODE) as string,
|
||||||
|
showText: '',
|
||||||
|
type: NodeType.CHILD_PROCESS_NODE,
|
||||||
|
childNode: props.childNode
|
||||||
|
}
|
||||||
|
emits('update:childNode', data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,12 @@
|
||||||
:flow-node="currentNode"
|
:flow-node="currentNode"
|
||||||
@update:flow-node="handleModelValueUpdate"
|
@update:flow-node="handleModelValueUpdate"
|
||||||
/>
|
/>
|
||||||
|
<!-- 子流程节点 -->
|
||||||
|
<ChildProcessNode
|
||||||
|
v-if="currentNode && currentNode.type === NodeType.CHILD_PROCESS_NODE"
|
||||||
|
:flow-node="currentNode"
|
||||||
|
@update:flow-node="handleModelValueUpdate"
|
||||||
|
/>
|
||||||
<!-- 条件节点 -->
|
<!-- 条件节点 -->
|
||||||
<ExclusiveNode
|
<ExclusiveNode
|
||||||
v-if="currentNode && currentNode.type === NodeType.CONDITION_BRANCH_NODE"
|
v-if="currentNode && currentNode.type === NodeType.CONDITION_BRANCH_NODE"
|
||||||
|
|
@ -57,6 +63,7 @@ import StartUserNode from './nodes/StartUserNode.vue'
|
||||||
import EndEventNode from './nodes/EndEventNode.vue'
|
import EndEventNode from './nodes/EndEventNode.vue'
|
||||||
import UserTaskNode from './nodes/UserTaskNode.vue'
|
import UserTaskNode from './nodes/UserTaskNode.vue'
|
||||||
import CopyTaskNode from './nodes/CopyTaskNode.vue'
|
import CopyTaskNode from './nodes/CopyTaskNode.vue'
|
||||||
|
import ChildProcessNode from './nodes/ChildProcessNode.vue'
|
||||||
import ExclusiveNode from './nodes/ExclusiveNode.vue'
|
import ExclusiveNode from './nodes/ExclusiveNode.vue'
|
||||||
import ParallelNode from './nodes/ParallelNode.vue'
|
import ParallelNode from './nodes/ParallelNode.vue'
|
||||||
import InclusiveNode from './nodes/InclusiveNode.vue'
|
import InclusiveNode from './nodes/InclusiveNode.vue'
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,11 @@ export enum NodeType {
|
||||||
*/
|
*/
|
||||||
COPY_TASK_NODE = 12,
|
COPY_TASK_NODE = 12,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 子流程节点
|
||||||
|
*/
|
||||||
|
CHILD_PROCESS_NODE = 20,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 条件节点
|
* 条件节点
|
||||||
*/
|
*/
|
||||||
|
|
@ -98,6 +103,8 @@ export interface SimpleFlowNode {
|
||||||
defaultFlow?: boolean
|
defaultFlow?: boolean
|
||||||
// 活动的状态,用于前端节点状态展示
|
// 活动的状态,用于前端节点状态展示
|
||||||
activityStatus?: TaskStatusEnum
|
activityStatus?: TaskStatusEnum
|
||||||
|
// 调用子流程
|
||||||
|
childProcess?: ChildProcess
|
||||||
}
|
}
|
||||||
// 候选人策略枚举 ( 用于审批节点。抄送节点 )
|
// 候选人策略枚举 ( 用于审批节点。抄送节点 )
|
||||||
export enum CandidateStrategy {
|
export enum CandidateStrategy {
|
||||||
|
|
@ -413,12 +420,14 @@ NODE_DEFAULT_TEXT.set(NodeType.USER_TASK_NODE, '请配置审批人')
|
||||||
NODE_DEFAULT_TEXT.set(NodeType.COPY_TASK_NODE, '请配置抄送人')
|
NODE_DEFAULT_TEXT.set(NodeType.COPY_TASK_NODE, '请配置抄送人')
|
||||||
NODE_DEFAULT_TEXT.set(NodeType.CONDITION_NODE, '请设置条件')
|
NODE_DEFAULT_TEXT.set(NodeType.CONDITION_NODE, '请设置条件')
|
||||||
NODE_DEFAULT_TEXT.set(NodeType.START_USER_NODE, '请设置发起人')
|
NODE_DEFAULT_TEXT.set(NodeType.START_USER_NODE, '请设置发起人')
|
||||||
|
NODE_DEFAULT_TEXT.set(NodeType.CHILD_PROCESS_NODE, '请设置子流程')
|
||||||
|
|
||||||
export const NODE_DEFAULT_NAME = new Map<number, string>()
|
export const NODE_DEFAULT_NAME = new Map<number, string>()
|
||||||
NODE_DEFAULT_NAME.set(NodeType.USER_TASK_NODE, '审批人')
|
NODE_DEFAULT_NAME.set(NodeType.USER_TASK_NODE, '审批人')
|
||||||
NODE_DEFAULT_NAME.set(NodeType.COPY_TASK_NODE, '抄送人')
|
NODE_DEFAULT_NAME.set(NodeType.COPY_TASK_NODE, '抄送人')
|
||||||
NODE_DEFAULT_NAME.set(NodeType.CONDITION_NODE, '条件')
|
NODE_DEFAULT_NAME.set(NodeType.CONDITION_NODE, '条件')
|
||||||
NODE_DEFAULT_NAME.set(NodeType.START_USER_NODE, '发起人')
|
NODE_DEFAULT_NAME.set(NodeType.START_USER_NODE, '发起人')
|
||||||
|
NODE_DEFAULT_NAME.set(NodeType.CHILD_PROCESS_NODE, '子流程')
|
||||||
|
|
||||||
// 候选人策略。暂时不从字典中取。 后续可能调整。控制显示顺序
|
// 候选人策略。暂时不从字典中取。 后续可能调整。控制显示顺序
|
||||||
export const CANDIDATE_STRATEGY: DictDataVO[] = [
|
export const CANDIDATE_STRATEGY: DictDataVO[] = [
|
||||||
|
|
@ -568,3 +577,26 @@ export enum ProcessVariableEnum {
|
||||||
*/
|
*/
|
||||||
START_USER_ID = 'PROCESS_START_USER_ID'
|
START_USER_ID = 'PROCESS_START_USER_ID'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程类型枚举
|
||||||
|
*/
|
||||||
|
export enum ProcessTypeEnum {
|
||||||
|
/**
|
||||||
|
* 主流程
|
||||||
|
*/
|
||||||
|
MAIN = 1,
|
||||||
|
/**
|
||||||
|
* 子流程
|
||||||
|
*/
|
||||||
|
CHILD = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 子流程结构定义
|
||||||
|
*/
|
||||||
|
export type ChildProcess = {
|
||||||
|
processKey: string
|
||||||
|
processName: string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,202 @@
|
||||||
|
<template>
|
||||||
|
<el-drawer
|
||||||
|
:append-to-body="true"
|
||||||
|
v-model="settingVisible"
|
||||||
|
:show-close="false"
|
||||||
|
:size="550"
|
||||||
|
:before-close="saveConfig"
|
||||||
|
>
|
||||||
|
<template #header>
|
||||||
|
<div class="config-header">
|
||||||
|
<input
|
||||||
|
v-if="showInput"
|
||||||
|
type="text"
|
||||||
|
class="config-editable-input"
|
||||||
|
@blur="blurEvent()"
|
||||||
|
v-mountedFocus
|
||||||
|
v-model="nodeName"
|
||||||
|
:placeholder="nodeName"
|
||||||
|
/>
|
||||||
|
<div v-else class="node-name">
|
||||||
|
{{ nodeName }} <Icon class="ml-1" icon="ep:edit-pen" :size="16" @click="clickIcon()" />
|
||||||
|
</div>
|
||||||
|
<div class="divide-line"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-tabs type="border-card" v-model="activeTabName">
|
||||||
|
<el-tab-pane label="子流程" name="child">
|
||||||
|
<div>
|
||||||
|
<el-form ref="formRef" :model="configForm" label-position="top" :rules="formRules">
|
||||||
|
<el-form-item label="选择子流程" prop="childProcessKey">
|
||||||
|
<el-select v-model="configForm.childProcessKey" clearable>
|
||||||
|
<el-option
|
||||||
|
v-for="(item, index) in childProcessOptions"
|
||||||
|
:key="index"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.key"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否多实例" prop="multiInstance">
|
||||||
|
<el-radio-group v-model="configForm.multiInstance">
|
||||||
|
<el-radio :value="true" :label="true">是</el-radio>
|
||||||
|
<el-radio :value="false" :label="false">否</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="多人审批方式" prop="approveMethod" v-if="configForm.multiInstance">
|
||||||
|
<el-radio-group v-model="configForm.approveMethod">
|
||||||
|
<div class="flex-col">
|
||||||
|
<div
|
||||||
|
v-for="(item, index) in APPROVE_METHODS"
|
||||||
|
:key="index"
|
||||||
|
class="flex items-center"
|
||||||
|
>
|
||||||
|
<el-radio :value="item.value" :label="item.value">
|
||||||
|
{{ item.label }}
|
||||||
|
</el-radio>
|
||||||
|
<el-form-item prop="approveRatio">
|
||||||
|
<el-input-number
|
||||||
|
v-model="configForm.approveRatio"
|
||||||
|
:min="10"
|
||||||
|
:max="100"
|
||||||
|
:step="10"
|
||||||
|
size="small"
|
||||||
|
v-if="
|
||||||
|
item.value === ApproveMethodType.APPROVE_BY_RATIO &&
|
||||||
|
configForm.approveMethod === ApproveMethodType.APPROVE_BY_RATIO
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
label="多实例来源"
|
||||||
|
prop="multiInstanceSource"
|
||||||
|
v-if="configForm.multiInstance"
|
||||||
|
>
|
||||||
|
<el-input
|
||||||
|
type="textarea"
|
||||||
|
v-model="configForm.multiInstanceSource"
|
||||||
|
clearable
|
||||||
|
style="width: 100%"
|
||||||
|
placeholder="请输入多实例来源(目前仅支持流程表达式!)"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<template #footer>
|
||||||
|
<el-divider />
|
||||||
|
<div>
|
||||||
|
<el-button type="primary" @click="saveConfig">确 定</el-button>
|
||||||
|
<el-button @click="closeDrawer">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { getProcessListByProcessType } from '@/api/bpm/model'
|
||||||
|
import {
|
||||||
|
SimpleFlowNode,
|
||||||
|
NodeType,
|
||||||
|
APPROVE_METHODS,
|
||||||
|
ApproveMethodType,
|
||||||
|
CandidateStrategy,
|
||||||
|
ProcessTypeEnum
|
||||||
|
} from '../consts'
|
||||||
|
import { useWatchNode, useDrawer, useNodeName } from '../node'
|
||||||
|
defineOptions({
|
||||||
|
name: 'ChildProcessNodeConfig'
|
||||||
|
})
|
||||||
|
const props = defineProps({
|
||||||
|
flowNode: {
|
||||||
|
type: Object as () => SimpleFlowNode,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 抽屉配置
|
||||||
|
const { settingVisible, closeDrawer, openDrawer } = useDrawer()
|
||||||
|
// 当前节点
|
||||||
|
const currentNode = useWatchNode(props)
|
||||||
|
// 节点名称
|
||||||
|
const { nodeName, showInput, clickIcon, blurEvent } = useNodeName(NodeType.CHILD_PROCESS_NODE)
|
||||||
|
// 激活的 Tab 标签页
|
||||||
|
const activeTabName = ref('child')
|
||||||
|
// 子流程表单配置
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
// 表单校验规则
|
||||||
|
const formRules = reactive({
|
||||||
|
childProcessKey: [{ required: true, message: '子流程不能为空', trigger: 'change' }],
|
||||||
|
multiInstance: [{ required: true, message: '是否多实例不能为空', trigger: 'change' }],
|
||||||
|
approveMethod: [{ required: true, message: '多人审批方式不能为空', trigger: 'change' }],
|
||||||
|
approveRatio: [{ required: true, message: '通过比例不能为空', trigger: 'change' }],
|
||||||
|
multiInstanceSource: [{ required: true, message: '多实例来源不能为空', trigger: 'blur' }]
|
||||||
|
})
|
||||||
|
const configForm = ref({
|
||||||
|
childProcessKey: '',
|
||||||
|
multiInstance: false,
|
||||||
|
approveMethod: ApproveMethodType.SEQUENTIAL_APPROVE,
|
||||||
|
approveRatio: 100,
|
||||||
|
multiInstanceSource: ''
|
||||||
|
})
|
||||||
|
const childProcessOptions = ref()
|
||||||
|
|
||||||
|
// 保存配置
|
||||||
|
const saveConfig = async () => {
|
||||||
|
activeTabName.value = 'child'
|
||||||
|
if (!formRef) return false
|
||||||
|
const valid = await formRef.value.validate()
|
||||||
|
if (!valid) return false
|
||||||
|
const childInfo = childProcessOptions.value.find(
|
||||||
|
(option) => option.key === configForm.value.childProcessKey
|
||||||
|
)
|
||||||
|
currentNode.value.name = nodeName.value!
|
||||||
|
currentNode.value.childProcess = {
|
||||||
|
processKey: childInfo.key,
|
||||||
|
processName: childInfo.name
|
||||||
|
}
|
||||||
|
currentNode.value.showText = `调用子流程:${childInfo.name}`
|
||||||
|
if (configForm.value.multiInstance) {
|
||||||
|
currentNode.value.candidateStrategy = CandidateStrategy.EXPRESSION
|
||||||
|
currentNode.value.candidateParam = configForm.value.multiInstanceSource
|
||||||
|
currentNode.value.approveMethod = configForm.value.approveMethod
|
||||||
|
if (configForm.value.approveMethod === ApproveMethodType.APPROVE_BY_RATIO) {
|
||||||
|
currentNode.value.approveRatio = configForm.value.approveRatio
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentNode.value.candidateStrategy = undefined
|
||||||
|
currentNode.value.candidateParam = undefined
|
||||||
|
currentNode.value.approveMethod = undefined
|
||||||
|
currentNode.value.approveRatio = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
settingVisible.value = false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// 显示子流程节点配置, 由父组件传过来
|
||||||
|
const showChildProcessNodeConfig = (node: SimpleFlowNode) => {
|
||||||
|
nodeName.value = node.name
|
||||||
|
if (node.childProcess) {
|
||||||
|
configForm.value.childProcessKey = node.childProcess.processKey
|
||||||
|
}
|
||||||
|
if (node.candidateStrategy) {
|
||||||
|
configForm.value.multiInstance = true
|
||||||
|
configForm.value.multiInstanceSource = node.candidateParam
|
||||||
|
configForm.value.approveMethod = node.approveMethod
|
||||||
|
if (node.approveMethod === ApproveMethodType.APPROVE_BY_RATIO) {
|
||||||
|
configForm.value.approveRatio = node.approveRatio
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ openDrawer, showChildProcessNodeConfig }) // 暴露方法给父组件
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
childProcessOptions.value = await getProcessListByProcessType(ProcessTypeEnum.CHILD)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
<template>
|
||||||
|
<div class="node-wrapper">
|
||||||
|
<div class="node-container">
|
||||||
|
<div
|
||||||
|
class="node-box"
|
||||||
|
:class="[
|
||||||
|
{ 'node-config-error': !currentNode.showText },
|
||||||
|
`${useTaskStatusClass(currentNode?.activityStatus)}`
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div class="node-title-container">
|
||||||
|
<div class="node-title-icon copy-task"><span class="iconfont icon-copy"></span></div>
|
||||||
|
<input
|
||||||
|
v-if="!readonly && showInput"
|
||||||
|
type="text"
|
||||||
|
class="editable-title-input"
|
||||||
|
@blur="blurEvent()"
|
||||||
|
v-mountedFocus
|
||||||
|
v-model="currentNode.name"
|
||||||
|
:placeholder="currentNode.name"
|
||||||
|
/>
|
||||||
|
<div v-else class="node-title" @click="clickTitle">
|
||||||
|
{{ currentNode.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="node-content" @click="openNodeConfig">
|
||||||
|
<div class="node-text" :title="currentNode.showText" v-if="currentNode.showText">
|
||||||
|
{{ currentNode.showText }}
|
||||||
|
</div>
|
||||||
|
<div class="node-text" v-else>
|
||||||
|
{{ NODE_DEFAULT_TEXT.get(NodeType.CHILD_PROCESS_NODE) }}
|
||||||
|
</div>
|
||||||
|
<Icon v-if="!readonly" icon="ep:arrow-right-bold" />
|
||||||
|
</div>
|
||||||
|
<div v-if="!readonly" class="node-toolbar">
|
||||||
|
<div class="toolbar-icon"
|
||||||
|
><Icon color="#0089ff" icon="ep:circle-close-filled" :size="18" @click="deleteNode"
|
||||||
|
/></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 传递子节点给添加节点组件。会在子节点前面添加节点 -->
|
||||||
|
<NodeHandler
|
||||||
|
v-if="currentNode"
|
||||||
|
v-model:child-node="currentNode.childNode"
|
||||||
|
:current-node="currentNode"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<ChildProcessNodeConfig
|
||||||
|
v-if="!readonly && currentNode"
|
||||||
|
ref="nodeSetting"
|
||||||
|
:flow-node="currentNode"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { SimpleFlowNode, NodeType, NODE_DEFAULT_TEXT } from '../consts'
|
||||||
|
import NodeHandler from '../NodeHandler.vue'
|
||||||
|
import { useNodeName2, useWatchNode, useTaskStatusClass } from '../node'
|
||||||
|
import ChildProcessNodeConfig from '../nodes-config/ChildProcessNodeConfig.vue'
|
||||||
|
defineOptions({
|
||||||
|
name: 'ChildProcessNode'
|
||||||
|
})
|
||||||
|
const props = defineProps({
|
||||||
|
flowNode: {
|
||||||
|
type: Object as () => SimpleFlowNode,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 定义事件,更新父组件。
|
||||||
|
const emits = defineEmits<{
|
||||||
|
'update:flowNode': [node: SimpleFlowNode | undefined]
|
||||||
|
}>()
|
||||||
|
// 是否只读
|
||||||
|
const readonly = inject<Boolean>('readonly')
|
||||||
|
// 监控节点的变化
|
||||||
|
const currentNode = useWatchNode(props)
|
||||||
|
// 节点名称编辑
|
||||||
|
const { showInput, blurEvent, clickTitle } = useNodeName2(currentNode, NodeType.CHILD_PROCESS_NODE)
|
||||||
|
const nodeSetting = ref()
|
||||||
|
// 打开节点配置
|
||||||
|
const openNodeConfig = () => {
|
||||||
|
if (readonly) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
nodeSetting.value.showChildProcessNodeConfig(currentNode.value)
|
||||||
|
nodeSetting.value.openDrawer()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除节点。更新当前节点为孩子节点
|
||||||
|
const deleteNode = () => {
|
||||||
|
emits('update:flowNode', currentNode.value.childNode)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
|
|
@ -690,10 +690,22 @@ const processSave = async () => {
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
console.log(props, 'propspropspropsprops')
|
console.log(props, 'propspropspropsprops')
|
||||||
})
|
})
|
||||||
onMounted(() => {
|
watch(
|
||||||
|
() => props.value,
|
||||||
|
(val) => {
|
||||||
|
val &&
|
||||||
|
val.length &&
|
||||||
|
nextTick(() => {
|
||||||
initBpmnModeler()
|
initBpmnModeler()
|
||||||
createNewDiagram(props.value)
|
createNewDiagram(props.value)
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
// onMounted(() => {
|
||||||
|
// initBpmnModeler()
|
||||||
|
// createNewDiagram(props.value)
|
||||||
|
// })
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
// this.$once('hook:beforeDestroy', () => {
|
// this.$once('hook:beforeDestroy', () => {
|
||||||
// })
|
// })
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,7 @@ export enum DICT_TYPE {
|
||||||
|
|
||||||
// ========== BPM 模块 ==========
|
// ========== BPM 模块 ==========
|
||||||
BPM_MODEL_TYPE = 'bpm_model_type',
|
BPM_MODEL_TYPE = 'bpm_model_type',
|
||||||
|
BPM_PROCESS_TYPE = 'bpm_process_type',
|
||||||
BPM_MODEL_FORM_TYPE = 'bpm_model_form_type',
|
BPM_MODEL_FORM_TYPE = 'bpm_model_form_type',
|
||||||
BPM_TASK_CANDIDATE_STRATEGY = 'bpm_task_candidate_strategy',
|
BPM_TASK_CANDIDATE_STRATEGY = 'bpm_task_candidate_strategy',
|
||||||
BPM_PROCESS_INSTANCE_STATUS = 'bpm_process_instance_status',
|
BPM_PROCESS_INSTANCE_STATUS = 'bpm_process_instance_status',
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,19 @@ const setSimpleModelNodeTaskStatus = (
|
||||||
simpleModel.activityStatus = TaskStatusEnum.NOT_START
|
simpleModel.activityStatus = TaskStatusEnum.NOT_START
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 子流程节点
|
||||||
|
if (simpleModel.type === NodeType.CHILD_PROCESS_NODE) {
|
||||||
|
simpleModel.activityStatus = TaskStatusEnum.NOT_START
|
||||||
|
if (rejectedTaskActivityIds.includes(simpleModel.id)) {
|
||||||
|
simpleModel.activityStatus = TaskStatusEnum.REJECT
|
||||||
|
} else if (unfinishedTaskActivityIds.includes(simpleModel.id)) {
|
||||||
|
simpleModel.activityStatus = TaskStatusEnum.RUNNING
|
||||||
|
} else if (finishedActivityIds.includes(simpleModel.id)) {
|
||||||
|
simpleModel.activityStatus = TaskStatusEnum.APPROVE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 条件节点 对应 SequenceFlow
|
// 条件节点 对应 SequenceFlow
|
||||||
if (simpleModel.type === NodeType.CONDITION_NODE) {
|
if (simpleModel.type === NodeType.CONDITION_NODE) {
|
||||||
// 条件节点。只有通过和未执行状态
|
// 条件节点。只有通过和未执行状态
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,7 @@ import copySvg from '@/assets/svgs/bpm/copy.svg'
|
||||||
import conditionSvg from '@/assets/svgs/bpm/condition.svg'
|
import conditionSvg from '@/assets/svgs/bpm/condition.svg'
|
||||||
import parallelSvg from '@/assets/svgs/bpm/parallel.svg'
|
import parallelSvg from '@/assets/svgs/bpm/parallel.svg'
|
||||||
import finishSvg from '@/assets/svgs/bpm/finish.svg'
|
import finishSvg from '@/assets/svgs/bpm/finish.svg'
|
||||||
|
import childProcessSvg from '@/assets/svgs/bpm/childProcess.svg'
|
||||||
|
|
||||||
defineOptions({ name: 'BpmProcessInstanceTimeline' })
|
defineOptions({ name: 'BpmProcessInstanceTimeline' })
|
||||||
withDefaults(
|
withDefaults(
|
||||||
|
|
@ -234,7 +235,9 @@ const nodeTypeSvgMap = {
|
||||||
// 条件分支节点
|
// 条件分支节点
|
||||||
[NodeType.CONDITION_NODE]: { color: '#14bb83', svg: conditionSvg },
|
[NodeType.CONDITION_NODE]: { color: '#14bb83', svg: conditionSvg },
|
||||||
// 并行分支节点
|
// 并行分支节点
|
||||||
[NodeType.PARALLEL_BRANCH_NODE]: { color: '#14bb83', svg: parallelSvg }
|
[NodeType.PARALLEL_BRANCH_NODE]: { color: '#14bb83', svg: parallelSvg },
|
||||||
|
// 子流程节点
|
||||||
|
[NodeType.CHILD_PROCESS_NODE]: { color: '#3296fb', svg: childProcessSvg }
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只有只有状态是 -1、0、1 才展示头像右小角状态小icon
|
// 只有只有状态是 -1、0、1 才展示头像右小角状态小icon
|
||||||
|
|
@ -253,7 +256,8 @@ const getApprovalNodeIcon = (taskStatus: number, nodeType: NodeType) => {
|
||||||
if (
|
if (
|
||||||
nodeType === NodeType.START_USER_NODE ||
|
nodeType === NodeType.START_USER_NODE ||
|
||||||
nodeType === NodeType.USER_TASK_NODE ||
|
nodeType === NodeType.USER_TASK_NODE ||
|
||||||
nodeType === NodeType.END_EVENT_NODE
|
nodeType === NodeType.END_EVENT_NODE ||
|
||||||
|
nodeType === NodeType.CHILD_PROCESS_NODE
|
||||||
) {
|
) {
|
||||||
return statusIconMap[taskStatus]?.icon
|
return statusIconMap[taskStatus]?.icon
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue