From f9b459a3fefd5fab0ee8e19268adb9d9eadab2a7 Mon Sep 17 00:00:00 2001 From: dengzedong <dengzedong@email> Date: 星期二, 17 十二月 2024 18:16:58 +0800 Subject: [PATCH] 预测项setting的值修改最大输入长度为1000 --- src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue | 905 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 905 insertions(+), 0 deletions(-) diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue new file mode 100644 index 0000000..a088b6d --- /dev/null +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue @@ -0,0 +1,905 @@ +<template> + <el-drawer + :append-to-body="true" + v-model="settingVisible" + :show-close="false" + :size="550" + :before-close="saveConfig" + class="justify-start" + > + <template #header> + <div class="config-header"> + <input + v-if="showInput" + type="text" + class="config-editable-input" + @blur="blurEvent()" + v-mountedFocus + v-model="nodeName" + :placeholder="nodeName" + /> + <div v-else class="node-name"> + {{ nodeName }} <Icon class="ml-1" icon="ep:edit-pen" :size="16" @click="clickIcon()" /> + </div> + <div class="divide-line"></div> + </div> + </template> + <div class="flex flex-items-center mb-3"> + <span class="font-size-16px mr-3">审批类型 :</span> + <el-radio-group v-model="approveType"> + <el-radio + v-for="(item, index) in APPROVE_TYPE" + :key="index" + :value="item.value" + :label="item.value" + > + {{ item.label }} + </el-radio> + </el-radio-group> + </div> + <el-tabs type="border-card" v-model="activeTabName" v-if="approveType === ApproveType.USER"> + <el-tab-pane label="审批人" name="user"> + <div> + <el-form ref="formRef" :model="configForm" label-position="top" :rules="formRules"> + <el-form-item label="审批人设置" prop="candidateStrategy"> + <el-radio-group + v-model="configForm.candidateStrategy" + @change="changeCandidateStrategy" + > + <el-radio + v-for="(dict, index) in CANDIDATE_STRATEGY" + :key="index" + :value="dict.value" + :label="dict.value" + > + {{ dict.label }} + </el-radio> + </el-radio-group> + </el-form-item> + <el-form-item + v-if="configForm.candidateStrategy == CandidateStrategy.ROLE" + label="指定角色" + prop="roleIds" + > + <el-select v-model="configForm.roleIds" clearable multiple style="width: 100%"> + <el-option + v-for="item in roleOptions" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + <el-form-item + v-if=" + configForm.candidateStrategy == CandidateStrategy.DEPT_MEMBER || + configForm.candidateStrategy == CandidateStrategy.DEPT_LEADER || + configForm.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER + " + label="指定部门" + prop="deptIds" + span="24" + > + <el-tree-select + ref="treeRef" + v-model="configForm.deptIds" + :data="deptTreeOptions" + :props="defaultProps" + empty-text="加载中,请稍后" + multiple + node-key="id" + :check-strictly="true" + style="width: 100%" + show-checkbox + /> + </el-form-item> + <el-form-item + v-if="configForm.candidateStrategy == CandidateStrategy.POST" + label="指定岗位" + prop="postIds" + span="24" + > + <el-select v-model="configForm.postIds" clearable multiple style="width: 100%"> + <el-option + v-for="item in postOptions" + :key="item.id" + :label="item.name" + :value="item.id!" + /> + </el-select> + </el-form-item> + <el-form-item + v-if="configForm.candidateStrategy == CandidateStrategy.USER" + label="指定用户" + prop="userIds" + span="24" + > + <el-select v-model="configForm.userIds" clearable multiple style="width: 100%"> + <el-option + v-for="item in userOptions" + :key="item.id" + :label="item.nickname" + :value="item.id" + /> + </el-select> + </el-form-item> + <el-form-item + v-if="configForm.candidateStrategy === CandidateStrategy.USER_GROUP" + label="指定用户组" + prop="userGroups" + > + <el-select v-model="configForm.userGroups" clearable multiple style="width: 100%"> + <el-option + v-for="item in userGroupOptions" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + <el-form-item + v-if="configForm.candidateStrategy === CandidateStrategy.FORM_USER" + label="表单内用户字段" + prop="formUser" + > + <el-select v-model="configForm.formUser" clearable style="width: 100%"> + <el-option + v-for="(item, idx) in userFieldOnFormOptions" + :key="idx" + :label="item.title" + :value="item.field" + :disabled ="!item.required" + /> + </el-select> + </el-form-item> + <el-form-item + v-if="configForm.candidateStrategy === CandidateStrategy.FORM_DEPT_LEADER" + label="表单内部门字段" + prop="formDept" + > + <el-select v-model="configForm.formDept" clearable style="width: 100%"> + <el-option + v-for="(item, idx) in deptFieldOnFormOptions" + :key="idx" + :label="item.title" + :value="item.field" + :disabled ="!item.required" + /> + </el-select> + </el-form-item> + <el-form-item + v-if=" + configForm.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER || + configForm.candidateStrategy == CandidateStrategy.START_USER_DEPT_LEADER || + configForm.candidateStrategy == + CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER || + configForm.candidateStrategy == CandidateStrategy.FORM_DEPT_LEADER + " + :label="deptLevelLabel!" + prop="deptLevel" + span="24" + > + <el-select v-model="configForm.deptLevel" clearable> + <el-option + v-for="(item, index) in MULTI_LEVEL_DEPT" + :key="index" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + <!-- TODO @jason:后续要支持选择已经存好的表达式 --> + <el-form-item + v-if="configForm.candidateStrategy === CandidateStrategy.EXPRESSION" + label="流程表达式" + prop="expression" + > + <el-input + type="textarea" + v-model="configForm.expression" + clearable + style="width: 100%" + /> + </el-form-item> + <el-form-item label="多人审批方式" prop="approveMethod"> + <el-radio-group v-model="configForm.approveMethod" @change="approveMethodChanged"> + <div class="flex-col"> + <div + v-for="(item, index) in APPROVE_METHODS" + :key="index" + class="flex items-center" + > + <el-radio :value="item.value" :label="item.value"> + {{ item.label }} + </el-radio> + <el-form-item prop="approveRatio"> + <el-input-number + v-model="configForm.approveRatio" + :min="10" + :max="100" + :step="10" + size="small" + v-if=" + item.value === ApproveMethodType.APPROVE_BY_RATIO && + configForm.approveMethod === ApproveMethodType.APPROVE_BY_RATIO + " + /> + </el-form-item> + </div> + </div> + </el-radio-group> + </el-form-item> + + <el-divider content-position="left">审批人拒绝时</el-divider> + <el-form-item prop="rejectHandlerType"> + <el-radio-group v-model="configForm.rejectHandlerType"> + <div class="flex-col"> + <div v-for="(item, index) in REJECT_HANDLER_TYPES" :key="index"> + <el-radio :key="item.value" :value="item.value" :label="item.label" /> + </div> + </div> + </el-radio-group> + </el-form-item> + <el-form-item + v-if="configForm.rejectHandlerType == RejectHandlerType.RETURN_USER_TASK" + label="驳回节点" + prop="returnNodeId" + > + <el-select v-model="configForm.returnNodeId" clearable style="width: 100%"> + <el-option + v-for="item in returnTaskList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + + <el-divider content-position="left">审批人超时未处理时</el-divider> + <el-form-item label="启用开关" prop="timeoutHandlerEnable"> + <el-switch + v-model="configForm.timeoutHandlerEnable" + active-text="开启" + inactive-text="关闭" + @change="timeoutHandlerChange" + /> + </el-form-item> + <el-form-item + label="执行动作" + prop="timeoutHandlerType" + v-if="configForm.timeoutHandlerEnable" + > + <el-radio-group + v-model="configForm.timeoutHandlerType" + @change="timeoutHandlerTypeChanged" + > + <el-radio-button + v-for="item in TIMEOUT_HANDLER_TYPES" + :key="item.value" + :value="item.value" + :label="item.label" + /> + </el-radio-group> + </el-form-item> + <el-form-item label="超时时间设置" v-if="configForm.timeoutHandlerEnable"> + <span class="mr-2">当超过</span> + <el-form-item prop="timeDuration"> + <el-input-number + class="mr-2" + :style="{ width: '100px' }" + v-model="configForm.timeDuration" + :min="1" + controls-position="right" + /> + </el-form-item> + <el-select + v-model="timeUnit" + class="mr-2" + :style="{ width: '100px' }" + @change="timeUnitChange" + > + <el-option + v-for="item in TIME_UNIT_TYPES" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + 未处理 + </el-form-item> + <el-form-item + label="最大提醒次数" + prop="maxRemindCount" + v-if="configForm.timeoutHandlerEnable && configForm.timeoutHandlerType === 1" + > + <el-input-number v-model="configForm.maxRemindCount" :min="1" :max="10" /> + </el-form-item> + + <el-divider content-position="left">审批人为空时</el-divider> + <el-form-item prop="assignEmptyHandlerType"> + <el-radio-group v-model="configForm.assignEmptyHandlerType"> + <div class="flex-col"> + <div v-for="(item, index) in ASSIGN_EMPTY_HANDLER_TYPES" :key="index"> + <el-radio :key="item.value" :value="item.value" :label="item.label" /> + </div> + </div> + </el-radio-group> + </el-form-item> + <el-form-item + v-if="configForm.assignEmptyHandlerType == AssignEmptyHandlerType.ASSIGN_USER" + label="指定用户" + prop="assignEmptyHandlerUserIds" + span="24" + > + <el-select + v-model="configForm.assignEmptyHandlerUserIds" + clearable + multiple + style="width: 100%" + > + <el-option + v-for="item in userOptions" + :key="item.id" + :label="item.nickname" + :value="item.id" + /> + </el-select> + </el-form-item> + + <el-divider content-position="left">审批人与提交人为同一人时</el-divider> + <el-form-item prop="assignStartUserHandlerType"> + <el-radio-group v-model="configForm.assignStartUserHandlerType"> + <div class="flex-col"> + <div v-for="(item, index) in ASSIGN_START_USER_HANDLER_TYPES" :key="index"> + <el-radio :key="item.value" :value="item.value" :label="item.label" /> + </div> + </div> + </el-radio-group> + </el-form-item> + </el-form> + </div> + </el-tab-pane> + <el-tab-pane label="操作按钮设置" name="buttons"> + <div class="button-setting-pane"> + <div class="button-setting-desc">操作按钮</div> + <div class="button-setting-title"> + <div class="button-title-label">操作按钮</div> + <div class="pl-4 button-title-label">显示名称</div> + <div class="button-title-label">启用</div> + </div> + <div class="button-setting-item" v-for="(item, index) in buttonsSetting" :key="index"> + <div class="button-setting-item-label"> {{ OPERATION_BUTTON_NAME.get(item.id) }} </div> + <div class="button-setting-item-label"> + <input + type="text" + class="editable-title-input" + @blur="btnDisplayNameBlurEvent(index)" + v-mountedFocus + v-model="item.displayName" + :placeholder="item.displayName" + v-if="btnDisplayNameEdit[index]" + /> + <el-button v-else text @click="changeBtnDisplayName(index)" + >{{ item.displayName }} <Icon icon="ep:edit" + /></el-button> + </div> + <div class="button-setting-item-label"> + <el-switch v-model="item.enable" /> + </div> + </div> + </div> + </el-tab-pane> + <el-tab-pane label="表单字段权限" name="fields" v-if="formType === 10"> + <div class="field-setting-pane"> + <div class="field-setting-desc">字段权限</div> + <div class="field-permit-title"> + <div class="setting-title-label first-title"> 字段名称 </div> + <div class="other-titles"> + <span class="setting-title-label">只读</span> + <span class="setting-title-label">可编辑</span> + <span class="setting-title-label">隐藏</span> + </div> + </div> + <div + class="field-setting-item" + v-for="(item, index) in fieldsPermissionConfig" + :key="index" + > + <div class="field-setting-item-label"> {{ item.title }} </div> + <el-radio-group class="field-setting-item-group" v-model="item.permission"> + <div class="item-radio-wrap"> + <el-radio + :value="FieldPermissionType.READ" + size="large" + :label="FieldPermissionType.READ" + ><span></span + ></el-radio> + </div> + <div class="item-radio-wrap"> + <el-radio + :value="FieldPermissionType.WRITE" + size="large" + :label="FieldPermissionType.WRITE" + ><span></span + ></el-radio> + </div> + <div class="item-radio-wrap"> + <el-radio + :value="FieldPermissionType.NONE" + size="large" + :label="FieldPermissionType.NONE" + ><span></span + ></el-radio> + </div> + </el-radio-group> + </div> + </div> + </el-tab-pane> + </el-tabs> + <template #footer> + <el-divider /> + <div> + <el-button type="primary" @click="saveConfig">确 定</el-button> + <el-button @click="closeDrawer">取 消</el-button> + </div> + </template> + </el-drawer> +</template> + +<script setup lang="ts"> +import { + SimpleFlowNode, + APPROVE_TYPE, + ApproveType, + APPROVE_METHODS, + CandidateStrategy, + NodeType, + ApproveMethodType, + TimeUnitType, + RejectHandlerType, + TIMEOUT_HANDLER_TYPES, + TIME_UNIT_TYPES, + REJECT_HANDLER_TYPES, + DEFAULT_BUTTON_SETTING, + OPERATION_BUTTON_NAME, + ButtonSetting, + MULTI_LEVEL_DEPT, + CANDIDATE_STRATEGY, + ASSIGN_START_USER_HANDLER_TYPES, + TimeoutHandlerType, + ASSIGN_EMPTY_HANDLER_TYPES, + AssignEmptyHandlerType, + FieldPermissionType +} from '../consts' + +import { + useWatchNode, + useNodeName, + useFormFieldsPermission, + useNodeForm, + UserTaskFormType, + useDrawer +} from '../node' +import { defaultProps } from '@/utils/tree' +import { cloneDeep } from 'lodash-es' +import { convertTimeUnit, getApproveTypeText } from '../utils' +defineOptions({ + name: 'UserTaskNodeConfig' +}) +const props = defineProps({ + flowNode: { + type: Object as () => SimpleFlowNode, + required: true + } +}) +const emits = defineEmits<{ + 'find:returnTaskNodes': [nodeList: SimpleFlowNode[]] +}>() +const deptLevelLabel = computed(() => { + let label = '部门负责人来源' + if (configForm.value.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER) { + label = label + '(指定部门向上)' + } else if (configForm.value.candidateStrategy == CandidateStrategy.FORM_DEPT_LEADER) { + label = label + '(表单内部门向上)' + } else { + label = label + '(发起人部门向上)' + } + return label +}) +// 监控节点的变化 +const currentNode = useWatchNode(props) +// 抽屉配置 +const { settingVisible, closeDrawer, openDrawer } = useDrawer() +// 节点名称配置 +const { nodeName, showInput, clickIcon, blurEvent } = useNodeName(NodeType.USER_TASK_NODE) +// 激活的 Tab 标签页 +const activeTabName = ref('user') +// 表单字段权限设置 +const { formType, fieldsPermissionConfig, formFieldOptions, getNodeConfigFormFields } = + useFormFieldsPermission(FieldPermissionType.READ) +// 表单内用户字段选项, 必须是必填和用户选择器 +const userFieldOnFormOptions = computed(() => { + return formFieldOptions.filter((item) => item.type === 'UserSelect') +}) +// 表单内部门字段选项, 必须是必填和部门选择器 +const deptFieldOnFormOptions = computed(() => { + return formFieldOptions.filter((item) => item.type === 'DeptSelect') +}) +// 操作按钮设置 +const { buttonsSetting, btnDisplayNameEdit, changeBtnDisplayName, btnDisplayNameBlurEvent } = + useButtonsSetting() +const approveType = ref(ApproveType.USER) +// 审批人表单设置 +const formRef = ref() // 表单 Ref +// 表单校验规则 +const formRules = reactive({ + candidateStrategy: [{ required: true, message: '审批人设置不能为空', trigger: 'change' }], + userIds: [{ required: true, message: '用户不能为空', trigger: 'change' }], + roleIds: [{ required: true, message: '角色不能为空', trigger: 'change' }], + deptIds: [{ required: true, message: '部门不能为空', trigger: 'change' }], + userGroups: [{ required: true, message: '用户组不能为空', trigger: 'change' }], + formUser: [{ required: true, message: '表单内用户字段不能为空', trigger: 'change' }], + formDept: [{ required: true, message: '表单内部门字段不能为空', trigger: 'change' }], + postIds: [{ required: true, message: '岗位不能为空', trigger: 'change' }], + expression: [{ required: true, message: '流程表达式不能为空', trigger: 'blur' }], + approveMethod: [{ required: true, message: '多人审批方式不能为空', trigger: 'change' }], + approveRatio: [{ required: true, message: '通过比例不能为空', trigger: 'blur' }], + returnNodeId: [{ required: true, message: '驳回节点不能为空', trigger: 'change' }], + timeoutHandlerEnable: [{ required: true }], + timeoutHandlerType: [{ required: true }], + timeDuration: [{ required: true, message: '超时时间不能为空', trigger: 'blur' }], + maxRemindCount: [{ required: true, message: '提醒次数不能为空', trigger: 'blur' }], + assignEmptyHandlerType: [{ required: true }], + assignEmptyHandlerUserIds: [{ required: true, message: '用户不能为空', trigger: 'change' }], + assignStartUserHandlerType: [{ required: true }] +}) + +const { + configForm: tempConfigForm, + roleOptions, + postOptions, + userOptions, + userGroupOptions, + deptTreeOptions, + handleCandidateParam, + parseCandidateParam, + getShowText +} = useNodeForm(NodeType.USER_TASK_NODE) +const configForm = tempConfigForm as Ref<UserTaskFormType> + +// 改变审批人设置策略 +const changeCandidateStrategy = () => { + configForm.value.userIds = [] + configForm.value.deptIds = [] + configForm.value.roleIds = [] + configForm.value.postIds = [] + configForm.value.userGroups = [] + configForm.value.deptLevel = 1 + configForm.value.formUser = '' + configForm.value.formDept = '' + configForm.value.approveMethod = ApproveMethodType.SEQUENTIAL_APPROVE +} + +// 审批方式改变 +const approveMethodChanged = () => { + configForm.value.rejectHandlerType = RejectHandlerType.FINISH_PROCESS + if (configForm.value.approveMethod === ApproveMethodType.APPROVE_BY_RATIO) { + configForm.value.approveRatio = 100 + } + formRef.value.clearValidate('approveRatio') +} +// 审批拒绝 可退回的节点 +const returnTaskList = ref<SimpleFlowNode[]>([]) +// 审批人超时未处理设置 +const { + timeoutHandlerChange, + cTimeoutType, + timeoutHandlerTypeChanged, + timeUnit, + timeUnitChange, + isoTimeDuration, + cTimeoutMaxRemindCount +} = useTimeoutHandler() + +// 保存配置 +const saveConfig = async () => { + activeTabName.value = 'user' + // 设置审批节点名称 + currentNode.value.name = nodeName.value! + // 设置审批类型 + currentNode.value.approveType = approveType.value + // 如果不是人工审批。返回 + if (approveType.value !== ApproveType.USER) { + currentNode.value.showText = getApproveTypeText(approveType.value) + settingVisible.value = false + return true + } + + if (!formRef) return false + const valid = await formRef.value.validate() + if (!valid) return false + const showText = getShowText() + if (!showText) return false + + currentNode.value.candidateStrategy = configForm.value.candidateStrategy + // 处理 candidateParam 参数 + currentNode.value.candidateParam = handleCandidateParam() + // 设置审批方式 + currentNode.value.approveMethod = configForm.value.approveMethod + if (configForm.value.approveMethod === ApproveMethodType.APPROVE_BY_RATIO) { + currentNode.value.approveRatio = configForm.value.approveRatio + } + // 设置拒绝处理 + currentNode.value.rejectHandler = { + type: configForm.value.rejectHandlerType!, + returnNodeId: configForm.value.returnNodeId + } + // 设置超时处理 + currentNode.value.timeoutHandler = { + enable: configForm.value.timeoutHandlerEnable!, + type: cTimeoutType.value, + timeDuration: isoTimeDuration.value, + maxRemindCount: cTimeoutMaxRemindCount.value + } + // 设置审批人为空时 + currentNode.value.assignEmptyHandler = { + type: configForm.value.assignEmptyHandlerType!, + userIds: + configForm.value.assignEmptyHandlerType === AssignEmptyHandlerType.ASSIGN_USER + ? configForm.value.assignEmptyHandlerUserIds + : undefined + } + // 设置审批人与发起人相同时 + currentNode.value.assignStartUserHandlerType = configForm.value.assignStartUserHandlerType + // 设置表单权限 + currentNode.value.fieldsPermission = fieldsPermissionConfig.value + // 设置按钮权限 + currentNode.value.buttonsSetting = buttonsSetting.value + + currentNode.value.showText = showText + settingVisible.value = false + return true +} + +// 显示审批节点配置, 由父组件传过来 +const showUserTaskNodeConfig = (node: SimpleFlowNode) => { + nodeName.value = node.name + // 1 审批类型 + approveType.value = node.approveType ? node.approveType : ApproveType.USER + // 如果审批类型不是人工审批返回 + if (approveType.value !== ApproveType.USER) { + return + } + + //2.1 审批人设置 + configForm.value.candidateStrategy = node.candidateStrategy! + // 解析候选人参数 + parseCandidateParam(node.candidateStrategy!, node?.candidateParam) + // 2.2 设置审批方式 + configForm.value.approveMethod = node.approveMethod! + if (node.approveMethod == ApproveMethodType.APPROVE_BY_RATIO) { + configForm.value.approveRatio = node.approveRatio! + } + // 2.3 设置审批拒绝处理 + configForm.value.rejectHandlerType = node.rejectHandler!.type + configForm.value.returnNodeId = node.rejectHandler?.returnNodeId + const matchNodeList = [] + emits('find:returnTaskNodes', matchNodeList) + returnTaskList.value = matchNodeList + // 2.4 设置审批超时处理 + configForm.value.timeoutHandlerEnable = node.timeoutHandler!.enable + if (node.timeoutHandler?.enable && node.timeoutHandler?.timeDuration) { + const strTimeDuration = node.timeoutHandler.timeDuration + let parseTime = strTimeDuration.slice(2, strTimeDuration.length - 1) + let parseTimeUnit = strTimeDuration.slice(strTimeDuration.length - 1) + configForm.value.timeDuration = parseInt(parseTime) + timeUnit.value = convertTimeUnit(parseTimeUnit) + } + configForm.value.timeoutHandlerType = node.timeoutHandler?.type + configForm.value.maxRemindCount = node.timeoutHandler?.maxRemindCount + // 2.5 设置审批人为空时 + configForm.value.assignEmptyHandlerType = node.assignEmptyHandler?.type + configForm.value.assignEmptyHandlerUserIds = node.assignEmptyHandler?.userIds + // 2.6 设置用户任务的审批人与发起人相同时 + configForm.value.assignStartUserHandlerType = node.assignStartUserHandlerType + // 3. 操作按钮设置 + buttonsSetting.value = cloneDeep(node.buttonsSetting) || DEFAULT_BUTTON_SETTING + // 4. 表单字段权限配置 + getNodeConfigFormFields(node.fieldsPermission) +} + +defineExpose({ openDrawer, showUserTaskNodeConfig }) // 暴露方法给父组件 + +/** + * @description 操作按钮设置 + */ +function useButtonsSetting() { + const buttonsSetting = ref<ButtonSetting[]>() + // 操作按钮显示名称可编辑 + const btnDisplayNameEdit = ref<boolean[]>([]) + const changeBtnDisplayName = (index: number) => { + btnDisplayNameEdit.value[index] = true + } + const btnDisplayNameBlurEvent = (index: number) => { + btnDisplayNameEdit.value[index] = false + const buttonItem = buttonsSetting.value![index] + buttonItem.displayName = buttonItem.displayName || OPERATION_BUTTON_NAME.get(buttonItem.id)! + } + return { + buttonsSetting, + btnDisplayNameEdit, + changeBtnDisplayName, + btnDisplayNameBlurEvent + } +} + +/** + * @description 审批人超时未处理配置 + */ +function useTimeoutHandler() { + // 时间单位 + const timeUnit = ref(TimeUnitType.HOUR) + + // 超时开关改变 + const timeoutHandlerChange = () => { + if (configForm.value.timeoutHandlerEnable) { + timeUnit.value = 2 + configForm.value.timeDuration = 6 + configForm.value.timeoutHandlerType = 1 + configForm.value.maxRemindCount = 1 + } + } + // 超时执行的动作 + const cTimeoutType = computed(() => { + if (!configForm.value.timeoutHandlerEnable) { + return undefined + } + return configForm.value.timeoutHandlerType + }) + + // 超时处理动作改变 + const timeoutHandlerTypeChanged = () => { + if (configForm.value.timeoutHandlerType === TimeoutHandlerType.REMINDER) { + configForm.value.maxRemindCount = 1 // 超时提醒次数,默认为1 + } + } + + // 时间单位改变 + const timeUnitChange = () => { + // 分钟,默认是 60 分钟 + if (timeUnit.value === TimeUnitType.MINUTE) { + configForm.value.timeDuration = 60 + } + // 小时,默认是 6 个小时 + if (timeUnit.value === TimeUnitType.HOUR) { + configForm.value.timeDuration = 6 + } + // 天, 默认 1天 + if (timeUnit.value === TimeUnitType.DAY) { + configForm.value.timeDuration = 1 + } + } + // 超时时间的 ISO 表示 + const isoTimeDuration = computed(() => { + if (!configForm.value.timeoutHandlerEnable) { + return undefined + } + let strTimeDuration = 'PT' + if (timeUnit.value === TimeUnitType.MINUTE) { + strTimeDuration += configForm.value.timeDuration + 'M' + } + if (timeUnit.value === TimeUnitType.HOUR) { + strTimeDuration += configForm.value.timeDuration + 'H' + } + if (timeUnit.value === TimeUnitType.DAY) { + strTimeDuration += configForm.value.timeDuration + 'D' + } + return strTimeDuration + }) + + // 超时最大提醒次数 + const cTimeoutMaxRemindCount = computed(() => { + if (!configForm.value.timeoutHandlerEnable) { + return undefined + } + if (configForm.value.timeoutHandlerType !== TimeoutHandlerType.REMINDER) { + return undefined + } + return configForm.value.maxRemindCount + }) + + return { + timeoutHandlerChange, + cTimeoutType, + timeoutHandlerTypeChanged, + timeUnit, + timeUnitChange, + isoTimeDuration, + cTimeoutMaxRemindCount + } +} +</script> + +<style lang="scss" scoped> +.button-setting-pane { + display: flex; + flex-direction: column; + font-size: 14px; + + .button-setting-desc { + padding-right: 8px; + margin-bottom: 16px; + font-size: 16px; + font-weight: 700; + } + + .button-setting-title { + display: flex; + justify-content: space-between; + align-items: center; + height: 45px; + padding-left: 12px; + background-color: #f8fafc0a; + border: 1px solid #1f38581a; + + & > :first-child { + width: 100px !important; + text-align: left !important; + } + + & > :last-child { + text-align: center !important; + } + + .button-title-label { + width: 150px; + font-size: 13px; + font-weight: 700; + color: #000; + text-align: left; + } + } + + .button-setting-item { + align-items: center; + display: flex; + justify-content: space-between; + height: 38px; + padding-left: 12px; + border: 1px solid #1f38581a; + border-top: 0; + + & > :first-child { + width: 100px !important; + } + + & > :last-child { + text-align: center !important; + } + + .button-setting-item-label { + width: 150px; + overflow: hidden; + text-align: left; + text-overflow: ellipsis; + white-space: nowrap; + } + + .editable-title-input { + height: 24px; + max-width: 130px; + margin-left: 4px; + line-height: 24px; + border: 1px solid #d9d9d9; + border-radius: 4px; + transition: all 0.3s; + + &:focus { + border-color: #40a9ff; + outline: 0; + box-shadow: 0 0 0 2px rgb(24 144 255 / 20%); + } + } + } +} +</style> -- Gitblit v1.9.3