diff --git a/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue b/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue index 136b0a54..3e56e793 100644 --- a/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue +++ b/src/components/SimpleProcessDesignerV2/src/NodeHandler.vue @@ -81,8 +81,6 @@ const addNode = (type: number) => { type: NodeType.USER_TASK_NODE, approveMethod: ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE, candidateStrategy: CandidateStrategy.USER, - // candidateParam: undefined, - // fieldsPermission: undefined, // 超时处理 rejectHandler: { type: RejectHandlerType.FINISH_PROCESS @@ -92,20 +90,6 @@ const addNode = (type: number) => { }, childNode: props.childNode - // 审批节点配置 - // attributes: { - // approveMethod: ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE, - // candidateStrategy: CandidateStrategy.USER, - // candidateParam: undefined, - // fieldsPermission: undefined, - // // 超时处理 - // timeoutHandler: { - // enable: false - // }, - // rejectHandler: { - // type: RejectHandlerType.FINISH_PROCESS - // } - // }, } emits('update:childNode', data) } @@ -118,12 +102,6 @@ const addNode = (type: number) => { candidateStrategy: CandidateStrategy.USER, candidateParam: undefined, fieldsPermission: undefined, - // 审批节点配置 - // attributes: { - // candidateStrategy: CandidateStrategy.USER, - // candidateParam: undefined, - // fieldsPermission: undefined - // }, childNode: props.childNode } emits('update:childNode', data) diff --git a/src/components/SimpleProcessDesignerV2/src/consts.ts b/src/components/SimpleProcessDesignerV2/src/consts.ts index 0b0411cf..4525ce67 100644 --- a/src/components/SimpleProcessDesignerV2/src/consts.ts +++ b/src/components/SimpleProcessDesignerV2/src/consts.ts @@ -182,6 +182,8 @@ export type SimpleFlowNode = { approveMethod?: ApproveMethodType //通过比例 approveRatio?: number + // 审批按钮设置 + buttonsSetting?: any[] // 表单权限 fieldsPermission?: any[] // 审批任务超时处理 @@ -214,6 +216,40 @@ export type ConditionRule = { rightSide: string } +// 审批操作按钮类型 +export enum OpsButtonType { + /** + * 通过 + */ + APPROVE = 1, + /** + * 拒绝 + */ + REJECT = 2, + /** + * 转办 + */ + TRANSFER = 3, + /** + * 委派 + */ + DELEGATE = 4, + /** + * 加签 + */ + ADD_SIGN = 5, + /** + * 回退 + */ + RETURN = 6 +} + +export type ButtonSetting = { + id: OpsButtonType + displayName: string + enable: boolean +} + export const NODE_DEFAULT_TEXT = new Map() NODE_DEFAULT_TEXT.set(NodeType.USER_TASK_NODE, '请配置审批人') NODE_DEFAULT_TEXT.set(NodeType.COPY_TASK_NODE, '请配置抄送人') @@ -281,3 +317,21 @@ export const COMPARISON_OPERATORS: DictDataVO = [ label: '小于等于' } ] +// 审批操作按钮名称 +export const OPERATION_BUTTON_NAME = new Map() +OPERATION_BUTTON_NAME.set(OpsButtonType.APPROVE, '通过') +OPERATION_BUTTON_NAME.set(OpsButtonType.REJECT, '拒绝') +OPERATION_BUTTON_NAME.set(OpsButtonType.TRANSFER, '转办') +OPERATION_BUTTON_NAME.set(OpsButtonType.DELEGATE, '委派') +OPERATION_BUTTON_NAME.set(OpsButtonType.ADD_SIGN, '加签') +OPERATION_BUTTON_NAME.set(OpsButtonType.RETURN, '回退') + +// 默认的按钮权限设置 +export const DEFAULT_BUTTON_SETTING: ButtonSetting[] = [ + { id: OpsButtonType.APPROVE, displayName: '通过', enable: true }, + { id: OpsButtonType.REJECT, displayName: '拒绝', enable: true }, + { id: OpsButtonType.TRANSFER, displayName: '转办', enable: false }, + { id: OpsButtonType.DELEGATE, displayName: '委派', enable: false }, + { id: OpsButtonType.ADD_SIGN, displayName: '加签', enable: false }, + { id: OpsButtonType.RETURN, displayName: '回退', enable: false } +] diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue index 11b5efc5..6254ebeb 100644 --- a/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue +++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue @@ -280,6 +280,40 @@ + +
+
操作按钮
+
+
操作按钮
+
显示名称
+
启用
+
+
+
{{ OPERATION_BUTTON_NAME.get(item.id) }}
+
+ + {{ item.displayName }}   +
+
+ +
+
+
+
字段权限
@@ -334,7 +368,9 @@ import { TIMEOUT_HANDLER_ACTION_TYPES, TIME_UNIT_TYPES, REJECT_HANDLER_TYPES, - NODE_DEFAULT_NAME + NODE_DEFAULT_NAME, + DEFAULT_BUTTON_SETTING, + OPERATION_BUTTON_NAME } from '../consts' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { getDefaultFieldsPermission } from '../utils' @@ -345,7 +381,6 @@ import * as PostApi from '@/api/system/post' import * as UserApi from '@/api/system/user' import * as UserGroupApi from '@/api/bpm/userGroup' import { cloneDeep } from 'lodash-es' - defineOptions({ name: 'UserTaskNodeConfig' }) @@ -385,7 +420,8 @@ const configForm = ref({ timeoutHandlerAction: 1, timeDuration: 6, // 默认 6小时 maxRemindCount: 1, // 默认 提醒 1次 - fieldsPermission: [] + fieldsPermission: [], + buttonsSetting: [] }) // 表单校验规则 const formRules = reactive({ @@ -432,6 +468,8 @@ const saveConfig = async () => { } // 设置表单权限 currentNode.value.fieldsPermission = configForm.value.fieldsPermission + // 设置按钮权限 + currentNode.value.buttonsSetting = configForm.value.buttonsSetting currentNode.value.showText = getShowText() settingVisible.value = false @@ -533,6 +571,7 @@ const setCurrentNode = (node: SimpleFlowNode) => { currentNode.value = node configForm.value.fieldsPermission = cloneDeep(node.fieldsPermission) || getDefaultFieldsPermission(formFields?.value) + configForm.value.buttonsSetting = cloneDeep(node.buttonsSetting) || DEFAULT_BUTTON_SETTING configForm.value.candidateStrategy = node.candidateStrategy const strCandidateParam = node?.candidateParam if (node.candidateStrategy === CandidateStrategy.EXPRESSION) { @@ -614,6 +653,7 @@ const blurEvent = () => { currentNode.value.name = currentNode.value.name || (NODE_DEFAULT_NAME.get(NodeType.USER_TASK_NODE) as string) } + const approveMethodChanged = () => { configForm.value.rejectHandlerType = RejectHandlerType.FINISH_PROCESS if (configForm.value.approveMethod === ApproveMethodType.APPROVE_BY_RATIO) { @@ -703,6 +743,99 @@ const convertTimeUnit = (strTimeUnit: string) => { } return TimeUnitType.HOUR } + +// 操作按钮显示名称可编辑 +const btnDisplayNameEdit = ref([]) +const changeBtnDisplayName = (index: number) => { + btnDisplayNameEdit.value[index] = true +} +const btnDisplayNameBlurEvent = (index: number) => { + btnDisplayNameEdit.value[index] = false + const buttonItem = configForm.value.buttonPermission[index] + buttonItem.displayName = buttonItem.displayName || OPERATION_BUTTON_NAME.get(buttonItem.id) +} - + diff --git a/src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss b/src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss index 3d633b6d..ecf4250a 100644 --- a/src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss +++ b/src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss @@ -241,7 +241,7 @@ .move-node-left { left: -2px; top: 0px; - background: rgba(126, 134, 142, .08); + background: rgba(126, 134, 142, 0.08); border-top-left-radius: 8px; border-bottom-left-radius: 8px; } @@ -249,13 +249,12 @@ .move-node-right { right: -2px; top: 0px; - background: rgba(126,134,142,.08); + background: rgba(126, 134, 142, 0.08); border-top-right-radius: 6px; border-bottom-right-radius: 6px; } } - .node-config-error { border-color: #ff5219 !important; } @@ -306,12 +305,10 @@ background-color: #0089ff; border-radius: 50%; - &:hover{ + &:hover { transform: scale(1.1); - } } - } .node-handler-arrow { @@ -323,7 +320,6 @@ } } - // 条件节点包装 .branch-node-wrapper { position: relative; @@ -341,8 +337,8 @@ position: absolute; height: 100%; width: 4px; - background-color: #fafafa; - content: ""; + background-color: #fafafa; + content: ''; left: 50%; transform: translate(-50%); } @@ -498,10 +494,10 @@ border-radius: 4px; transition: all 0.3s; - &:focus { + &:focus { border-color: #40a9ff; outline: 0; - box-shadow: 0 0 0 2px rgba(24, 144, 255, .2) + box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2); } } } @@ -537,11 +533,11 @@ border: 1px solid #d9d9d9; border-radius: 4px; transition: all 0.3s; - - &:focus { + + &:focus { border-color: #40a9ff; outline: 0; - box-shadow: 0 0 0 2px rgba(24, 144, 255, .2) + box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2); } } } @@ -550,7 +546,6 @@ .field-setting-pane { display: flex; flex-direction: column; - padding: 16px 0; font-size: 14px; .field-setting-desc { @@ -569,7 +564,7 @@ line-height: 45px; background-color: #f8fafc0a; border: 1px solid #1f38581a; - + .first-title { text-align: left !important; } @@ -588,9 +583,8 @@ color: #000; text-align: center; } - } - + .field-setting-item { align-items: center; display: flex; @@ -632,56 +626,56 @@ margin-right: 8px; } - .handler-item-icon { - width: 80px; - height: 80px; - background: #fff; - border: 1px solid #e2e2e2; - border-radius: 50%; - transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); - user-select: none; - text-align: center; + .handler-item-icon { + width: 80px; + height: 80px; + background: #fff; + border: 1px solid #e2e2e2; + border-radius: 50%; + transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); + user-select: none; + text-align: center; - &:hover { - background: #e2e2e2; - box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1); - } + &:hover { + background: #e2e2e2; + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1); + } - .icon-size { - font-size: 35px; - line-height: 80px; - } + .icon-size { + font-size: 35px; + line-height: 80px; + } } - .approve { - color: #ff943e; + .approve { + color: #ff943e; } .copy { color: #3296fa; } - + .condition { color: #15bc83; } - .handler-item-text { - margin-top: 4px; - width: 80px; - text-align: center; - } - + .handler-item-text { + margin-top: 4px; + width: 80px; + text-align: center; + } } // iconfont 样式 @font-face { - font-family: "iconfont"; /* Project id 4495938 */ - src: url('iconfont.woff2?t=1712392083512') format('woff2'), - url('iconfont.woff?t=1712392083512') format('woff'), - url('iconfont.ttf?t=1712392083512') format('truetype'); + font-family: 'iconfont'; /* Project id 4495938 */ + src: + url('iconfont.woff2?t=1712392083512') format('woff2'), + url('iconfont.woff?t=1712392083512') format('woff'), + url('iconfont.ttf?t=1712392083512') format('truetype'); } .iconfont { - font-family: "iconfont" !important; + font-family: 'iconfont' !important; font-size: 16px; font-style: normal; -webkit-font-smoothing: antialiased; @@ -689,25 +683,25 @@ } .icon-Inclusive:before { - content: "\e602"; + content: '\e602'; } .icon-copy:before { - content: "\e7eb"; + content: '\e7eb'; } .icon-handle:before { - content: "\e61c"; + content: '\e61c'; } .icon-exclusive:before { - content: "\e717"; + content: '\e717'; } .icon-approve:before { - content: "\e715"; + content: '\e715'; } .icon-parallel:before { - content: "\e688"; -} \ No newline at end of file + content: '\e688'; +} diff --git a/src/views/bpm/processInstance/detail/index.vue b/src/views/bpm/processInstance/detail/index.vue index 94475647..0a9f96a3 100644 --- a/src/views/bpm/processInstance/detail/index.vue +++ b/src/views/bpm/processInstance/detail/index.vue @@ -56,29 +56,71 @@
- + - 通过 + {{ + item.buttonsSetting?.[OpsButtonType.APPROVE]?.displayName || + OPERATION_BUTTON_NAME.get(OpsButtonType.APPROVE) + }} - + - 不通过 + {{ + item.buttonsSetting?.[OpsButtonType.REJECT].displayName || + OPERATION_BUTTON_NAME.get(OpsButtonType.REJECT) + }} - + - 转办 + {{ + item.buttonsSetting?.[OpsButtonType.TRANSFER]?.displayName || + OPERATION_BUTTON_NAME.get(OpsButtonType.TRANSFER) + }} - + - 委派 + {{ + item.buttonsSetting?.[OpsButtonType.DELEGATE]?.displayName || + OPERATION_BUTTON_NAME.get(OpsButtonType.DELEGATE) + }} - + - 加签 + {{ + item.buttonsSetting?.[OpsButtonType.ADD_SIGN]?.displayName || + OPERATION_BUTTON_NAME.get(OpsButtonType.ADD_SIGN) + }} - + - 回退 + {{ + item.buttonsSetting?.[OpsButtonType.RETURN]?.displayName || + OPERATION_BUTTON_NAME.get(OpsButtonType.RETURN) + }}
@@ -147,6 +189,10 @@ import TaskSignCreateForm from './dialog/TaskSignCreateForm.vue' import { registerComponent } from '@/utils/routerHelper' import { isEmpty } from '@/utils/is' import * as UserApi from '@/api/system/user' +import { + OpsButtonType, + OPERATION_BUTTON_NAME +} from '@/components/SimpleProcessDesignerV2/src/consts' defineOptions({ name: 'BpmProcessInstanceDetail' }) @@ -280,12 +326,16 @@ const getProcessInstance = async () => { // 设置表单信息 const processDefinition = data.processDefinition if (processDefinition.formType === 10) { - setConfAndFields2( - detailForm, - processDefinition.formConf, - processDefinition.formFields, - data.formVariables - ) + if (detailForm.value.rule.length > 0) { + detailForm.value.value = data.formVariables + } else { + setConfAndFields2( + detailForm, + processDefinition.formConf, + processDefinition.formFields, + data.formVariables + ) + } nextTick().then(() => { fApi.value?.btn.show(false) fApi.value?.resetBtn.show(false)