From 8a97a33a291ee8099821f384773e162d11f62693 Mon Sep 17 00:00:00 2001 From: jinmh716 Date: Tue, 5 Nov 2024 17:30:23 +0800 Subject: [PATCH 01/15] =?UTF-8?q?=E3=80=90=E4=BC=98=E5=8C=96=E3=80=91?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=87=AA=E5=AE=9A=E4=B9=89=E6=8C=87=E4=BB=A4?= =?UTF-8?q?=E6=B6=88=E9=99=A4IDE=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + web-types.json | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 web-types.json diff --git a/package.json b/package.json index ba540009..a4775dca 100644 --- a/package.json +++ b/package.json @@ -143,6 +143,7 @@ "url": "https://gitee.com/yudaocode/yudao-ui-admin-vue3/issues" }, "homepage": "https://gitee.com/yudaocode/yudao-ui-admin-vue3", + "web-types": "./web-types.json", "engines": { "node": ">= 16.0.0", "pnpm": ">=8.6.0" diff --git a/web-types.json b/web-types.json new file mode 100644 index 00000000..602f2129 --- /dev/null +++ b/web-types.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://json.schemastore.org/web-types", + "framework": "vue", + "name": "name written in package.json", + "version": "version written in package.json", + "contributions": { + "html": { + "types-syntax": "typescript", + "attributes": [ + { + "name": "v-hasPermi" + }, + { + "name": "v-hasRole" + } + ] + } + } +} From 2c8125e218d38fe4a515b8b33d140234bd0af3f1 Mon Sep 17 00:00:00 2001 From: panda <1565636758@qq.com> Date: Mon, 11 Nov 2024 15:19:05 +0800 Subject: [PATCH 02/15] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=B2=A1=E6=9C=89z-ind?= =?UTF-8?q?ex=E4=BC=9A=E8=A2=AB=E8=A1=A8=E6=A0=BC=E5=B1=82=E8=A6=86?= =?UTF-8?q?=E7=9B=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layout/components/Setting/src/Setting.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/layout/components/Setting/src/Setting.vue b/src/layout/components/Setting/src/Setting.vue index 306cb238..2973674b 100644 --- a/src/layout/components/Setting/src/Setting.vue +++ b/src/layout/components/Setting/src/Setting.vue @@ -297,5 +297,6 @@ $prefix-cls: #{$namespace}-setting; .#{$prefix-cls} { border-radius: 6px 0 0 6px; + z-index: 1200;/*修正没有z-index会被表格层覆盖,值不要超过4000*/ } From 046e6ce5a765486880298f4f600e7c113a522217 Mon Sep 17 00:00:00 2001 From: LesanOuO <1960681385@qq.com> Date: Sat, 16 Nov 2024 14:37:42 +0800 Subject: [PATCH 03/15] =?UTF-8?q?fix:=20=E5=BD=93id=E4=B8=BA=E9=9B=AA?= =?UTF-8?q?=E8=8A=B1id=E6=97=B6=E6=97=A0=E6=B3=95=E4=BC=A0=E9=80=92id?= =?UTF-8?q?=E8=87=B3=E8=B7=AF=E7=94=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/bpm/form/index.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/views/bpm/form/index.vue b/src/views/bpm/form/index.vue index 3d542c80..46edd8f9 100644 --- a/src/views/bpm/form/index.vue +++ b/src/views/bpm/form/index.vue @@ -143,8 +143,9 @@ const openForm = (id?: number) => { const toRouter: { name: string; query?: { id: number } } = { name: 'BpmFormEditor' } + console.log(typeof id) // 表单新建的时候id传的是event需要排除 - if (typeof id === 'number') { + if (typeof id === 'number' || typeof id === 'string') { toRouter.query = { id } From da0a7801639a9335f87ba25eb7a160d85c1f76c9 Mon Sep 17 00:00:00 2001 From: LesanOuO <1960681385@qq.com> Date: Sat, 16 Nov 2024 14:44:14 +0800 Subject: [PATCH 04/15] =?UTF-8?q?fix:=20=E9=80=89=E4=B8=AD=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E6=97=A0=E6=B3=95=E6=96=B0=E5=A2=9E=E5=B1=9E=E6=80=A7?= =?UTF-8?q?,=E6=8A=A5=E9=94=99filter=20is=20not=20a=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../package/penal/properties/ElementProperties.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/bpmnProcessDesigner/package/penal/properties/ElementProperties.vue b/src/components/bpmnProcessDesigner/package/penal/properties/ElementProperties.vue index 494b3d97..016cdf6c 100644 --- a/src/components/bpmnProcessDesigner/package/penal/properties/ElementProperties.vue +++ b/src/components/bpmnProcessDesigner/package/penal/properties/ElementProperties.vue @@ -80,7 +80,7 @@ const resetAttributesList = () => { otherExtensionList.value = [] // 其他扩展配置 bpmnElementProperties.value = // bpmnElement.value.businessObject?.extensionElements?.filter((ex) => { - bpmnElement.value.businessObject?.extensionElements?.values.filter((ex) => { + bpmnElement.value.businessObject?.extensionElements?.values?.filter((ex) => { if (ex.$type !== `${prefix}:Properties`) { otherExtensionList.value.push(ex) } From 6ac0ee584491ef1cc2c2dd7773b73898ec51ddf0 Mon Sep 17 00:00:00 2001 From: LesanOuO <1960681385@qq.com> Date: Sat, 16 Nov 2024 17:58:34 +0800 Subject: [PATCH 05/15] =?UTF-8?q?fix:=20=E5=89=8D=E7=AB=AFint=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=AF=BC=E8=87=B4=E7=B2=BE=E5=BA=A6=E4=B8=A2=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bpmnProcessDesigner/package/penal/form/ElementForm.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/bpmnProcessDesigner/package/penal/form/ElementForm.vue b/src/components/bpmnProcessDesigner/package/penal/form/ElementForm.vue index 33f0bc09..3bb7d660 100644 --- a/src/components/bpmnProcessDesigner/package/penal/form/ElementForm.vue +++ b/src/components/bpmnProcessDesigner/package/penal/form/ElementForm.vue @@ -268,9 +268,9 @@ const bpmnInstances = () => (window as any)?.bpmnInstances const resetFormList = () => { bpmnELement.value = bpmnInstances().bpmnElement formKey.value = bpmnELement.value.businessObject.formKey - if (formKey.value?.length > 0) { - formKey.value = parseInt(formKey.value) - } + // if (formKey.value?.length > 0) { + // formKey.value = parseInt(formKey.value) + // } // 获取元素扩展属性 或者 创建扩展属性 elExtensionElements.value = bpmnELement.value.businessObject.get('extensionElements') || 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 06/15] =?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 eefabf34a50b884e59926619ef1bcb343444e153 Mon Sep 17 00:00:00 2001 From: LesanOuO <1960681385@qq.com> Date: Sun, 17 Nov 2024 14:43:52 +0800 Subject: [PATCH 07/15] =?UTF-8?q?feat:=20bpmn=E8=AE=BE=E8=AE=A1=E5=99=A8?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0assignStartUserHandlerType=E9=80=82=E9=85=8DS?= =?UTF-8?q?imple=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../descriptor/flowableDescriptor.json | 14 ++++ .../package/penal/PropertiesPanel.vue | 4 + .../custom-config/ElementCustomConfig.vue | 81 +++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 src/components/bpmnProcessDesigner/package/penal/custom-config/ElementCustomConfig.vue diff --git a/src/components/bpmnProcessDesigner/package/designer/plugins/descriptor/flowableDescriptor.json b/src/components/bpmnProcessDesigner/package/designer/plugins/descriptor/flowableDescriptor.json index 4ea632a0..ee8e0d22 100644 --- a/src/components/bpmnProcessDesigner/package/designer/plugins/descriptor/flowableDescriptor.json +++ b/src/components/bpmnProcessDesigner/package/designer/plugins/descriptor/flowableDescriptor.json @@ -1211,6 +1211,20 @@ "isAttr": true } ] + }, + { + "name": "AssignStartUserHandlerType", + "superClass": ["Element"], + "meta": { + "allowedIn": ["bpmn:StartEvent", "bpmn:UserTask"] + }, + "properties": [ + { + "name": "value", + "type": "Integer", + "isBody": true + } + ] } ], "emumerations": [] diff --git a/src/components/bpmnProcessDesigner/package/penal/PropertiesPanel.vue b/src/components/bpmnProcessDesigner/package/penal/PropertiesPanel.vue index 86a1cf74..5cd76383 100644 --- a/src/components/bpmnProcessDesigner/package/penal/PropertiesPanel.vue +++ b/src/components/bpmnProcessDesigner/package/penal/PropertiesPanel.vue @@ -54,6 +54,10 @@ + + + + diff --git a/src/components/bpmnProcessDesigner/package/penal/custom-config/ElementCustomConfig.vue b/src/components/bpmnProcessDesigner/package/penal/custom-config/ElementCustomConfig.vue new file mode 100644 index 00000000..4b6cb527 --- /dev/null +++ b/src/components/bpmnProcessDesigner/package/penal/custom-config/ElementCustomConfig.vue @@ -0,0 +1,81 @@ + + + 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 08/15] =?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 09/15] =?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 } From c119e910d038083dd7892e3ecfb339f6a04846dc Mon Sep 17 00:00:00 2001 From: preschooler Date: Mon, 18 Nov 2024 11:38:42 +0800 Subject: [PATCH 10/15] =?UTF-8?q?=F0=9F=90=9E=20fix:=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=AF=B9=20axios=20=E7=9A=84=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/login/oauth2/index.ts | 2 +- src/config/axios/index.ts | 12 ++++-------- src/config/axios/service.ts | 30 +++--------------------------- 3 files changed, 8 insertions(+), 36 deletions(-) diff --git a/src/api/login/oauth2/index.ts b/src/api/login/oauth2/index.ts index aef1820d..f4a67fbe 100644 --- a/src/api/login/oauth2/index.ts +++ b/src/api/login/oauth2/index.ts @@ -27,7 +27,7 @@ export const authorize = ( return request.post({ url: '/system/oauth2/authorize', headers: { - 'Content-type': 'application/x-www-form-urlencoded' + 'Content-Type': 'application/x-www-form-urlencoded' }, params: { response_type: responseType, diff --git a/src/config/axios/index.ts b/src/config/axios/index.ts index 79e558da..07719a20 100644 --- a/src/config/axios/index.ts +++ b/src/config/axios/index.ts @@ -5,16 +5,12 @@ import { config } from './config' const { default_headers } = config const request = (option: any) => { - const { url, method, params, data, headersType, responseType, ...config } = option + const { headersType, headers, ...otherOption } = option return service({ - url: url, - method, - params, - data, - ...config, - responseType: responseType, + ...otherOption, headers: { - 'Content-Type': headersType || default_headers + 'Content-Type': headersType || default_headers, + ...headers } }) } diff --git a/src/config/axios/service.ts b/src/config/axios/service.ts index 3df813f2..f0eccc56 100644 --- a/src/config/axios/service.ts +++ b/src/config/axios/service.ts @@ -1,13 +1,6 @@ -import axios, { - AxiosError, - AxiosInstance, - AxiosRequestHeaders, - AxiosResponse, - InternalAxiosRequestConfig -} from 'axios' +import axios, { AxiosError, AxiosInstance, AxiosResponse, InternalAxiosRequestConfig } from 'axios' import { ElMessage, ElMessageBox, ElNotification } from 'element-plus' -import qs from 'qs' import { config } from '@/config/axios/config' import { getAccessToken, getRefreshToken, getTenantId, removeToken, setToken } from '@/utils/auth' import errorCode from './errorCode' @@ -52,29 +45,12 @@ service.interceptors.request.use( } }) if (getAccessToken() && !isToken) { - ;(config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token + config.headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token } // 设置租户 if (tenantEnable && tenantEnable === 'true') { const tenantId = getTenantId() - if (tenantId) (config as Recordable).headers['tenant-id'] = tenantId - } - const params = config.params || {} - const data = config.data || false - if ( - config.method?.toUpperCase() === 'POST' && - (config.headers as AxiosRequestHeaders)['Content-Type'] === - 'application/x-www-form-urlencoded' - ) { - config.data = qs.stringify(data) - } - // get参数编码 - if (config.method?.toUpperCase() === 'GET' && params) { - config.params = {} - const paramsStr = qs.stringify(params, { allowDots: true }) - if (paramsStr) { - config.url = config.url + '?' + paramsStr - } + if (tenantId) config.headers['tenant-id'] = tenantId } return config }, From 6cd64291029114acd9e8fc27ec8bd7243edf82ab Mon Sep 17 00:00:00 2001 From: preschooler Date: Tue, 19 Nov 2024 19:24:49 +0800 Subject: [PATCH 11/15] =?UTF-8?q?=F0=9F=90=9E=20fix:=E6=81=A2=E5=A4=8D=20a?= =?UTF-8?q?xios=20=E8=87=AA=E5=AE=9A=E4=B9=89=E5=8F=82=E6=95=B0=E5=BA=8F?= =?UTF-8?q?=E5=88=97=E5=8C=96=E5=87=BD=E6=95=B0=EF=BC=8C=E5=B9=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=89=80=E6=9C=89=E8=AF=B7=E6=B1=82=E7=9A=84=20params?= =?UTF-8?q?=20=E8=87=AA=E5=AE=9A=E4=B9=89=E5=BA=8F=E5=88=97=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=E5=88=B7=E6=96=B0=20token=20?= =?UTF-8?q?=E5=90=8E=E4=BA=8C=E6=AC=A1=E8=AF=B7=E6=B1=82=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E4=B8=A2=E5=A4=B1=E9=97=AE=E9=A2=98=EF=BC=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20GET=20=E8=AF=B7=E6=B1=82=E7=BC=93=E5=AD=98=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config/axios/service.ts | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/config/axios/service.ts b/src/config/axios/service.ts index f0eccc56..ae3845c0 100644 --- a/src/config/axios/service.ts +++ b/src/config/axios/service.ts @@ -1,6 +1,7 @@ import axios, { AxiosError, AxiosInstance, AxiosResponse, InternalAxiosRequestConfig } from 'axios' import { ElMessage, ElMessageBox, ElNotification } from 'element-plus' +import qs from 'qs' import { config } from '@/config/axios/config' import { getAccessToken, getRefreshToken, getTenantId, removeToken, setToken } from '@/utils/auth' import errorCode from './errorCode' @@ -30,7 +31,11 @@ const whiteList: string[] = ['/login', '/refresh-token'] const service: AxiosInstance = axios.create({ baseURL: base_url, // api 的 base_url timeout: request_timeout, // 请求超时时间 - withCredentials: false // 禁用 Cookie 等信息 + withCredentials: false, // 禁用 Cookie 等信息 + // 自定义参数序列化函数 + paramsSerializer: (params) => { + return qs.stringify(params, { allowDots: true }) + } }) // request拦截器 @@ -52,6 +57,21 @@ service.interceptors.request.use( const tenantId = getTenantId() if (tenantId) config.headers['tenant-id'] = tenantId } + const method = config.method?.toUpperCase() + // 防止 GET 请求缓存 + if (method === 'GET') { + config.headers['Cache-Control'] = 'no-cache' + config.headers['Pragma'] = 'no-cache' + } + // 自定义参数序列化函数 + else if (method === 'POST') { + const contentType = config.headers['Content-Type'] || config.headers['content-type'] + if (contentType === 'application/x-www-form-urlencoded') { + if (config.data && typeof config.data !== 'string') { + config.data = qs.stringify(config.data) + } + } + } return config }, (error: AxiosError) => { From 12bd71e70b5ca739476091c191a29e51382215c3 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 19 Nov 2024 21:24:11 +0800 Subject: [PATCH 12/15] =?UTF-8?q?=E3=80=90=E4=BB=A3=E7=A0=81=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E3=80=91=E5=B7=A5=E4=BD=9C=E6=B5=81=EF=BC=9A=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E9=80=89=E6=8B=A9=E5=AE=A1=E6=89=B9=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/useApiSelect.tsx | 1 - .../SimpleProcessDesignerV2/src/consts.ts | 12 ++--- .../SimpleProcessDesignerV2/src/node.ts | 45 +++++++++---------- .../src/nodes-config/CopyTaskNodeConfig.vue | 30 +++++-------- .../src/nodes-config/UserTaskNodeConfig.vue | 31 ++++++------- 5 files changed, 54 insertions(+), 65 deletions(-) diff --git a/src/components/FormCreate/src/components/useApiSelect.tsx b/src/components/FormCreate/src/components/useApiSelect.tsx index 741b1d48..8ff95fb0 100644 --- a/src/components/FormCreate/src/components/useApiSelect.tsx +++ b/src/components/FormCreate/src/components/useApiSelect.tsx @@ -185,7 +185,6 @@ export const useApiSelect = (option: ApiSelectProps) => { ) } - // debugger return ( { }) } // 固定添加发起人 ID 字段 - result.unshift( { + result.unshift({ field: ProcessVariableEnum.START_USER_ID, title: '发起人', type: 'UserSelect', @@ -46,6 +46,7 @@ const parseFormCreateFields = (formFields?: string[]) => { return result } +// TODO @jason:parse 方法,是不是搞到 formCreate.ts。统一维护管理 const parseFields = ( rule: Record, fields: Array>, @@ -57,9 +58,10 @@ const parseFields = ( if (parentTitle) { title = `${parentTitle}.${tempTitle}` } - let required = false; - if($required) { - required = true; + // TODO @jason:按照微信讨论的,非 $required 显示,但是 disable 不可选择 + let required = false + if ($required) { + required = true } fields.push({ field, @@ -82,7 +84,6 @@ const parseFields = ( } } - /** * @description 表单数据权限配置,用于发起人节点 、审批节点、抄送节点 */ @@ -103,19 +104,17 @@ export function useFormFieldsPermission(defaultPermission: FieldPermissionType) const getDefaultFieldsPermission = (formFields?: string[]) => { let defaultFieldsPermission: Array> = [] if (formFields) { - defaultFieldsPermission = parseFormCreateFields(formFields).map( item => { + defaultFieldsPermission = parseFormCreateFields(formFields).map((item) => { return { field: item.field, title: item.title, permission: defaultPermission } - }); + }) } return defaultFieldsPermission } - - - + // 获取表单的所有字段,作为下拉框选项 const formFieldOptions = parseFormCreateFields(unref(formFields)) @@ -281,14 +280,14 @@ export function useNodeForm(nodeType: NodeType) { } // 表单内用户字段 - if (configForm.value?.candidateStrategy === CandidateStrategy.USER_FIELD_ON_FORM) { + if (configForm.value?.candidateStrategy === CandidateStrategy.FORM_USER) { const formFieldOptions = parseFormCreateFields(unref(formFields)) const item = formFieldOptions.find((item) => item.field === configForm.value?.userFieldOnForm) showText = `表单用户:${item?.title}` } // 表单内部门负责人 - if (configForm.value?.candidateStrategy === CandidateStrategy.DEPT_LEADER_ON_FORM) { + if (configForm.value?.candidateStrategy === CandidateStrategy.FORM_DEPT_LEADER) { showText = `表单内部门负责人` } @@ -338,7 +337,7 @@ export function useNodeForm(nodeType: NodeType) { case CandidateStrategy.USER_GROUP: candidateParam = configForm.value.userGroups!.join(',') break - case CandidateStrategy.USER_FIELD_ON_FORM: + case CandidateStrategy.FORM_USER: candidateParam = configForm.value.userFieldOnForm! break case CandidateStrategy.EXPRESSION: @@ -361,7 +360,7 @@ export function useNodeForm(nodeType: NodeType) { break } // 表单内部门的负责人 - case CandidateStrategy.DEPT_LEADER_ON_FORM: { + case CandidateStrategy.FORM_DEPT_LEADER: { // 候选人参数格式: | 分隔 。左边为表单内部门字段。 右边为部门层级 const deptFieldOnForm = configForm.value.deptFieldOnForm! candidateParam = deptFieldOnForm.concat('|' + configForm.value.deptLevel + '') @@ -396,7 +395,7 @@ export function useNodeForm(nodeType: NodeType) { case CandidateStrategy.USER_GROUP: configForm.value.userGroups = candidateParam.split(',').map((item) => +item) break - case CandidateStrategy.USER_FIELD_ON_FORM: + case CandidateStrategy.FORM_USER: configForm.value.userFieldOnForm = candidateParam break case CandidateStrategy.EXPRESSION: @@ -420,7 +419,7 @@ export function useNodeForm(nodeType: NodeType) { break } // 表单内的部门负责人 - case CandidateStrategy.DEPT_LEADER_ON_FORM: { + case CandidateStrategy.FORM_DEPT_LEADER: { // 候选人参数格式: | 分隔 。左边为表单内的部门字段。 右边为部门层级 const paramArray = candidateParam.split('|') configForm.value.deptFieldOnForm = paramArray[0] @@ -512,22 +511,22 @@ export function useNodeName2(node: Ref, nodeType: NodeType) { /** * @description 根据节点任务状态,获取节点任务状态样式 */ -export function useTaskStatusClass(taskStatus: TaskStatusEnum | undefined) : string { +export function useTaskStatusClass(taskStatus: TaskStatusEnum | undefined): string { if (!taskStatus) { return '' } - if (taskStatus === TaskStatusEnum.APPROVE ) { + if (taskStatus === TaskStatusEnum.APPROVE) { return 'status-pass' } - if (taskStatus === TaskStatusEnum.RUNNING ) { + if (taskStatus === TaskStatusEnum.RUNNING) { return 'status-running' } - if (taskStatus === TaskStatusEnum.REJECT ) { + if (taskStatus === TaskStatusEnum.REJECT) { return 'status-reject' } - if (taskStatus === TaskStatusEnum.CANCEL ) { + if (taskStatus === TaskStatusEnum.CANCEL) { return 'status-cancel' } - - return ''; + + return '' } diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue index 91ac5b87..eeb51bd4 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue @@ -124,13 +124,13 @@ { - return formFieldOptions.filter( - (item) => item.required && item.type === 'UserSelect' - ) + return formFieldOptions.filter((item) => item.required && item.type === 'UserSelect') }) // 表单内部门字段选项, 必须是必填和部门选择器 const deptFieldOnFormOptions = computed(() => { - return formFieldOptions.filter( - (item) => item.required && item.type === 'DeptSelect' - ) + return formFieldOptions.filter((item) => item.required && item.type === 'DeptSelect') }) // 抄送人表单配置 const formRef = ref() // 表单 Ref @@ -332,9 +328,7 @@ const { const configForm = tempConfigForm as Ref // 抄送人策略, 去掉发起人自选 和 发起人自己 const copyUserStrategies = computed(() => { - return CANDIDATE_STRATEGY.filter( - (item) => item.value !== CandidateStrategy.START_USER - ) + return CANDIDATE_STRATEGY.filter((item) => item.value !== CandidateStrategy.START_USER) }) // 改变抄送人设置策略 const changeCandidateStrategy = () => { diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue index 02ec582c..ebb41278 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue @@ -138,13 +138,13 @@ { let label = '部门负责人来源' if (configForm.value.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER) { label = label + '(指定部门向上)' - } else if (configForm.value.candidateStrategy == CandidateStrategy.DEPT_LEADER_ON_FORM) { + } else if (configForm.value.candidateStrategy == CandidateStrategy.FORM_DEPT_LEADER) { label = label + '(表单内部门向上)' } else { - label = label + '(发起人部门向上)' + label = label + '(发起人部门向上)' } return label }) @@ -512,20 +513,15 @@ const { nodeName, showInput, clickIcon, blurEvent } = useNodeName(NodeType.USER_ // 激活的 Tab 标签页 const activeTabName = ref('user') // 表单字段权限设置 -const { formType, fieldsPermissionConfig, formFieldOptions, getNodeConfigFormFields } = useFormFieldsPermission( - FieldPermissionType.READ -) +const { formType, fieldsPermissionConfig, formFieldOptions, getNodeConfigFormFields } = + useFormFieldsPermission(FieldPermissionType.READ) // 表单内用户字段选项, 必须是必填和用户选择器 const userFieldOnFormOptions = computed(() => { - return formFieldOptions.filter( - (item) => item.required && item.type === 'UserSelect' - ) + return formFieldOptions.filter((item) => item.required && item.type === 'UserSelect') }) // 表单内部门字段选项, 必须是必填和部门选择器 const deptFieldOnFormOptions = computed(() => { - return formFieldOptions.filter( - (item) => item.required && item.type === 'DeptSelect' - ) + return formFieldOptions.filter((item) => item.required && item.type === 'DeptSelect') }) // 操作按钮设置 const { buttonsSetting, btnDisplayNameEdit, changeBtnDisplayName, btnDisplayNameBlurEvent } = @@ -577,6 +573,7 @@ const changeCandidateStrategy = () => { configForm.value.postIds = [] configForm.value.userGroups = [] configForm.value.deptLevel = 1 + // TODO @jason:是不是 userFieldOnForm => formUser;deptFieldOnForm => formDeptLeader;原因是:想通前缀,好管理点 configForm.value.userFieldOnForm = '' configForm.value.deptFieldOnForm = '' configForm.value.approveMethod = ApproveMethodType.SEQUENTIAL_APPROVE From 2d1b31a841f76ac63732fb4dc1079990b1fd435b Mon Sep 17 00:00:00 2001 From: shifeng Date: Thu, 21 Nov 2024 08:34:43 +0800 Subject: [PATCH 13/15] =?UTF-8?q?=E5=88=A4=E6=96=AD=E5=A6=82=E6=9E=9C?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E6=9D=83=E9=99=90=E8=AE=BE=E7=BD=AE=E4=B8=8D?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E5=8F=AF=E7=BC=96=E8=BE=91=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=EF=BC=8C=E9=81=BF=E5=85=8D=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E8=A2=AB=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/bpm/processInstance/detail/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/bpm/processInstance/detail/index.vue b/src/views/bpm/processInstance/detail/index.vue index 11bdeedf..aa6ad5fe 100644 --- a/src/views/bpm/processInstance/detail/index.vue +++ b/src/views/bpm/processInstance/detail/index.vue @@ -271,7 +271,7 @@ const handleAudit = async (task, pass) => { data.variables = approveForms.value[index].value } // 获取表单可编辑字段的值 - if (fApi.value) { + if (fApi.value && task.fieldsPermission !== null) { data.variables = getWritableValueOfForm(task.fieldsPermission) } From a07f61a9edca17463e9960290a957dc85b4ea470 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 21 Nov 2024 09:53:12 +0800 Subject: [PATCH 14/15] =?UTF-8?q?=E3=80=90=E4=BB=A3=E7=A0=81=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E3=80=91=E5=B7=A5=E4=BD=9C=E6=B5=81=EF=BC=9ABPMN=20?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E5=99=A8=EF=BC=8C=E5=A2=9E=E5=8A=A0=20UserTa?= =?UTF-8?q?sk=20=E8=87=AA=E5=AE=9A=E4=B9=89=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../package/penal/custom-config/ElementCustomConfig.vue | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/bpmnProcessDesigner/package/penal/custom-config/ElementCustomConfig.vue b/src/components/bpmnProcessDesigner/package/penal/custom-config/ElementCustomConfig.vue index 4b6cb527..d27b2997 100644 --- a/src/components/bpmnProcessDesigner/package/penal/custom-config/ElementCustomConfig.vue +++ b/src/components/bpmnProcessDesigner/package/penal/custom-config/ElementCustomConfig.vue @@ -1,3 +1,6 @@ +