diff --git a/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue b/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue index d11e67cc..440e574a 100644 --- a/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue +++ b/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue @@ -50,6 +50,7 @@ import CopyTaskNode from './nodes/CopyTaskNode.vue' import ExclusiveNode from './nodes/ExclusiveNode.vue' import ParallelNode from './nodes/ParallelNode.vue' import { SimpleFlowNode, NodeType } from './consts' +import { useWatchNode } from './node' defineOptions({ name: 'ProcessNodeTree' }) @@ -72,15 +73,8 @@ const emits = defineEmits<{ ] }>() -const currentNode = ref(props.flowNode) +const currentNode = useWatchNode(props) -// 重要:监控节点变化. 重新绘制节点 -watch( - () => props.flowNode, - (newValue) => { - currentNode.value = newValue - } -) // 用于删除节点 const handleModelValueUpdate = (updateValue) => { emits('update:flowNode', updateValue) diff --git a/src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue b/src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue index b26c2fea..60369120 100644 --- a/src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue +++ b/src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue @@ -138,6 +138,7 @@ const zoomIn = () => { onMounted(async () => { const result = await getBpmSimpleModel(props.modelId) + console.log('the result is :', result) if (result) { processNodeTree.value = result } else { diff --git a/src/components/SimpleProcessDesignerV2/src/consts.ts b/src/components/SimpleProcessDesignerV2/src/consts.ts index 4525ce67..70188590 100644 --- a/src/components/SimpleProcessDesignerV2/src/consts.ts +++ b/src/components/SimpleProcessDesignerV2/src/consts.ts @@ -1,6 +1,8 @@ // @ts-ignore import { DictDataVO } from '@/api/system/dict/types' - +/** + * 节点类型 + */ export enum NodeType { /** * 发起人节点 @@ -46,68 +48,37 @@ export enum NodeType { */ INCLUSIVE_NODE_JOIN = 8 } -// 时间单位枚举 -export enum TimeUnitType { - /** - * 分钟 - */ - MINUTE = 1, - /** - * 小时 - */ - HOUR = 2, - /** - * 天 - */ - DAY = 3 +/** + * 节点结构定义 + */ +export interface SimpleFlowNode { + id: string + type: NodeType + name: string + showText?: string + attributes?: any + // 孩子节点 + childNode?: SimpleFlowNode + // 条件节点 + conditionNodes?: SimpleFlowNode[] + // 候选人策略 + candidateStrategy?: number + // 候选人参数 + candidateParam?: string + // 多人审批方式 + approveMethod?: ApproveMethodType + //通过比例 + approveRatio?: number + // 审批按钮设置 + buttonsSetting?: any[] + // 表单权限 + fieldsPermission?: Array> + // 审批任务超时处理 + timeoutHandler?: TimeoutHandler + // 审批任务拒绝处理 + rejectHandler?: RejectHandler } - -export enum RejectHandlerType { - /** - * 结束流程 - */ - FINISH_PROCESS = 1, - /** - * 驳回到指定节点 - */ - RETURN_USER_TASK = 2 -} - -// 条件配置类型 ( 用于条件节点配置 ) -export enum ConditionConfigType { - /** - * 条件表达式 - */ - EXPRESSION = 1, - - /** - * 条件规则 - */ - RULE = 2 -} -// 多人审批方式类型 ( 用于审批节点 ) -export enum ApproveMethodType { - /** - * 随机挑选一人审批 - */ - RRANDOM_SELECT_ONE_APPROVE = 1, - - /** - * 多人会签(按通过比例) - */ - APPROVE_BY_RATIO = 2, - - /** - * 多人或签(通过只需一人,拒绝只需一人) - */ - ANY_APPROVE = 3, - /** - * 多人依次审批 - */ - SEQUENTIAL_APPROVE = 4 -} - -// 候选人策略 ( 用于审批节点。抄送节点 ) +// 候选人策略枚举 ( 用于审批节点。抄送节点 ) export enum CandidateStrategy { /** * 指定角色 @@ -147,12 +118,41 @@ export enum CandidateStrategy { EXPRESSION = 60 } -export type RejectHandler = { - type: RejectHandlerType +// 多人审批方式类型枚举 ( 用于审批节点 ) +export enum ApproveMethodType { + /** + * 随机挑选一人审批 + */ + RRANDOM_SELECT_ONE_APPROVE = 1, + /** + * 多人会签(按通过比例) + */ + APPROVE_BY_RATIO = 2, + + /** + * 多人或签(通过只需一人,拒绝只需一人) + */ + ANY_APPROVE = 3, + /** + * 多人依次审批 + */ + SEQUENTIAL_APPROVE = 4 +} + +/** + * 审批拒绝结构定义 + */ +export type RejectHandler = { + // 审批拒绝类型 + type: RejectHandlerType + // 回退节点 Id returnNodeId?: string } +/** + * 审批超时结构定义 + */ export type TimeoutHandler = { //是否开启超时处理 enable: boolean @@ -163,60 +163,57 @@ export type TimeoutHandler = { // 执行动作是自动提醒, 最大提醒次数 maxRemindCount?: number } - -export type SimpleFlowNode = { - id: string - type: NodeType - name: string - showText?: string - attributes?: any - // 孩子节点 - childNode?: SimpleFlowNode - // 条件节点 - conditionNodes?: SimpleFlowNode[] - // 候选人策略 - candidateStrategy?: number - // 候选人参数 - candidateParam?: string - // 多人审批方式 - approveMethod?: ApproveMethodType - //通过比例 - approveRatio?: number - // 审批按钮设置 - buttonsSetting?: any[] - // 表单权限 - fieldsPermission?: any[] - // 审批任务超时处理 - timeoutHandler?: TimeoutHandler - // 审批任务拒绝处理 - rejectHandler?: RejectHandler +// 审批拒绝类型枚举 +export enum RejectHandlerType { + /** + * 结束流程 + */ + FINISH_PROCESS = 1, + /** + * 驳回到指定节点 + */ + RETURN_USER_TASK = 2 } -// 条件组 -export type ConditionGroup = { - // 条件组的逻辑关系是否为且 - and: boolean - // 条件数组 - conditions: Condition[] +// 时间单位枚举 +export enum TimeUnitType { + /** + * 分钟 + */ + MINUTE = 1, + /** + * 小时 + */ + HOUR = 2, + /** + * 天 + */ + DAY = 3 } -// 条件 -export type Condition = { - // 条件规则的逻辑关系是否为且 - and: boolean - rules: ConditionRule[] +// 条件配置类型 ( 用于条件节点配置 ) +export enum ConditionConfigType { + /** + * 条件表达式 + */ + EXPRESSION = 1, + + /** + * 条件规则 + */ + RULE = 2 } -// 条件规则 -export type ConditionRule = { - type: number - opName: string - opCode: string - leftSide: string - rightSide: string +/** + * 操作按钮权限结构定义 + */ +export type ButtonSetting = { + id: OpsButtonType + displayName: string + enable: boolean } -// 审批操作按钮类型 +// 操作按钮类型枚举 (用于审批节点) export enum OpsButtonType { /** * 通过 @@ -243,11 +240,34 @@ export enum OpsButtonType { */ RETURN = 6 } +/** + * 条件规则结构定义 + */ +export type ConditionRule = { + type: number + opName: string + opCode: string + leftSide: string + rightSide: string +} -export type ButtonSetting = { - id: OpsButtonType - displayName: string - enable: boolean +/** + * 条件组结构定义 + */ +export type ConditionGroup = { + // 条件组的逻辑关系是否为且 + and: boolean + // 条件数组 + conditions: Condition[] +} + +/** + * 条件结构定义 + */ +export type Condition = { + // 条件规则的逻辑关系是否为且 + and: boolean + rules: ConditionRule[] } export const NODE_DEFAULT_TEXT = new Map() diff --git a/src/components/SimpleProcessDesignerV2/src/node.ts b/src/components/SimpleProcessDesignerV2/src/node.ts new file mode 100644 index 00000000..a2c47b1e --- /dev/null +++ b/src/components/SimpleProcessDesignerV2/src/node.ts @@ -0,0 +1,260 @@ +import { cloneDeep } from 'lodash-es' +import * as RoleApi from '@/api/system/role' +import * as DeptApi from '@/api/system/dept' +import * as PostApi from '@/api/system/post' +import * as UserApi from '@/api/system/user' +import * as UserGroupApi from '@/api/bpm/userGroup' +import { + SimpleFlowNode, + CandidateStrategy, + NodeType, + ApproveMethodType, + RejectHandlerType, + NODE_DEFAULT_NAME +} from './consts' +export function useWatchNode(props: { flowNode: SimpleFlowNode }): Ref { + const node = ref(props.flowNode) + watch( + () => props.flowNode, + (newValue) => { + node.value = newValue + } + ) + return node +} + +/** + * @description 表单数据权限配置,用于审批节点、抄送节点 + */ +export function useFormFieldsPermission() { + // 字段权限配置. 需要有 field, title, permissioin 属性 + const fieldsPermissionConfig = ref>>([]) + + const formType = inject>('formType') // 表单类型 + + const formFields = inject>('formFields') // 流程表单字段 + + const getNodeConfigFormFields = (nodeFormFields?: Array>) => { + nodeFormFields = toRaw(nodeFormFields) + fieldsPermissionConfig.value = + cloneDeep(nodeFormFields) || getDefaultFieldsPermission(unref(formFields)) + } + // 获取默认的表单权限。 所有字段只读 + const getDefaultFieldsPermission = (formFields?: string[]) => { + const defaultFieldsPermission: Array> = [] + if (formFields) { + formFields.forEach((fieldStr: string) => { + const { field, title } = JSON.parse(fieldStr) + defaultFieldsPermission.push({ + field, + title, + permission: '1' // 只读 + }) + }) + } + return defaultFieldsPermission + } + + return { + formType, + fieldsPermissionConfig, + getNodeConfigFormFields + } +} + +export type UserTaskFormType = { + candidateParamArray: any[] + candidateStrategy: CandidateStrategy + approveMethod: ApproveMethodType + approveRatio?: number + rejectHandlerType?: RejectHandlerType + returnNodeId?: string + timeoutHandlerEnable?: boolean + timeoutHandlerAction?: number + timeDuration?: number + maxRemindCount?: number + buttonsSetting: any[] +} + +export type CopyTaskFormType = { + candidateParamArray: any[] + candidateStrategy: CandidateStrategy +} + +/** + * @description 节点表单数据。 用于审批节点、抄送节点 + */ +export function useNodeForm(nodeType: NodeType) { + const roleOptions = inject>('roleList') // 角色列表 + const postOptions = inject>('postList') // 岗位列表 + const userOptions = inject>('userList') // 用户列表 + const deptOptions = inject>('deptList') // 部门列表 + const userGroupOptions = inject>('userGroupList') // 用户组列表 + const deptTreeOptions = inject('deptTree') // 部门树 + const configForm = ref() + if (nodeType === NodeType.USER_TASK_NODE) { + configForm.value = { + candidateParamArray: [], + candidateStrategy: CandidateStrategy.USER, + approveMethod: ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE, + approveRatio: 100, + rejectHandlerType: RejectHandlerType.FINISH_PROCESS, + returnNodeId: '', + timeoutHandlerEnable: false, + timeoutHandlerAction: 1, + timeDuration: 6, // 默认 6小时 + maxRemindCount: 1, // 默认 提醒 1次 + buttonsSetting: [] + } + } else { + configForm.value = { + candidateParamArray: [], + candidateStrategy: CandidateStrategy.USER + } + } + + const getShowText = (): string => { + let showText = '' + // 指定成员 + if (configForm.value?.candidateStrategy === CandidateStrategy.USER) { + if (configForm.value.candidateParamArray?.length > 0) { + const candidateNames: string[] = [] + userOptions?.value.forEach((item) => { + if (configForm.value?.candidateParamArray.includes(item.id)) { + candidateNames.push(item.nickname) + } + }) + showText = `指定成员:${candidateNames.join(',')}` + } + } + // 指定角色 + if (configForm.value?.candidateStrategy === CandidateStrategy.ROLE) { + if (configForm.value.candidateParamArray?.length > 0) { + const candidateNames: string[] = [] + roleOptions?.value.forEach((item) => { + if (configForm.value?.candidateParamArray.includes(item.id)) { + candidateNames.push(item.name) + } + }) + showText = `指定角色:${candidateNames.join(',')}` + } + } + // 指定部门 + if ( + configForm.value?.candidateStrategy === CandidateStrategy.DEPT_MEMBER || + configForm.value?.candidateStrategy === CandidateStrategy.DEPT_LEADER + ) { + if (configForm.value?.candidateParamArray?.length > 0) { + const candidateNames: string[] = [] + deptOptions?.value.forEach((item) => { + if (configForm.value?.candidateParamArray.includes(item.id)) { + candidateNames.push(item.name) + } + }) + if (configForm.value.candidateStrategy === CandidateStrategy.DEPT_MEMBER) { + showText = `部门成员:${candidateNames.join(',')}` + } else { + showText = `部门的负责人:${candidateNames.join(',')}` + } + } + } + + // 指定岗位 + if (configForm.value?.candidateStrategy === CandidateStrategy.POST) { + if (configForm.value.candidateParamArray?.length > 0) { + const candidateNames: string[] = [] + postOptions?.value.forEach((item) => { + if (configForm.value?.candidateParamArray.includes(item.id)) { + candidateNames.push(item.name) + } + }) + showText = `指定岗位: ${candidateNames.join(',')}` + } + } + // 指定用户组 + if (configForm.value?.candidateStrategy === CandidateStrategy.USER_GROUP) { + if (configForm.value?.candidateParamArray?.length > 0) { + const candidateNames: string[] = [] + userGroupOptions?.value.forEach((item) => { + if (configForm.value?.candidateParamArray.includes(item.id)) { + candidateNames.push(item.name) + } + }) + showText = `指定用户组: ${candidateNames.join(',')}` + } + } + + // 发起人自选 + if (configForm.value?.candidateStrategy === CandidateStrategy.START_USER_SELECT) { + showText = `发起人自选` + } + // 发起人自己 + if (configForm.value?.candidateStrategy === CandidateStrategy.START_USER) { + showText = `发起人自己` + } + + // 流程表达式 + if (configForm.value?.candidateStrategy === CandidateStrategy.EXPRESSION) { + if (configForm.value.candidateParamArray?.length > 0) { + showText = `流程表达式:${configForm.value.candidateParamArray[0]}` + } + } + return showText + } + + return { + configForm, + roleOptions, + postOptions, + userOptions, + userGroupOptions, + deptTreeOptions, + getShowText + } +} + +/** + * @description 抽屉配置 + */ +export function useDrawer() { + // 抽屉配置是否可见 + const settingVisible = ref(false) + // 关闭配置抽屉 + const closeDrawer = () => { + settingVisible.value = false + } + // 打开配置抽屉 + const openDrawer = () => { + settingVisible.value = true + } + return { + settingVisible, + closeDrawer, + openDrawer + } +} + +/** + * @description 节点名称配置 + */ +export function useNodeName(nodeType: NodeType) { + // 节点名称 + const nodeName = ref() + // 节点名称输入框 + const showInput = ref(false) + // 点击节点名称编辑图标 + const clickIcon = () => { + showInput.value = true + } + // 节点名称输入框失去焦点 + const blurEvent = () => { + showInput.value = false + nodeName.value = nodeName.value || (NODE_DEFAULT_NAME.get(nodeType) as string) + } + return { + nodeName, + showInput, + clickIcon, + blurEvent + } +} diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue index b1ee7e1f..807f08b5 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue @@ -14,14 +14,12 @@ class="config-editable-input" @blur="blurEvent()" v-mountedFocus - v-model="configForm.name" - :placeholder="configForm.name" + v-model="nodeName" + :placeholder="nodeName" /> -
{{ configForm.name }} -
- +
+ {{ nodeName }} +
@@ -173,7 +171,7 @@
{{ item.title }}
@@ -202,16 +200,17 @@ diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue index cb55341e..75af7ba7 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue @@ -15,14 +15,12 @@ class="config-editable-input" @blur="blurEvent()" v-mountedFocus - v-model="configForm.name" - :placeholder="configForm.name" + v-model="nodeName" + :placeholder="nodeName" /> -
{{ configForm.name }} -
- +
+ {{ nodeName }} +
@@ -280,7 +278,7 @@ - +
操作按钮
@@ -288,11 +286,7 @@
显示名称
启用
-
+
{{ OPERATION_BUTTON_NAME.get(item.id) }}
{{ item.title }}
@@ -368,19 +362,22 @@ import { TIMEOUT_HANDLER_ACTION_TYPES, TIME_UNIT_TYPES, REJECT_HANDLER_TYPES, - NODE_DEFAULT_NAME, DEFAULT_BUTTON_SETTING, - OPERATION_BUTTON_NAME + OPERATION_BUTTON_NAME, + ButtonSetting } from '../consts' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' -import { getDefaultFieldsPermission } from '../utils' +import { + useWatchNode, + useNodeName, + useFormFieldsPermission, + useNodeForm, + UserTaskFormType, + useDrawer +} from '../node' import { defaultProps } from '@/utils/tree' -import * as RoleApi from '@/api/system/role' -import * as DeptApi from '@/api/system/dept' -import * as PostApi from '@/api/system/post' -import * as UserApi from '@/api/system/user' -import * as UserGroupApi from '@/api/bpm/userGroup' import { cloneDeep } from 'lodash-es' +import { convertTimeUnit } from '../utils' defineOptions({ name: 'UserTaskNodeConfig' }) @@ -393,44 +390,22 @@ const props = defineProps({ const emits = defineEmits<{ 'find:returnTaskNodes': [nodeList: SimpleFlowNode[]] }>() +// 监控节点的变化 +const currentNode = useWatchNode(props) +// 抽屉配置 +const { settingVisible, closeDrawer, openDrawer } = useDrawer() +// 节点名称配置 +const { nodeName, showInput, clickIcon, blurEvent } = useNodeName(NodeType.USER_TASK_NODE) +// 激活的 Tab 标签页 +const activeTabName = ref('user') +// 表单字段权限设置 +const { formType, fieldsPermissionConfig, getNodeConfigFormFields } = useFormFieldsPermission() +// 操作按钮设置 +const { buttonsSetting, btnDisplayNameEdit, changeBtnDisplayName, btnDisplayNameBlurEvent } = + useButtonsSetting() -const currentNode = ref(props.flowNode) -// 监控节点变化 -watch( - () => props.flowNode, - (newValue) => { - currentNode.value = newValue - } -) -const notAllowedMultiApprovers = ref(false) -const settingVisible = ref(false) -const roleOptions = inject>('roleList') // 角色列表 -const postOptions = inject>('postList') // 岗位列表 -const userOptions = inject>('userList') // 用户列表 -const deptOptions = inject>('deptList') // 部门列表 -const userGroupOptions = inject>('userGroupList') // 用户组列表 -const deptTreeOptions = inject('deptTree') // 部门树 -const formType = inject('formType') // 表单类型 -const formFields = inject>('formFields') -const returnTaskList = ref([]) - +// 审批人表单设置 const formRef = ref() // 表单 Ref -const activeTabName = ref('user') // 激活的 Tab 标签页 -const configForm = ref({ - name: NODE_DEFAULT_NAME.get(NodeType.USER_TASK_NODE), - candidateParamArray: [], - candidateStrategy: CandidateStrategy.USER, - approveMethod: ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE, - approveRatio: 100, - rejectHandlerType: RejectHandlerType.FINISH_PROCESS, - returnNodeId: '', - timeoutHandlerEnable: false, - timeoutHandlerAction: 1, - timeDuration: 6, // 默认 6小时 - maxRemindCount: 1, // 默认 提醒 1次 - fieldsPermission: [], - buttonsSetting: [] -}) // 表单校验规则 const formRules = reactive({ candidateStrategy: [{ required: true, message: '审批人设置不能为空', trigger: 'change' }], @@ -443,10 +418,66 @@ const formRules = reactive({ timeDuration: [{ required: true, message: '超时时间不能为空', trigger: 'blur' }], maxRemindCount: [{ required: true, message: '提醒次数不能为空', trigger: 'blur' }] }) -// 关闭 -const closeDrawer = () => { - settingVisible.value = false + +const { + configForm: tempConfigForm, + roleOptions, + postOptions, + userOptions, + userGroupOptions, + deptTreeOptions, + getShowText +} = useNodeForm(NodeType.USER_TASK_NODE) +const configForm = tempConfigForm as Ref +// 不允许多人审批 +const notAllowedMultiApprovers = ref(false) +// 改变审批人设置策略 +const changeCandidateStrategy = () => { + configForm.value.candidateParamArray = [] + configForm.value.approveMethod = ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE + if ( + configForm.value.candidateStrategy === CandidateStrategy.START_USER || + configForm.value.candidateStrategy === CandidateStrategy.USER + ) { + notAllowedMultiApprovers.value = true + } else { + notAllowedMultiApprovers.value = false + } } +// 改变审批候选人 +const changedCandidateUsers = () => { + if ( + configForm.value.candidateParamArray?.length <= 1 && + configForm.value.candidateStrategy === CandidateStrategy.USER + ) { + configForm.value.approveMethod = ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE + configForm.value.rejectHandlerType = RejectHandlerType.FINISH_PROCESS + notAllowedMultiApprovers.value = true + } else { + notAllowedMultiApprovers.value = false + } +} +// 审批方式改变 +const approveMethodChanged = () => { + configForm.value.rejectHandlerType = RejectHandlerType.FINISH_PROCESS + if (configForm.value.approveMethod === ApproveMethodType.APPROVE_BY_RATIO) { + configForm.value.approveRatio = 100 + } + formRef.value.clearValidate('approveRatio') +} +// 审批拒绝 可回退的节点 +const returnTaskList = ref([]) +// 审批人超时未处理设置 +const { + timeoutHandlerChange, + cTimeoutAction, + timeoutActionChanged, + timeUnit, + timeUnitChange, + isoTimeDuration, + cTimeoutMaxRemindCount +} = useTimeoutHandler() + // 保存配置 const saveConfig = async () => { activeTabName.value = 'user' @@ -455,7 +486,7 @@ const saveConfig = async () => { if (!valid) return false const showText = getShowText() if (!showText) return false - currentNode.value.name = configForm.value.name + currentNode.value.name = nodeName.value! currentNode.value.candidateStrategy = configForm.value.candidateStrategy currentNode.value.candidateParam = configForm.value.candidateParamArray?.join(',') // 设置审批方式 @@ -465,121 +496,31 @@ const saveConfig = async () => { } // 设置拒绝处理 currentNode.value.rejectHandler = { - type: configForm.value.rejectHandlerType, + type: configForm.value.rejectHandlerType!, returnNodeId: configForm.value.returnNodeId } // 设置超时处理 currentNode.value.timeoutHandler = { - enable: configForm.value.timeoutHandlerEnable, + enable: configForm.value.timeoutHandlerEnable!, action: cTimeoutAction.value, timeDuration: isoTimeDuration.value, maxRemindCount: cTimeoutMaxRemindCount.value } // 设置表单权限 - currentNode.value.fieldsPermission = configForm.value.fieldsPermission + currentNode.value.fieldsPermission = fieldsPermissionConfig.value // 设置按钮权限 - currentNode.value.buttonsSetting = configForm.value.buttonsSetting + currentNode.value.buttonsSetting = buttonsSetting.value - currentNode.value.showText = getShowText() + currentNode.value.showText = showText settingVisible.value = false return true } -const getShowText = (): string => { - let showText = '' - // 指定成员 - if (configForm.value.candidateStrategy === CandidateStrategy.USER) { - if (configForm.value.candidateParamArray?.length > 0) { - const candidateNames: string[] = [] - userOptions?.value.forEach((item) => { - if (configForm.value.candidateParamArray.includes(item.id)) { - candidateNames.push(item.nickname) - } - }) - showText = `指定成员:${candidateNames.join(',')}` - } - } - // 指定角色 - if (configForm.value.candidateStrategy === CandidateStrategy.ROLE) { - if (configForm.value.candidateParamArray?.length > 0) { - const candidateNames: string[] = [] - roleOptions?.value.forEach((item) => { - if (configForm.value.candidateParamArray.includes(item.id)) { - candidateNames.push(item.name) - } - }) - showText = `指定角色:${candidateNames.join(',')}` - } - } - // 指定部门 - if ( - configForm.value.candidateStrategy === CandidateStrategy.DEPT_MEMBER || - configForm.value.candidateStrategy === CandidateStrategy.DEPT_LEADER - ) { - if (configForm.value.candidateParamArray?.length > 0) { - const candidateNames: string[] = [] - deptOptions?.value.forEach((item) => { - if (configForm.value.candidateParamArray.includes(item.id)) { - candidateNames.push(item.name) - } - }) - if (configForm.value.candidateStrategy === CandidateStrategy.DEPT_MEMBER) { - showText = `部门成员:${candidateNames.join(',')}` - } else { - showText = `部门的负责人:${candidateNames.join(',')}` - } - } - } - // 指定岗位 - if (configForm.value.candidateStrategy === CandidateStrategy.POST) { - if (configForm.value.candidateParamArray?.length > 0) { - const candidateNames: string[] = [] - postOptions?.value.forEach((item) => { - if (configForm.value.candidateParamArray.includes(item.id)) { - candidateNames.push(item.name) - } - }) - showText = `指定岗位: ${candidateNames.join(',')}` - } - } - // 指定用户组 - if (configForm.value.candidateStrategy === CandidateStrategy.USER_GROUP) { - if (configForm.value.candidateParamArray?.length > 0) { - const candidateNames: string[] = [] - userGroupOptions?.value.forEach((item) => { - if (configForm.value.candidateParamArray.includes(item.id)) { - candidateNames.push(item.name) - } - }) - showText = `指定用户组: ${candidateNames.join(',')}` - } - } - - // 发起人自选 - if (configForm.value.candidateStrategy === CandidateStrategy.START_USER_SELECT) { - showText = `发起人自选` - } - // 发起人自己 - if (configForm.value.candidateStrategy === CandidateStrategy.START_USER) { - showText = `发起人自己` - } - - // 流程表达式 - if (configForm.value.candidateStrategy === CandidateStrategy.EXPRESSION) { - if (configForm.value.candidateParamArray?.length > 0) { - showText = `流程表达式:${configForm.value.candidateParamArray[0]}` - } - } - return showText -} -const open = () => { - settingVisible.value = true -} -// 配置审批节点, 由父组件传过来 -const setCurrentNode = (node: SimpleFlowNode) => { - configForm.value.name = node.name +// 显示审批节点配置, 由父组件传过来 +const showUserTaskNodeConfig = (node: SimpleFlowNode) => { + nodeName.value = node.name //1.1 审批人设置 - configForm.value.candidateStrategy = node.candidateStrategy + configForm.value.candidateStrategy = node.candidateStrategy! const strCandidateParam = node?.candidateParam if (node.candidateStrategy === CandidateStrategy.EXPRESSION) { configForm.value.candidateParamArray[0] = strCandidateParam @@ -598,18 +539,18 @@ const setCurrentNode = (node: SimpleFlowNode) => { notAllowedMultiApprovers.value = false } //1.2 设置审批方式 - configForm.value.approveMethod = node.approveMethod + configForm.value.approveMethod = node.approveMethod! if (node.approveMethod == ApproveMethodType.APPROVE_BY_RATIO) { - configForm.value.approveRatio = node.approveRatio + configForm.value.approveRatio = node.approveRatio! } // 1.3 设置审批拒绝处理 - configForm.value.rejectHandlerType = node.rejectHandler?.type + configForm.value.rejectHandlerType = node.rejectHandler!.type configForm.value.returnNodeId = node.rejectHandler?.returnNodeId const matchNodeList = [] emits('find:returnTaskNodes', matchNodeList) returnTaskList.value = matchNodeList // 1.4 设置审批超时处理 - configForm.value.timeoutHandlerEnable = node.timeoutHandler?.enable + configForm.value.timeoutHandlerEnable = node.timeoutHandler!.enable if (node.timeoutHandler?.enable && node.timeoutHandler?.timeDuration) { const strTimeDuration = node.timeoutHandler.timeDuration let parseTime = strTimeDuration.slice(2, strTimeDuration.length - 1) @@ -620,152 +561,121 @@ const setCurrentNode = (node: SimpleFlowNode) => { configForm.value.timeoutHandlerAction = node.timeoutHandler?.action configForm.value.maxRemindCount = node.timeoutHandler?.maxRemindCount // 2. 操作按钮设置 - configForm.value.buttonsSetting = cloneDeep(node.buttonsSetting) || DEFAULT_BUTTON_SETTING + buttonsSetting.value = cloneDeep(node.buttonsSetting) || DEFAULT_BUTTON_SETTING // 3. 表单字段权限配置 - configForm.value.fieldsPermission = - cloneDeep(node.fieldsPermission) || getDefaultFieldsPermission(formFields?.value) + getNodeConfigFormFields(node.fieldsPermission) } -defineExpose({ open, setCurrentNode }) // 暴露方法给父组件 +defineExpose({ openDrawer, showUserTaskNodeConfig }) // 暴露方法给父组件 -const changeCandidateStrategy = () => { - configForm.value.candidateParamArray = [] - configForm.value.approveMethod = ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE - if ( - configForm.value.candidateStrategy === CandidateStrategy.START_USER || - configForm.value.candidateStrategy === CandidateStrategy.USER - ) { - notAllowedMultiApprovers.value = true - } else { - notAllowedMultiApprovers.value = false +/** + * @description 操作按钮设置 + */ +function useButtonsSetting() { + const buttonsSetting = ref() + // 操作按钮显示名称可编辑 + const btnDisplayNameEdit = ref([]) + const changeBtnDisplayName = (index: number) => { + btnDisplayNameEdit.value[index] = true + } + const btnDisplayNameBlurEvent = (index: number) => { + btnDisplayNameEdit.value[index] = false + const buttonItem = buttonsSetting.value![index] + buttonItem.displayName = buttonItem.displayName || OPERATION_BUTTON_NAME.get(buttonItem.id)! + } + return { + buttonsSetting, + btnDisplayNameEdit, + changeBtnDisplayName, + btnDisplayNameBlurEvent } } -const changedCandidateUsers = () => { - if ( - configForm.value.candidateParamArray?.length <= 1 && - configForm.value.candidateStrategy === CandidateStrategy.USER - ) { - configForm.value.approveMethod = ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE - configForm.value.rejectHandlerType = RejectHandlerType.FINISH_PROCESS - notAllowedMultiApprovers.value = true - } else { - notAllowedMultiApprovers.value = false - } -} -// 显示名称输入框 -const showInput = ref(false) +/** + * @description 审批人超时未处理配置 + */ +function useTimeoutHandler() { + // 时间单位 + const timeUnit = ref(TimeUnitType.HOUR) -const clickIcon = () => { - showInput.value = true -} -// 节点名称输入框失去焦点 -const blurEvent = () => { - showInput.value = false - configForm.value.name = - configForm.value.name || (NODE_DEFAULT_NAME.get(NodeType.USER_TASK_NODE) as string) -} + // 超时开关改变 + const timeoutHandlerChange = () => { + if (configForm.value.timeoutHandlerEnable) { + timeUnit.value = 2 + configForm.value.timeDuration = 6 + configForm.value.timeoutHandlerAction = 1 + configForm.value.maxRemindCount = 1 + } + } + // 超时执行的动作 + const cTimeoutAction = computed(() => { + if (!configForm.value.timeoutHandlerEnable) { + return undefined + } + return configForm.value.timeoutHandlerAction + }) -const approveMethodChanged = () => { - configForm.value.rejectHandlerType = RejectHandlerType.FINISH_PROCESS - if (configForm.value.approveMethod === ApproveMethodType.APPROVE_BY_RATIO) { - configForm.value.approveRatio = 100 + // 超时处理动作改变 + const timeoutActionChanged = () => { + if (configForm.value.timeoutHandlerAction === 1) { + configForm.value.maxRemindCount = 1 // 超时提醒次数,默认为1 + } } - formRef.value.clearValidate('approveRatio') -} -const timeUnit = ref(TimeUnitType.HOUR) + // 时间单位改变 + const timeUnitChange = () => { + // 分钟,默认是 60 分钟 + if (timeUnit.value === TimeUnitType.MINUTE) { + configForm.value.timeDuration = 60 + } + // 小时,默认是 6 个小时 + if (timeUnit.value === TimeUnitType.HOUR) { + configForm.value.timeDuration = 6 + } + // 天, 默认 1天 + if (timeUnit.value === TimeUnitType.DAY) { + configForm.value.timeDuration = 1 + } + } + // 超时时间的 ISO 表示 + const isoTimeDuration = computed(() => { + if (!configForm.value.timeoutHandlerEnable) { + return undefined + } + let strTimeDuration = 'PT' + if (timeUnit.value === TimeUnitType.MINUTE) { + strTimeDuration += configForm.value.timeDuration + 'M' + } + if (timeUnit.value === TimeUnitType.HOUR) { + strTimeDuration += configForm.value.timeDuration + 'H' + } + if (timeUnit.value === TimeUnitType.DAY) { + strTimeDuration += configForm.value.timeDuration + 'D' + } + return strTimeDuration + }) -// 超时时间的 ISO 表示 -const isoTimeDuration = computed(() => { - if (!configForm.value.timeoutHandlerEnable) { - return undefined - } - let strTimeDuration = 'PT' - if (timeUnit.value === TimeUnitType.MINUTE) { - strTimeDuration += configForm.value.timeDuration + 'M' - } - if (timeUnit.value === TimeUnitType.HOUR) { - strTimeDuration += configForm.value.timeDuration + 'H' - } - if (timeUnit.value === TimeUnitType.DAY) { - strTimeDuration += configForm.value.timeDuration + 'D' - } - return strTimeDuration -}) -// 超时执行的动作 -const cTimeoutAction = computed(() => { - if (!configForm.value.timeoutHandlerEnable) { - return undefined - } - return configForm.value.timeoutHandlerAction -}) -// 超时最大提醒次数 -const cTimeoutMaxRemindCount = computed(() => { - if (!configForm.value.timeoutHandlerEnable) { - return undefined - } - if (configForm.value.timeoutHandlerAction !== 1) { - return undefined - } - return configForm.value.maxRemindCount -}) + // 超时最大提醒次数 + const cTimeoutMaxRemindCount = computed(() => { + if (!configForm.value.timeoutHandlerEnable) { + return undefined + } + if (configForm.value.timeoutHandlerAction !== 1) { + return undefined + } + return configForm.value.maxRemindCount + }) -// 超时开关改变 -const timeoutHandlerChange = () => { - if (configForm.value.timeoutHandlerEnable) { - timeUnit.value = 2 - configForm.value.timeDuration = 6 - configForm.value.timeoutHandlerAction = 1 - configForm.value.maxRemindCount = 1 + return { + timeoutHandlerChange, + cTimeoutAction, + timeoutActionChanged, + timeUnit, + timeUnitChange, + isoTimeDuration, + cTimeoutMaxRemindCount } } -// 超时处理动作改变 -const timeoutActionChanged = () => { - if (configForm.value.timeoutHandlerAction === 1) { - configForm.value.maxRemindCount = 1 // 超时提醒次数,默认为1 - } -} - -// 时间单位改变 -const timeUnitChange = () => { - // 分钟,默认是 60 分钟 - if (timeUnit.value === TimeUnitType.MINUTE) { - configForm.value.timeDuration = 60 - } - // 小时,默认是 6 个小时 - if (timeUnit.value === TimeUnitType.HOUR) { - configForm.value.timeDuration = 6 - } - // 天, 默认 1天 - if (timeUnit.value === TimeUnitType.DAY) { - configForm.value.timeDuration = 1 - } -} - -const convertTimeUnit = (strTimeUnit: string) => { - if (strTimeUnit === 'M') { - return TimeUnitType.MINUTE - } - if (strTimeUnit === 'H') { - return TimeUnitType.HOUR - } - if (strTimeUnit === 'D') { - return TimeUnitType.DAY - } - return TimeUnitType.HOUR -} - -// 操作按钮显示名称可编辑 -const btnDisplayNameEdit = ref([]) -const changeBtnDisplayName = (index: number) => { - btnDisplayNameEdit.value[index] = true -} -const btnDisplayNameBlurEvent = (index: number) => { - btnDisplayNameEdit.value[index] = false - const buttonItem = configForm.value.buttonPermission[index] - buttonItem.displayName = buttonItem.displayName || OPERATION_BUTTON_NAME.get(buttonItem.id) -}