From 67769c299ed0a65b4b2979b4d124718db6425430 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sun, 17 Nov 2024 10:49:57 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E3=80=90=E5=8A=9F=E8=83=BD=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E3=80=91=E5=80=99=E9=80=89=E4=BA=BA=E7=AD=96=E7=95=A5?= =?UTF-8?q?=EF=BC=9A=E6=96=B0=E5=A2=9E=E8=A1=A8=E5=8D=95=E5=86=85=E6=88=90?= =?UTF-8?q?=E5=91=98=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/useApiSelect.tsx | 2 +- .../SimpleProcessDesignerV2/src/consts.ts | 8 ++- .../SimpleProcessDesignerV2/src/node.ts | 61 +++++++++++++++---- .../src/nodes-config/CopyTaskNodeConfig.vue | 25 +++++++- .../src/nodes-config/UserTaskNodeConfig.vue | 24 +++++++- 5 files changed, 102 insertions(+), 18 deletions(-) diff --git a/src/components/FormCreate/src/components/useApiSelect.tsx b/src/components/FormCreate/src/components/useApiSelect.tsx index 29cd3027..741b1d48 100644 --- a/src/components/FormCreate/src/components/useApiSelect.tsx +++ b/src/components/FormCreate/src/components/useApiSelect.tsx @@ -185,7 +185,7 @@ export const useApiSelect = (option: ApiSelectProps) => { ) } - debugger + // debugger return ( > + fieldsPermission?: Array> // 审批任务超时处理 timeoutHandler?: TimeoutHandler // 审批任务拒绝处理 @@ -145,6 +145,11 @@ export enum CandidateStrategy { * 指定用户组 */ USER_GROUP = 40, + + /** + * 表单内成员字段 + */ + USER_FIELD_ON_FORM = 50, /** * 流程表达式 */ @@ -424,6 +429,7 @@ export const CANDIDATE_STRATEGY: DictDataVO[] = [ { label: '发起人部门负责人', value: CandidateStrategy.START_USER_DEPT_LEADER }, { label: '发起人连续部门负责人', value: CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER }, { label: '用户组', value: CandidateStrategy.USER_GROUP }, + { label: '表单内成员字段', value: CandidateStrategy.USER_FIELD_ON_FORM }, { label: '流程表达式', value: CandidateStrategy.EXPRESSION } ] // 审批节点 的审批类型 diff --git a/src/components/SimpleProcessDesignerV2/src/node.ts b/src/components/SimpleProcessDesignerV2/src/node.ts index d10173bb..64e5fef8 100644 --- a/src/components/SimpleProcessDesignerV2/src/node.ts +++ b/src/components/SimpleProcessDesignerV2/src/node.ts @@ -32,7 +32,7 @@ export function useWatchNode(props: { flowNode: SimpleFlowNode }): Ref>>([]) + const fieldsPermissionConfig = ref>>([]) const formType = inject>('formType') // 表单类型 @@ -45,49 +45,71 @@ export function useFormFieldsPermission(defaultPermission: FieldPermissionType) } // 默认的表单权限: 获取表单的所有字段,设置字段默认权限为只读 const getDefaultFieldsPermission = (formFields?: string[]) => { - const defaultFieldsPermission: Array> = [] + let defaultFieldsPermission: Array> = [] if (formFields) { - formFields.forEach((fieldStr: string) => { - parseFieldsSetDefaultPermission(JSON.parse(fieldStr), defaultFieldsPermission) - }) + defaultFieldsPermission = parseFormCreateFields(formFields).map( item => { + return { + field: item.field, + title: item.title, + permission: defaultPermission + } + }); } return defaultFieldsPermission } - // 解析字段。赋给默认权限 - const parseFieldsSetDefaultPermission = ( + // 解析 formCreate 所有表单字段, 并返回 + const parseFormCreateFields = (formFields?: string[]) => { + const result: Array> = [] + if (formFields) { + formFields.forEach((fieldStr: string) => { + parseFields(JSON.parse(fieldStr), result) + }) + } + return result + } + const parseFields = ( rule: Record, - fieldsPermission: Array>, + fields: Array>, parentTitle: string = '' ) => { - const { /**type,*/ field, title: tempTitle, children } = rule + const { type, field, $required, title: tempTitle, children } = rule if (field && tempTitle) { let title = tempTitle if (parentTitle) { title = `${parentTitle}.${tempTitle}` } - fieldsPermission.push({ + let required = false; + if($required) { + required = true; + } + fields.push({ field, title, - permission: defaultPermission + type, + required }) // TODO 子表单 需要处理子表单字段 // if (type === 'group' && rule.props?.rule && Array.isArray(rule.props.rule)) { // // 解析子表单的字段 // rule.props.rule.forEach((item) => { - // parseFieldsSetDefaultPermission(item, fieldsPermission, title) + // parseFields(item, fieldsPermission, title) // }) // } } if (children && Array.isArray(children)) { children.forEach((rule) => { - parseFieldsSetDefaultPermission(rule, fieldsPermission) + parseFields(rule, fields) }) } } + + // 获取表单的所有字段,作为下拉框选项 + const formFieldOptions = parseFormCreateFields(unref(formFields)) return { formType, fieldsPermissionConfig, + formFieldOptions, getNodeConfigFormFields } } @@ -152,6 +174,7 @@ export type UserTaskFormType = { userGroups?: number[] // 用户组 postIds?: number[] // 岗位 expression?: string // 流程表达式 + userFieldOnForm?: string // 表单内成员字段 approveRatio?: number rejectHandlerType?: RejectHandlerType returnNodeId?: string @@ -174,6 +197,7 @@ export type CopyTaskFormType = { userIds?: number[] // 用户 userGroups?: number[] // 用户组 postIds?: number[] // 岗位 + userFieldOnForm?: string // 表单内成员字段 expression?: string // 流程表达式 } @@ -282,6 +306,11 @@ export function useNodeForm(nodeType: NodeType) { } } + // 表单内成员字段 + if (configForm.value?.candidateStrategy === CandidateStrategy.USER_FIELD_ON_FORM) { + showText = `表单内用户字段` + } + // 发起人自选 if (configForm.value?.candidateStrategy === CandidateStrategy.START_USER_SELECT) { showText = `发起人自选` @@ -328,6 +357,9 @@ export function useNodeForm(nodeType: NodeType) { case CandidateStrategy.USER_GROUP: candidateParam = configForm.value.userGroups!.join(',') break + case CandidateStrategy.USER_FIELD_ON_FORM: + candidateParam = configForm.value.userFieldOnForm! + break case CandidateStrategy.EXPRESSION: candidateParam = configForm.value.expression! break @@ -376,6 +408,9 @@ export function useNodeForm(nodeType: NodeType) { case CandidateStrategy.USER_GROUP: configForm.value.userGroups = candidateParam.split(',').map((item) => +item) break + case CandidateStrategy.USER_FIELD_ON_FORM: + configForm.value.userFieldOnForm = candidateParam + break case CandidateStrategy.EXPRESSION: configForm.value.expression = candidateParam break diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue index c3006afc..422ac992 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue @@ -122,7 +122,20 @@ /> - + + + + + { + return formFieldOptions.filter( + (item) => item.required && item.type === 'UserSelect' + ) +}) // 抄送人表单配置 const formRef = ref() // 表单 Ref // 表单校验规则 @@ -243,6 +262,7 @@ const formRules = reactive({ deptIds: [{ required: true, message: '部门不能为空', trigger: 'change' }], userGroups: [{ required: true, message: '用户组不能为空', trigger: 'change' }], postIds: [{ required: true, message: '岗位不能为空', trigger: 'change' }], + userFieldOnForm: [{ required: true, message: '表单内成员字段为空', trigger: 'change' }], expression: [{ required: true, message: '流程表达式不能为空', trigger: 'blur' }] }) @@ -272,6 +292,7 @@ const changeCandidateStrategy = () => { configForm.value.postIds = [] configForm.value.userGroups = [] configForm.value.deptLevel = 1 + configForm.value.userFieldOnForm = '' } // 保存配置 const saveConfig = async () => { diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue index 899d7045..7d8d7708 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue @@ -157,6 +157,20 @@ /> + + + + + { + return formFieldOptions.filter( + (item) => item.required && item.type === 'UserSelect' + ) +}) // 操作按钮设置 const { buttonsSetting, btnDisplayNameEdit, changeBtnDisplayName, btnDisplayNameBlurEvent } = useButtonsSetting() @@ -498,6 +518,7 @@ const formRules = reactive({ roleIds: [{ required: true, message: '角色不能为空', trigger: 'change' }], deptIds: [{ required: true, message: '部门不能为空', trigger: 'change' }], userGroups: [{ required: true, message: '用户组不能为空', trigger: 'change' }], + userFieldOnForm: [{ required: true, message: '表单内成员字段为空', trigger: 'change' }], postIds: [{ required: true, message: '岗位不能为空', trigger: 'change' }], expression: [{ required: true, message: '流程表达式不能为空', trigger: 'blur' }], approveMethod: [{ required: true, message: '多人审批方式不能为空', trigger: 'change' }], @@ -533,6 +554,7 @@ const changeCandidateStrategy = () => { configForm.value.postIds = [] configForm.value.userGroups = [] configForm.value.deptLevel = 1 + configForm.value.userFieldOnForm = '' configForm.value.approveMethod = ApproveMethodType.SEQUENTIAL_APPROVE } From 756addd4233fcdd7aff2b0842c733004be2b6600 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sun, 17 Nov 2024 16:47:18 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E3=80=90=E5=8A=9F=E8=83=BD=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E3=80=91=E6=9D=A1=E4=BB=B6=E8=8A=82=E7=82=B9=EF=BC=9A?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=E5=A2=9E=E5=8A=A0=E5=8F=91=E8=B5=B7=E4=BA=BA?= =?UTF-8?q?=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SimpleProcessDesignerV2/src/consts.ts | 14 +- .../SimpleProcessDesignerV2/src/node.ts | 160 ++++++++---------- .../src/nodes-config/CopyTaskNodeConfig.vue | 6 +- .../src/nodes-config/UserTaskNodeConfig.vue | 6 +- 4 files changed, 85 insertions(+), 101 deletions(-) diff --git a/src/components/SimpleProcessDesignerV2/src/consts.ts b/src/components/SimpleProcessDesignerV2/src/consts.ts index 9f20a906..a712fb13 100644 --- a/src/components/SimpleProcessDesignerV2/src/consts.ts +++ b/src/components/SimpleProcessDesignerV2/src/consts.ts @@ -147,7 +147,7 @@ export enum CandidateStrategy { USER_GROUP = 40, /** - * 表单内成员字段 + * 表单内用户字段 */ USER_FIELD_ON_FORM = 50, /** @@ -429,7 +429,7 @@ export const CANDIDATE_STRATEGY: DictDataVO[] = [ { label: '发起人部门负责人', value: CandidateStrategy.START_USER_DEPT_LEADER }, { label: '发起人连续部门负责人', value: CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER }, { label: '用户组', value: CandidateStrategy.USER_GROUP }, - { label: '表单内成员字段', value: CandidateStrategy.USER_FIELD_ON_FORM }, + { label: '表单内用户字段', value: CandidateStrategy.USER_FIELD_ON_FORM }, { label: '流程表达式', value: CandidateStrategy.EXPRESSION } ] // 审批节点 的审批类型 @@ -554,3 +554,13 @@ export const MULTI_LEVEL_DEPT: DictDataVO = [ { label: '第 14 级部门', value: 14 }, { label: '第 15 级部门', value: 15 } ] + +/** + * 流程实例的变量枚举 + */ +export enum ProcessVariableEnum { + /** + * 发起用户 ID + */ + START_USER_ID = 'PROCESS_START_USER_ID' +} diff --git a/src/components/SimpleProcessDesignerV2/src/node.ts b/src/components/SimpleProcessDesignerV2/src/node.ts index 64e5fef8..53e2b11f 100644 --- a/src/components/SimpleProcessDesignerV2/src/node.ts +++ b/src/components/SimpleProcessDesignerV2/src/node.ts @@ -14,7 +14,8 @@ import { NODE_DEFAULT_NAME, AssignStartUserHandlerType, AssignEmptyHandlerType, - FieldPermissionType + FieldPermissionType, + ProcessVariableEnum } from './consts' export function useWatchNode(props: { flowNode: SimpleFlowNode }): Ref { const node = ref(props.flowNode) @@ -27,6 +28,61 @@ export function useWatchNode(props: { flowNode: SimpleFlowNode }): Ref { + const result: Array> = [] + if (formFields) { + formFields.forEach((fieldStr: string) => { + parseFields(JSON.parse(fieldStr), result) + }) + } + // 固定添加发起人 ID 字段 + result.unshift( { + field: ProcessVariableEnum.START_USER_ID, + title: '发起人', + type: 'UserSelect', + required: true + }) + return result +} + +const parseFields = ( + rule: Record, + fields: Array>, + parentTitle: string = '' +) => { + const { type, field, $required, title: tempTitle, children } = rule + if (field && tempTitle) { + let title = tempTitle + if (parentTitle) { + title = `${parentTitle}.${tempTitle}` + } + let required = false; + if($required) { + required = true; + } + fields.push({ + field, + title, + type, + required + }) + // TODO 子表单 需要处理子表单字段 + // if (type === 'group' && rule.props?.rule && Array.isArray(rule.props.rule)) { + // // 解析子表单的字段 + // rule.props.rule.forEach((item) => { + // parseFields(item, fieldsPermission, title) + // }) + // } + } + if (children && Array.isArray(children)) { + children.forEach((rule) => { + parseFields(rule, fields) + }) + } +} + + /** * @description 表单数据权限配置,用于发起人节点 、审批节点、抄送节点 */ @@ -57,51 +113,8 @@ export function useFormFieldsPermission(defaultPermission: FieldPermissionType) } return defaultFieldsPermission } - // 解析 formCreate 所有表单字段, 并返回 - const parseFormCreateFields = (formFields?: string[]) => { - const result: Array> = [] - if (formFields) { - formFields.forEach((fieldStr: string) => { - parseFields(JSON.parse(fieldStr), result) - }) - } - return result - } - const parseFields = ( - rule: Record, - fields: Array>, - parentTitle: string = '' - ) => { - const { type, field, $required, title: tempTitle, children } = rule - if (field && tempTitle) { - let title = tempTitle - if (parentTitle) { - title = `${parentTitle}.${tempTitle}` - } - let required = false; - if($required) { - required = true; - } - fields.push({ - field, - title, - type, - required - }) - // TODO 子表单 需要处理子表单字段 - // if (type === 'group' && rule.props?.rule && Array.isArray(rule.props.rule)) { - // // 解析子表单的字段 - // rule.props.rule.forEach((item) => { - // parseFields(item, fieldsPermission, title) - // }) - // } - } - if (children && Array.isArray(children)) { - children.forEach((rule) => { - parseFields(rule, fields) - }) - } - } + + // 获取表单的所有字段,作为下拉框选项 const formFieldOptions = parseFormCreateFields(unref(formFields)) @@ -117,50 +130,8 @@ export function useFormFieldsPermission(defaultPermission: FieldPermissionType) * @description 获取表单的字段 */ export function useFormFields() { - // 解析后的表单字段 const formFields = inject>('formFields') // 流程表单字段 - const parseFormFields = () => { - const parsedFormFields: Array> = [] - if (formFields) { - formFields.value.forEach((fieldStr: string) => { - parseField(JSON.parse(fieldStr), parsedFormFields) - }) - } - return parsedFormFields - } - // 解析字段。 - const parseField = ( - rule: Record, - parsedFormFields: Array>, - parentTitle: string = '' - ) => { - const { field, title: tempTitle, children, type } = rule - if (field && tempTitle) { - let title = tempTitle - if (parentTitle) { - title = `${parentTitle}.${tempTitle}` - } - parsedFormFields.push({ - field, - title, - type - }) - // TODO 子表单 需要处理子表单字段 - // if (type === 'group' && rule.props?.rule && Array.isArray(rule.props.rule)) { - // // 解析子表单的字段 - // rule.props.rule.forEach((item) => { - // parseFieldsSetDefaultPermission(item, fieldsPermission, title) - // }) - // } - } - if (children && Array.isArray(children)) { - children.forEach((rule) => { - parseField(rule, parsedFormFields) - }) - } - } - - return parseFormFields() + return parseFormCreateFields(unref(formFields)) } export type UserTaskFormType = { @@ -174,7 +145,7 @@ export type UserTaskFormType = { userGroups?: number[] // 用户组 postIds?: number[] // 岗位 expression?: string // 流程表达式 - userFieldOnForm?: string // 表单内成员字段 + userFieldOnForm?: string // 表单内用户字段 approveRatio?: number rejectHandlerType?: RejectHandlerType returnNodeId?: string @@ -197,7 +168,7 @@ export type CopyTaskFormType = { userIds?: number[] // 用户 userGroups?: number[] // 用户组 postIds?: number[] // 岗位 - userFieldOnForm?: string // 表单内成员字段 + userFieldOnForm?: string // 表单内用户字段 expression?: string // 流程表达式 } @@ -211,6 +182,7 @@ export function useNodeForm(nodeType: NodeType) { const deptOptions = inject>('deptList') // 部门列表 const userGroupOptions = inject>('userGroupList') // 用户组列表 const deptTreeOptions = inject('deptTree') // 部门树 + const formFields = inject>('formFields') // 流程表单字段 const configForm = ref() if (nodeType === NodeType.USER_TASK_NODE) { configForm.value = { @@ -306,9 +278,11 @@ export function useNodeForm(nodeType: NodeType) { } } - // 表单内成员字段 + // 表单内用户字段 if (configForm.value?.candidateStrategy === CandidateStrategy.USER_FIELD_ON_FORM) { - showText = `表单内用户字段` + const formFieldOptions = parseFormCreateFields(unref(formFields)) + const item = formFieldOptions.find((item) => item.field === configForm.value?.userFieldOnForm) + showText = `表单用户:${item?.title}` } // 发起人自选 diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue index 422ac992..5df0d882 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue @@ -124,7 +124,7 @@ @@ -246,7 +246,7 @@ const activeTabName = ref('user') const { formType, fieldsPermissionConfig, formFieldOptions, getNodeConfigFormFields } = useFormFieldsPermission( FieldPermissionType.READ ) -// 表单内成员字段选项, 必须是必填和用户选择器 +// 表单内用户字段选项, 必须是必填和用户选择器 const userFieldOnFormOptions = computed(() => { return formFieldOptions.filter( (item) => item.required && item.type === 'UserSelect' @@ -262,7 +262,7 @@ const formRules = reactive({ deptIds: [{ required: true, message: '部门不能为空', trigger: 'change' }], userGroups: [{ required: true, message: '用户组不能为空', trigger: 'change' }], postIds: [{ required: true, message: '岗位不能为空', trigger: 'change' }], - userFieldOnForm: [{ required: true, message: '表单内成员字段为空', trigger: 'change' }], + userFieldOnForm: [{ required: true, message: '表单内用户字段不能为空', trigger: 'change' }], expression: [{ required: true, message: '流程表达式不能为空', trigger: 'blur' }] }) diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue index 7d8d7708..400ead2c 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue @@ -159,7 +159,7 @@ @@ -499,7 +499,7 @@ const activeTabName = ref('user') const { formType, fieldsPermissionConfig, formFieldOptions, getNodeConfigFormFields } = useFormFieldsPermission( FieldPermissionType.READ ) -// 表单内成员字段选项, 必须是必填和用户选择器 +// 表单内用户字段选项, 必须是必填和用户选择器 const userFieldOnFormOptions = computed(() => { return formFieldOptions.filter( (item) => item.required && item.type === 'UserSelect' @@ -518,7 +518,7 @@ const formRules = reactive({ roleIds: [{ required: true, message: '角色不能为空', trigger: 'change' }], deptIds: [{ required: true, message: '部门不能为空', trigger: 'change' }], userGroups: [{ required: true, message: '用户组不能为空', trigger: 'change' }], - userFieldOnForm: [{ required: true, message: '表单内成员字段为空', trigger: 'change' }], + userFieldOnForm: [{ required: true, message: '表单内用户字段不能为空', trigger: 'change' }], postIds: [{ required: true, message: '岗位不能为空', trigger: 'change' }], expression: [{ required: true, message: '流程表达式不能为空', trigger: 'blur' }], approveMethod: [{ required: true, message: '多人审批方式不能为空', trigger: 'change' }], From 2fe28af05d6d8d736255cb3e10ad52f3052fa799 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Mon, 18 Nov 2024 09:03:45 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E3=80=90=E5=8A=9F=E8=83=BD=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E3=80=91=E5=80=99=E9=80=89=E4=BA=BA=E7=AD=96=E7=95=A5?= =?UTF-8?q?=EF=BC=9A=E6=96=B0=E5=A2=9E=E8=A1=A8=E5=8D=95=E9=83=A8=E9=97=A8?= =?UTF-8?q?=E8=B4=9F=E8=B4=A3=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SimpleProcessDesignerV2/src/consts.ts | 6 +- .../SimpleProcessDesignerV2/src/node.ts | 22 ++++++ .../src/nodes-config/CopyTaskNodeConfig.vue | 56 ++++++++++++++- .../src/nodes-config/UserTaskNodeConfig.vue | 68 +++++++++++++------ 4 files changed, 127 insertions(+), 25 deletions(-) diff --git a/src/components/SimpleProcessDesignerV2/src/consts.ts b/src/components/SimpleProcessDesignerV2/src/consts.ts index a712fb13..9b78fa11 100644 --- a/src/components/SimpleProcessDesignerV2/src/consts.ts +++ b/src/components/SimpleProcessDesignerV2/src/consts.ts @@ -145,11 +145,14 @@ export enum CandidateStrategy { * 指定用户组 */ USER_GROUP = 40, - /** * 表单内用户字段 */ USER_FIELD_ON_FORM = 50, + /** + * 表单内部门负责人 + */ + DEPT_LEADER_ON_FORM = 51, /** * 流程表达式 */ @@ -430,6 +433,7 @@ export const CANDIDATE_STRATEGY: DictDataVO[] = [ { label: '发起人连续部门负责人', value: CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER }, { label: '用户组', value: CandidateStrategy.USER_GROUP }, { label: '表单内用户字段', value: CandidateStrategy.USER_FIELD_ON_FORM }, + { label: '表单内部门负责人', value: CandidateStrategy.DEPT_LEADER_ON_FORM }, { label: '流程表达式', value: CandidateStrategy.EXPRESSION } ] // 审批节点 的审批类型 diff --git a/src/components/SimpleProcessDesignerV2/src/node.ts b/src/components/SimpleProcessDesignerV2/src/node.ts index 53e2b11f..167e2c5d 100644 --- a/src/components/SimpleProcessDesignerV2/src/node.ts +++ b/src/components/SimpleProcessDesignerV2/src/node.ts @@ -146,6 +146,7 @@ export type UserTaskFormType = { postIds?: number[] // 岗位 expression?: string // 流程表达式 userFieldOnForm?: string // 表单内用户字段 + deptFieldOnForm?: string // 表单内部门字段 approveRatio?: number rejectHandlerType?: RejectHandlerType returnNodeId?: string @@ -169,6 +170,7 @@ export type CopyTaskFormType = { userGroups?: number[] // 用户组 postIds?: number[] // 岗位 userFieldOnForm?: string // 表单内用户字段 + deptFieldOnForm?: string // 表单内部门字段 expression?: string // 流程表达式 } @@ -285,6 +287,11 @@ export function useNodeForm(nodeType: NodeType) { showText = `表单用户:${item?.title}` } + // 表单内部门负责人 + if (configForm.value?.candidateStrategy === CandidateStrategy.DEPT_LEADER_ON_FORM) { + showText = `表单内部门负责人` + } + // 发起人自选 if (configForm.value?.candidateStrategy === CandidateStrategy.START_USER_SELECT) { showText = `发起人自选` @@ -353,6 +360,13 @@ export function useNodeForm(nodeType: NodeType) { candidateParam = deptIds.concat('|' + configForm.value.deptLevel + '') break } + // 表单内部门的负责人 + case CandidateStrategy.DEPT_LEADER_ON_FORM: { + // 候选人参数格式: | 分隔 。左边为表单内部门字段。 右边为部门层级 + const deptFieldOnForm = configForm.value.deptFieldOnForm! + candidateParam = deptFieldOnForm.concat('|' + configForm.value.deptLevel + '') + break + } default: break } @@ -405,6 +419,14 @@ export function useNodeForm(nodeType: NodeType) { configForm.value.deptLevel = +paramArray[1] break } + // 表单内的部门负责人 + case CandidateStrategy.DEPT_LEADER_ON_FORM: { + // 候选人参数格式: | 分隔 。左边为表单内的部门字段。 右边为部门层级 + const paramArray = candidateParam.split('|') + configForm.value.deptFieldOnForm = paramArray[0] + configForm.value.deptLevel = +paramArray[1] + break + } default: break } diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue index 5df0d882..91ac5b87 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue @@ -60,7 +60,8 @@ + + + + + + + + + + { + let label = '部门负责人来源' + if (configForm.value.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER) { + label = label + '(指定部门向上)' + } else { + label = label + '(发起人部门向上)' + } + return label +}) // 抽屉配置 const { settingVisible, closeDrawer, openDrawer } = useDrawer() // 当前节点 @@ -252,6 +297,12 @@ const userFieldOnFormOptions = computed(() => { (item) => item.required && item.type === 'UserSelect' ) }) +// 表单内部门字段选项, 必须是必填和部门选择器 +const deptFieldOnFormOptions = computed(() => { + return formFieldOptions.filter( + (item) => item.required && item.type === 'DeptSelect' + ) +}) // 抄送人表单配置 const formRef = ref() // 表单 Ref // 表单校验规则 @@ -263,6 +314,7 @@ const formRules = reactive({ userGroups: [{ required: true, message: '用户组不能为空', trigger: 'change' }], postIds: [{ required: true, message: '岗位不能为空', trigger: 'change' }], userFieldOnForm: [{ required: true, message: '表单内用户字段不能为空', trigger: 'change' }], + deptFieldOnForm: [{ required: true, message: '表单内部门字段不能为空', trigger: 'change' }], expression: [{ required: true, message: '流程表达式不能为空', trigger: 'blur' }] }) diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue index 400ead2c..02ec582c 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue @@ -56,7 +56,6 @@ - - - - - - + + + + + + + + + + { let label = '部门负责人来源' if (configForm.value.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER) { label = label + '(指定部门向上)' + } else if (configForm.value.candidateStrategy == CandidateStrategy.DEPT_LEADER_ON_FORM) { + label = label + '(表单内部门向上)' } else { - label = label + '(发起人部门向上)' + label = label + '(发起人部门向上)' } return label }) @@ -505,6 +521,12 @@ const userFieldOnFormOptions = computed(() => { (item) => item.required && item.type === 'UserSelect' ) }) +// 表单内部门字段选项, 必须是必填和部门选择器 +const deptFieldOnFormOptions = computed(() => { + return formFieldOptions.filter( + (item) => item.required && item.type === 'DeptSelect' + ) +}) // 操作按钮设置 const { buttonsSetting, btnDisplayNameEdit, changeBtnDisplayName, btnDisplayNameBlurEvent } = useButtonsSetting() @@ -519,6 +541,7 @@ const formRules = reactive({ deptIds: [{ required: true, message: '部门不能为空', trigger: 'change' }], userGroups: [{ required: true, message: '用户组不能为空', trigger: 'change' }], userFieldOnForm: [{ required: true, message: '表单内用户字段不能为空', trigger: 'change' }], + deptFieldOnForm: [{ required: true, message: '表单内部门字段不能为空', trigger: 'change' }], postIds: [{ required: true, message: '岗位不能为空', trigger: 'change' }], expression: [{ required: true, message: '流程表达式不能为空', trigger: 'blur' }], approveMethod: [{ required: true, message: '多人审批方式不能为空', trigger: 'change' }], @@ -554,7 +577,8 @@ const changeCandidateStrategy = () => { configForm.value.postIds = [] configForm.value.userGroups = [] configForm.value.deptLevel = 1 - configForm.value.userFieldOnForm = '' + configForm.value.userFieldOnForm = '' + configForm.value.deptFieldOnForm = '' configForm.value.approveMethod = ApproveMethodType.SEQUENTIAL_APPROVE }