浏览代码

【功能新增】候选人策略:新增表单内成员字段

jason 9 月之前
父节点
当前提交
67769c299e

+ 1 - 1
src/components/FormCreate/src/components/useApiSelect.tsx

@@ -185,7 +185,7 @@ export const useApiSelect = (option: ApiSelectProps) => {
             </el-select>
           )
         }
-        debugger
+        // debugger
         return (
           <el-select
             class="w-1/1"

+ 7 - 1
src/components/SimpleProcessDesignerV2/src/consts.ts

@@ -79,7 +79,7 @@ export interface SimpleFlowNode {
   // 审批按钮设置
   buttonsSetting?: any[]
   // 表单权限
-  fieldsPermission?: Array<Record<string, string>>
+  fieldsPermission?: Array<Record<string, any>>
   // 审批任务超时处理
   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 }
 ]
 // 审批节点 的审批类型

+ 47 - 12
src/components/SimpleProcessDesignerV2/src/node.ts

@@ -32,7 +32,7 @@ export function useWatchNode(props: { flowNode: SimpleFlowNode }): Ref<SimpleFlo
  */
 export function useFormFieldsPermission(defaultPermission: FieldPermissionType) {
   // 字段权限配置. 需要有 field, title,  permissioin 属性
-  const fieldsPermissionConfig = ref<Array<Record<string, string>>>([])
+  const fieldsPermissionConfig = ref<Array<Record<string, any>>>([])
 
   const formType = inject<Ref<number>>('formType') // 表单类型
 
@@ -45,49 +45,71 @@ export function useFormFieldsPermission(defaultPermission: FieldPermissionType)
   }
   // 默认的表单权限: 获取表单的所有字段,设置字段默认权限为只读
   const getDefaultFieldsPermission = (formFields?: string[]) => {
-    const defaultFieldsPermission: Array<Record<string, string>> = []
+    let defaultFieldsPermission: Array<Record<string, any>> = []
+    if (formFields) {
+      defaultFieldsPermission = parseFormCreateFields(formFields).map( item => {
+        return {
+          field: item.field,
+          title: item.title,
+          permission: defaultPermission
+        }
+      });
+    }
+    return defaultFieldsPermission
+  }
+   // 解析 formCreate 所有表单字段, 并返回
+   const parseFormCreateFields = (formFields?: string[]) => {
+    const result: Array<Record<string, any>> = []
     if (formFields) {
       formFields.forEach((fieldStr: string) => {
-        parseFieldsSetDefaultPermission(JSON.parse(fieldStr), defaultFieldsPermission)
+        parseFields(JSON.parse(fieldStr), result)
       })
     }
-    return defaultFieldsPermission
+    return result
   }
-  // 解析字段。赋给默认权限
-  const parseFieldsSetDefaultPermission = (
+  const parseFields = (
     rule: Record<string, any>,
-    fieldsPermission: Array<Record<string, string>>,
+    fields: Array<Record<string, any>>,
     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

+ 23 - 2
src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue

@@ -122,7 +122,20 @@
                 />
               </el-select>
             </el-form-item>
-
+            <el-form-item
+              v-if="configForm.candidateStrategy === CandidateStrategy.USER_FIELD_ON_FORM"
+              label="表单内成员字段"
+              prop="userFieldOnForm"
+            >
+              <el-select v-model="configForm.userFieldOnForm" clearable style="width: 100%">
+                <el-option
+                  v-for="(item,idx) in userFieldOnFormOptions"
+                  :key="idx"
+                  :label="item.title"
+                  :value="item.field"
+                />
+              </el-select>
+            </el-form-item>
             <el-form-item
               v-if="configForm.candidateStrategy === CandidateStrategy.EXPRESSION"
               label="流程表达式"
@@ -230,9 +243,15 @@ const { nodeName, showInput, clickIcon, blurEvent } = useNodeName(NodeType.COPY_
 // 激活的 Tab 标签页
 const activeTabName = ref('user')
 // 表单字段权限配置
-const { formType, fieldsPermissionConfig, getNodeConfigFormFields } = useFormFieldsPermission(
+const { formType, fieldsPermissionConfig, formFieldOptions, getNodeConfigFormFields } = useFormFieldsPermission(
   FieldPermissionType.READ
 )
+// 表单内成员字段选项, 必须是必填和用户选择器
+const userFieldOnFormOptions = computed(() => {
+  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 () => {

+ 23 - 1
src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue

@@ -157,6 +157,20 @@
                 />
               </el-select>
             </el-form-item>
+            <el-form-item
+              v-if="configForm.candidateStrategy === CandidateStrategy.USER_FIELD_ON_FORM"
+              label="表单内成员字段"
+              prop="userFieldOnForm"
+            >
+              <el-select v-model="configForm.userFieldOnForm" clearable style="width: 100%">
+                <el-option
+                  v-for="(item,idx) in userFieldOnFormOptions"
+                  :key="idx"
+                  :label="item.title"
+                  :value="item.field"
+                />
+              </el-select>
+            </el-form-item>
             <!-- TODO @jason:后续要支持选择已经存好的表达式 -->
             <el-form-item
               v-if="configForm.candidateStrategy === CandidateStrategy.EXPRESSION"
@@ -482,9 +496,15 @@ const { nodeName, showInput, clickIcon, blurEvent } = useNodeName(NodeType.USER_
 // 激活的 Tab 标签页
 const activeTabName = ref('user')
 // 表单字段权限设置
-const { formType, fieldsPermissionConfig, getNodeConfigFormFields } = useFormFieldsPermission(
+const { formType, fieldsPermissionConfig, formFieldOptions, getNodeConfigFormFields } = useFormFieldsPermission(
   FieldPermissionType.READ
 )
+// 表单内成员字段选项, 必须是必填和用户选择器
+const userFieldOnFormOptions = computed(() => {
+  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
 }