diff --git a/build/vite/optimize.ts b/build/vite/optimize.ts index aa7e68c9cce9548c01e007e75da7e1867472682f..9de496a30ab69d5b7a13b1def823ad786f6a272b 100644 --- a/build/vite/optimize.ts +++ b/build/vite/optimize.ts @@ -114,7 +114,8 @@ const include = [ 'element-plus/es/components/segmented/style/css', '@element-plus/icons-vue', 'element-plus/es/components/footer/style/css', - 'element-plus/es/components/empty/style/css' + 'element-plus/es/components/empty/style/css', + 'element-plus/es/components/mention/style/css' ] const exclude = ['@iconify/json'] diff --git a/src/assets/svgs/bpm/transactor.svg b/src/assets/svgs/bpm/transactor.svg new file mode 100644 index 0000000000000000000000000000000000000000..a9547a7dda353a47166eb476b25ae85a44b77e04 --- /dev/null +++ b/src/assets/svgs/bpm/transactor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue b/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue index b3f62340a2e7595da3898d2b5abe43cfb3e8bbb1..ab5b62714213bb36453a1bbccbc1ed75bb664b43 100644 --- a/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue +++ b/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue @@ -15,6 +15,12 @@
审批人
+
+
+ +
+
办理人
+
@@ -57,7 +63,7 @@
触发器
- + @@ -78,7 +84,7 @@ import { SimpleFlowNode, DEFAULT_CONDITION_GROUP_VALUE } from './consts' -import {generateUUID} from '@/utils' +import { generateUUID } from '@/utils' defineOptions({ name: 'NodeHandler' @@ -114,13 +120,13 @@ const addNode = (type: number) => { } popoverShow.value = false - if (type === NodeType.USER_TASK_NODE) { + if (type === NodeType.USER_TASK_NODE || type === NodeType.TRANSACTOR_NODE) { const id = 'Activity_' + generateUUID() const data: SimpleFlowNode = { id: id, - name: NODE_DEFAULT_NAME.get(NodeType.USER_TASK_NODE) as string, + name: NODE_DEFAULT_NAME.get(type) as string, showText: '', - type: NodeType.USER_TASK_NODE, + type: type, approveMethod: ApproveMethodType.SEQUENTIAL_APPROVE, // 超时处理 rejectHandler: { diff --git a/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue b/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue index 048764c1ab03aab5c5d284b07c24aa9c54f0a2a3..cdb540322d8d3ddf90e778fed665dcd3efa61d9b 100644 --- a/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue +++ b/src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue @@ -6,7 +6,11 @@ /> -p diff --git a/src/components/SimpleProcessDesignerV2/src/consts.ts b/src/components/SimpleProcessDesignerV2/src/consts.ts index f0614eefa9a7ca5495da35c339b7301da2bd5a22..31ee837020ce10dcc6ba4c8bd7587ab24aca92a3 100644 --- a/src/components/SimpleProcessDesignerV2/src/consts.ts +++ b/src/components/SimpleProcessDesignerV2/src/consts.ts @@ -23,6 +23,11 @@ export enum NodeType { */ COPY_TASK_NODE = 12, + /** + * 办理人节点 + */ + TRANSACTOR_NODE = 13, + /** * 延迟器节点 */ @@ -506,6 +511,7 @@ NODE_DEFAULT_TEXT.set(NodeType.START_USER_NODE, '请设置发起人') NODE_DEFAULT_TEXT.set(NodeType.DELAY_TIMER_NODE, '请设置延迟器') NODE_DEFAULT_TEXT.set(NodeType.ROUTER_BRANCH_NODE, '请设置路由节点') NODE_DEFAULT_TEXT.set(NodeType.TRIGGER_NODE, '请设置触发器') +NODE_DEFAULT_TEXT.set(NodeType.TRANSACTOR_NODE, '请设置办理人') export const NODE_DEFAULT_NAME = new Map() NODE_DEFAULT_NAME.set(NodeType.USER_TASK_NODE, '审批人') @@ -515,15 +521,17 @@ NODE_DEFAULT_NAME.set(NodeType.START_USER_NODE, '发起人') NODE_DEFAULT_NAME.set(NodeType.DELAY_TIMER_NODE, '延迟器') NODE_DEFAULT_NAME.set(NodeType.ROUTER_BRANCH_NODE, '路由分支') NODE_DEFAULT_NAME.set(NodeType.TRIGGER_NODE, '触发器') +NODE_DEFAULT_NAME.set(NodeType.TRANSACTOR_NODE, '办理人') // 候选人策略。暂时不从字典中取。 后续可能调整。控制显示顺序 export const CANDIDATE_STRATEGY: DictDataVO[] = [ { label: '指定成员', value: CandidateStrategy.USER }, { label: '指定角色', value: CandidateStrategy.ROLE }, + { label: '指定岗位', value: CandidateStrategy.POST }, { label: '部门成员', value: CandidateStrategy.DEPT_MEMBER }, { label: '部门负责人', value: CandidateStrategy.DEPT_LEADER }, { label: '连续多级部门负责人', value: CandidateStrategy.MULTI_LEVEL_DEPT_LEADER }, - { label: '发起人自选', value: CandidateStrategy.START_USER_SELECT }, + { label: '指定岗位', value: CandidateStrategy.MULTI_LEVEL_DEPT_LEADER }, { label: '发起人本人', value: CandidateStrategy.START_USER }, { label: '发起人部门负责人', value: CandidateStrategy.START_USER_DEPT_LEADER }, { label: '发起人连续部门负责人', value: CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER }, @@ -627,6 +635,16 @@ export const DEFAULT_BUTTON_SETTING: ButtonSetting[] = [ { id: OperationButtonType.RETURN, displayName: '退回', enable: true } ] +// 办理人默认的按钮权限设置 +export const TRANSACTOR_DEFAULT_BUTTON_SETTING: ButtonSetting[] = [ + { id: OperationButtonType.APPROVE, displayName: '办理', enable: true }, + { id: OperationButtonType.REJECT, displayName: '拒绝', enable: false }, + { id: OperationButtonType.TRANSFER, displayName: '转办', enable: false }, + { id: OperationButtonType.DELEGATE, displayName: '委派', enable: false }, + { id: OperationButtonType.ADD_SIGN, displayName: '加签', enable: false }, + { id: OperationButtonType.RETURN, displayName: '退回', enable: false } +] + // 发起人的按钮权限。暂时定死,不可以编辑 export const START_USER_BUTTON_SETTING: ButtonSetting[] = [ { id: OperationButtonType.APPROVE, displayName: '提交', enable: true }, @@ -717,7 +735,7 @@ export type RouterSetting = { export type TriggerSetting = { type: TriggerTypeEnum httpRequestSetting?: HttpRequestTriggerSetting - normalFormSetting?: NormalFormTriggerSetting + formSettings?: FormTriggerSetting[] } /** @@ -751,7 +769,13 @@ export type HttpRequestTriggerSetting = { /** * 流程表单触发器配置结构定义 */ -export type NormalFormTriggerSetting = { +export type FormTriggerSetting = { + // 条件类型 + conditionType?: ConditionType + // 条件表达式 + conditionExpression?: string + // 条件组 + conditionGroups?: ConditionGroup // 更新表单字段 updateFormFields?: Record } diff --git a/src/components/SimpleProcessDesignerV2/src/node.ts b/src/components/SimpleProcessDesignerV2/src/node.ts index 407fd4837933520d8a3cbc907a37616ee107c138..edd38fcd43da62e46cf90a53e5b652036363d8a1 100644 --- a/src/components/SimpleProcessDesignerV2/src/node.ts +++ b/src/components/SimpleProcessDesignerV2/src/node.ts @@ -15,7 +15,10 @@ import { AssignEmptyHandlerType, FieldPermissionType, HttpRequestParam, - ProcessVariableEnum + ProcessVariableEnum, + ConditionType, + ConditionGroup, + COMPARISON_OPERATORS } from './consts' import { parseFormFields } from '@/components/FormCreate/src/utils' @@ -201,7 +204,7 @@ export function useNodeForm(nodeType: NodeType) { const deptTreeOptions = inject('deptTree', ref()) // 部门树 const formFields = inject>('formFields', ref([])) // 流程表单字段 const configForm = ref() - if (nodeType === NodeType.USER_TASK_NODE) { + if (nodeType === NodeType.USER_TASK_NODE || nodeType === NodeType.TRANSACTOR_NODE) { configForm.value = { candidateStrategy: CandidateStrategy.USER, approveMethod: ApproveMethodType.SEQUENTIAL_APPROVE, @@ -543,6 +546,66 @@ export function useTaskStatusClass(taskStatus: TaskStatusEnum | undefined): stri if (taskStatus === TaskStatusEnum.CANCEL) { return 'status-cancel' } - return '' } + +/** 条件组件文字展示 */ +export function getConditionShowText( + conditonType: ConditionType | undefined, + conditionExpression: string | undefined, + conditionGroups: ConditionGroup | undefined, + fieldOptions: Array> +) { + let showText = '' + if (conditonType === ConditionType.EXPRESSION) { + if (conditionExpression) { + showText = `表达式:${conditionExpression}` + } + } + if (conditonType === ConditionType.RULE) { + // 条件组是否为与关系 + const groupAnd = conditionGroups?.and + let warningMesg: undefined | string = undefined + const conditionGroup = conditionGroups?.conditions.map((item) => { + return ( + '(' + + item.rules + .map((rule) => { + if (rule.leftSide && rule.rightSide) { + return ( + getFormFieldTitle(fieldOptions, rule.leftSide) + + ' ' + + getOpName(rule.opCode) + + ' ' + + rule.rightSide + ) + } else { + // 有一条规则不完善。提示错误 + warningMesg = '请完善条件规则' + return '' + } + }) + .join(item.and ? ' 且 ' : ' 或 ') + + ' ) ' + ) + }) + if (warningMesg) { + showText = '' + } else { + showText = conditionGroup!.join(groupAnd ? ' 且 ' : ' 或 ') + } + } + return showText +} + +/** 获取表单字段名称*/ +const getFormFieldTitle = (fieldOptions: Array>, field: string) => { + const item = fieldOptions.find((item) => item.field === field) + return item?.title +} + +/** 获取操作符名称 */ +const getOpName = (opCode: string): string => { + const opName = COMPARISON_OPERATORS.find((item: any) => item.value === opCode) + return opName?.label +} diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue index e9b387a7ff5bdb3116d66cd6a876b519da901d56..c7881cd28a2cb2ece7305dc42d0970d8aeef0809 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue @@ -43,13 +43,9 @@ diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/TriggerNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/TriggerNodeConfig.vue index 5c3c05b08c36265c9191df6cba1b7889e19b9de7..794f38b3576ae6925f4c3cf2b83fb9cdba7b5d97 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/TriggerNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/TriggerNodeConfig.vue @@ -3,7 +3,7 @@ :append-to-body="true" v-model="settingVisible" :show-close="false" - :size="550" + :size="630" :before-close="saveConfig" > diff --git a/src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue b/src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue index 47ef540cc9e1229db7d2986ff42eff60fb6db84e..ae1af6c287957627fcdc5b0febe729ad618593be 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue @@ -9,7 +9,14 @@ ]" >
-
+
+ + +
- {{ NODE_DEFAULT_TEXT.get(NodeType.USER_TASK_NODE) }} + {{ NODE_DEFAULT_TEXT.get(currentNode.type) }}
diff --git a/src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss b/src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss index f3d8b4437335aa206dce04c919d343001252a4ad..62199105c22c684af71bb15db657c4e46d78ea6d 100644 --- a/src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss +++ b/src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss @@ -177,6 +177,10 @@ color: #ca3a31 } + .transactor { + color: #330099; + } + .handler-item-text { margin-top: 4px; width: 80px; @@ -290,10 +294,14 @@ &.trigger-node { color: #3373d2; } - + &.router-node { color: #ca3a31 } + + &.transactor-task { + color: #330099; + } } .node-title { @@ -777,7 +785,7 @@ content: "\e7eb"; } -.icon-handle:before { +.icon-transactor:before { content: "\e61c"; } diff --git a/src/components/bpmnProcessDesigner/package/penal/custom-config/components/UserTaskCustomConfig.vue b/src/components/bpmnProcessDesigner/package/penal/custom-config/components/UserTaskCustomConfig.vue index aab130d087aa243b2e89c8c89fef76b50b21bb9b..8b3b8af2d4676b5e0696c5c14a07cd7812c16d74 100644 --- a/src/components/bpmnProcessDesigner/package/penal/custom-config/components/UserTaskCustomConfig.vue +++ b/src/components/bpmnProcessDesigner/package/penal/custom-config/components/UserTaskCustomConfig.vue @@ -191,6 +191,7 @@ import { } from '@/components/SimpleProcessDesignerV2/src/consts' import * as UserApi from '@/api/system/user' import { useFormFieldsPermission } from '@/components/SimpleProcessDesignerV2/src/node' +import { BpmModelFormType } from '@/utils/constants' defineOptions({ name: 'ElementCustomConfig4UserTask' }) const props = defineProps({ @@ -248,7 +249,6 @@ const resetCustomConfigList = () => { bpmnElement.value.id, bpmnInstances().modeler ) - // 获取元素扩展属性 或者 创建扩展属性 elExtensionElements.value = bpmnElement.value.businessObject?.extensionElements ?? @@ -311,14 +311,13 @@ const resetCustomConfigList = () => { } // 字段权限 - if (formType.value === 10) { + if (formType.value === BpmModelFormType.NORMAL) { const fieldsPermissionList = elExtensionElements.value.values?.filter( (ex) => ex.$type === `${prefix}:FieldsPermission` ) fieldsPermissionEl.value = [] getNodeConfigFormFields() - // 由于默认添加了发起人元素,这里需要删掉 - fieldsPermissionConfig.value = fieldsPermissionConfig.value.slice(1) + fieldsPermissionConfig.value = fieldsPermissionConfig.value fieldsPermissionConfig.value.forEach((element) => { element.permission = fieldsPermissionList?.find((obj) => obj.field === element.field)?.permission ?? '1' @@ -497,9 +496,9 @@ onMounted(async () => {