Skip to content

Commit 538ad86

Browse files
committed
仿钉钉流程设计器- 操作按钮设置
1 parent fae712b commit 538ad86

File tree

5 files changed

+311
-102
lines changed

5 files changed

+311
-102
lines changed

src/components/SimpleProcessDesignerV2/src/NodeHandler.vue

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ const addNode = (type: number) => {
8181
type: NodeType.USER_TASK_NODE,
8282
approveMethod: ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE,
8383
candidateStrategy: CandidateStrategy.USER,
84-
// candidateParam: undefined,
85-
// fieldsPermission: undefined,
8684
// 超时处理
8785
rejectHandler: {
8886
type: RejectHandlerType.FINISH_PROCESS
@@ -92,20 +90,6 @@ const addNode = (type: number) => {
9290
},
9391
9492
childNode: props.childNode
95-
// 审批节点配置
96-
// attributes: {
97-
// approveMethod: ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE,
98-
// candidateStrategy: CandidateStrategy.USER,
99-
// candidateParam: undefined,
100-
// fieldsPermission: undefined,
101-
// // 超时处理
102-
// timeoutHandler: {
103-
// enable: false
104-
// },
105-
// rejectHandler: {
106-
// type: RejectHandlerType.FINISH_PROCESS
107-
// }
108-
// },
10993
}
11094
emits('update:childNode', data)
11195
}
@@ -118,12 +102,6 @@ const addNode = (type: number) => {
118102
candidateStrategy: CandidateStrategy.USER,
119103
candidateParam: undefined,
120104
fieldsPermission: undefined,
121-
// 审批节点配置
122-
// attributes: {
123-
// candidateStrategy: CandidateStrategy.USER,
124-
// candidateParam: undefined,
125-
// fieldsPermission: undefined
126-
// },
127105
childNode: props.childNode
128106
}
129107
emits('update:childNode', data)

src/components/SimpleProcessDesignerV2/src/consts.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ export type SimpleFlowNode = {
182182
approveMethod?: ApproveMethodType
183183
//通过比例
184184
approveRatio?: number
185+
// 审批按钮设置
186+
buttonsSetting?: any[]
185187
// 表单权限
186188
fieldsPermission?: any[]
187189
// 审批任务超时处理
@@ -214,6 +216,40 @@ export type ConditionRule = {
214216
rightSide: string
215217
}
216218

219+
// 审批操作按钮类型
220+
export enum OpsButtonType {
221+
/**
222+
* 通过
223+
*/
224+
APPROVE = 1,
225+
/**
226+
* 拒绝
227+
*/
228+
REJECT = 2,
229+
/**
230+
* 转办
231+
*/
232+
TRANSFER = 3,
233+
/**
234+
* 委派
235+
*/
236+
DELEGATE = 4,
237+
/**
238+
* 加签
239+
*/
240+
ADD_SIGN = 5,
241+
/**
242+
* 回退
243+
*/
244+
RETURN = 6
245+
}
246+
247+
export type ButtonSetting = {
248+
id: OpsButtonType
249+
displayName: string
250+
enable: boolean
251+
}
252+
217253
export const NODE_DEFAULT_TEXT = new Map<number, string>()
218254
NODE_DEFAULT_TEXT.set(NodeType.USER_TASK_NODE, '请配置审批人')
219255
NODE_DEFAULT_TEXT.set(NodeType.COPY_TASK_NODE, '请配置抄送人')
@@ -281,3 +317,21 @@ export const COMPARISON_OPERATORS: DictDataVO = [
281317
label: '小于等于'
282318
}
283319
]
320+
// 审批操作按钮名称
321+
export const OPERATION_BUTTON_NAME = new Map<number, string>()
322+
OPERATION_BUTTON_NAME.set(OpsButtonType.APPROVE, '通过')
323+
OPERATION_BUTTON_NAME.set(OpsButtonType.REJECT, '拒绝')
324+
OPERATION_BUTTON_NAME.set(OpsButtonType.TRANSFER, '转办')
325+
OPERATION_BUTTON_NAME.set(OpsButtonType.DELEGATE, '委派')
326+
OPERATION_BUTTON_NAME.set(OpsButtonType.ADD_SIGN, '加签')
327+
OPERATION_BUTTON_NAME.set(OpsButtonType.RETURN, '回退')
328+
329+
// 默认的按钮权限设置
330+
export const DEFAULT_BUTTON_SETTING: ButtonSetting[] = [
331+
{ id: OpsButtonType.APPROVE, displayName: '通过', enable: true },
332+
{ id: OpsButtonType.REJECT, displayName: '拒绝', enable: true },
333+
{ id: OpsButtonType.TRANSFER, displayName: '转办', enable: false },
334+
{ id: OpsButtonType.DELEGATE, displayName: '委派', enable: false },
335+
{ id: OpsButtonType.ADD_SIGN, displayName: '加签', enable: false },
336+
{ id: OpsButtonType.RETURN, displayName: '回退', enable: false }
337+
]

src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue

Lines changed: 137 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,40 @@
280280
</el-form>
281281
</div>
282282
</el-tab-pane>
283+
<el-tab-pane label="操作按钮设置" name="buttons" v-if="formType === 10">
284+
<div class="button-setting-pane">
285+
<div class="button-setting-desc">操作按钮</div>
286+
<div class="button-setting-title">
287+
<div class="button-title-label">操作按钮</div>
288+
<div class="pl-4 button-title-label">显示名称</div>
289+
<div class="button-title-label">启用</div>
290+
</div>
291+
<div
292+
class="button-setting-item"
293+
v-for="(item, index) in configForm.buttonsSetting"
294+
:key="index"
295+
>
296+
<div class="button-setting-item-label"> {{ OPERATION_BUTTON_NAME.get(item.id) }} </div>
297+
<div class="button-setting-item-label">
298+
<input
299+
type="text"
300+
class="editable-title-input"
301+
@blur="btnDisplayNameBlurEvent(index)"
302+
v-mountedFocus
303+
v-model="item.displayName"
304+
:placeholder="item.displayName"
305+
v-if="btnDisplayNameEdit[index]"
306+
/>
307+
<el-button v-else text @click="changeBtnDisplayName(index)"
308+
>{{ item.displayName }} &nbsp;<Icon icon="ep:edit"
309+
/></el-button>
310+
</div>
311+
<div class="button-setting-item-label">
312+
<el-switch v-model="item.enable" />
313+
</div>
314+
</div>
315+
</div>
316+
</el-tab-pane>
283317
<el-tab-pane label="表单字段权限" name="fields" v-if="formType === 10">
284318
<div class="field-setting-pane">
285319
<div class="field-setting-desc">字段权限</div>
@@ -334,7 +368,9 @@ import {
334368
TIMEOUT_HANDLER_ACTION_TYPES,
335369
TIME_UNIT_TYPES,
336370
REJECT_HANDLER_TYPES,
337-
NODE_DEFAULT_NAME
371+
NODE_DEFAULT_NAME,
372+
DEFAULT_BUTTON_SETTING,
373+
OPERATION_BUTTON_NAME
338374
} from '../consts'
339375
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
340376
import { getDefaultFieldsPermission } from '../utils'
@@ -345,7 +381,6 @@ import * as PostApi from '@/api/system/post'
345381
import * as UserApi from '@/api/system/user'
346382
import * as UserGroupApi from '@/api/bpm/userGroup'
347383
import { cloneDeep } from 'lodash-es'
348-
349384
defineOptions({
350385
name: 'UserTaskNodeConfig'
351386
})
@@ -385,7 +420,8 @@ const configForm = ref<any>({
385420
timeoutHandlerAction: 1,
386421
timeDuration: 6, // 默认 6小时
387422
maxRemindCount: 1, // 默认 提醒 1次
388-
fieldsPermission: []
423+
fieldsPermission: [],
424+
buttonsSetting: []
389425
})
390426
// 表单校验规则
391427
const formRules = reactive({
@@ -432,6 +468,8 @@ const saveConfig = async () => {
432468
}
433469
// 设置表单权限
434470
currentNode.value.fieldsPermission = configForm.value.fieldsPermission
471+
// 设置按钮权限
472+
currentNode.value.buttonsSetting = configForm.value.buttonsSetting
435473
436474
currentNode.value.showText = getShowText()
437475
settingVisible.value = false
@@ -533,6 +571,7 @@ const setCurrentNode = (node: SimpleFlowNode) => {
533571
currentNode.value = node
534572
configForm.value.fieldsPermission =
535573
cloneDeep(node.fieldsPermission) || getDefaultFieldsPermission(formFields?.value)
574+
configForm.value.buttonsSetting = cloneDeep(node.buttonsSetting) || DEFAULT_BUTTON_SETTING
536575
configForm.value.candidateStrategy = node.candidateStrategy
537576
const strCandidateParam = node?.candidateParam
538577
if (node.candidateStrategy === CandidateStrategy.EXPRESSION) {
@@ -614,6 +653,7 @@ const blurEvent = () => {
614653
currentNode.value.name =
615654
currentNode.value.name || (NODE_DEFAULT_NAME.get(NodeType.USER_TASK_NODE) as string)
616655
}
656+
617657
const approveMethodChanged = () => {
618658
configForm.value.rejectHandlerType = RejectHandlerType.FINISH_PROCESS
619659
if (configForm.value.approveMethod === ApproveMethodType.APPROVE_BY_RATIO) {
@@ -703,6 +743,99 @@ const convertTimeUnit = (strTimeUnit: string) => {
703743
}
704744
return TimeUnitType.HOUR
705745
}
746+
747+
// 操作按钮显示名称可编辑
748+
const btnDisplayNameEdit = ref<boolean[]>([])
749+
const changeBtnDisplayName = (index: number) => {
750+
btnDisplayNameEdit.value[index] = true
751+
}
752+
const btnDisplayNameBlurEvent = (index: number) => {
753+
btnDisplayNameEdit.value[index] = false
754+
const buttonItem = configForm.value.buttonPermission[index]
755+
buttonItem.displayName = buttonItem.displayName || OPERATION_BUTTON_NAME.get(buttonItem.id)
756+
}
706757
</script>
707758

708-
<style lang="scss" scoped></style>
759+
<style lang="scss" scoped>
760+
.button-setting-pane {
761+
display: flex;
762+
flex-direction: column;
763+
font-size: 14px;
764+
765+
.button-setting-desc {
766+
padding-right: 8px;
767+
margin-bottom: 16px;
768+
font-size: 16px;
769+
font-weight: 700;
770+
}
771+
772+
.button-setting-title {
773+
display: flex;
774+
justify-content: space-between;
775+
align-items: center;
776+
height: 45px;
777+
padding-left: 12px;
778+
background-color: #f8fafc0a;
779+
border: 1px solid #1f38581a;
780+
781+
& > :first-child {
782+
width: 100px !important;
783+
text-align: left !important;
784+
}
785+
786+
& > :last-child {
787+
text-align: center !important;
788+
}
789+
790+
.button-title-label {
791+
width: 150px;
792+
font-size: 13px;
793+
font-weight: 700;
794+
color: #000;
795+
text-align: left;
796+
}
797+
}
798+
799+
.button-setting-item {
800+
align-items: center;
801+
display: flex;
802+
justify-content: space-between;
803+
height: 38px;
804+
padding-left: 12px;
805+
border: 1px solid #1f38581a;
806+
border-top: 0;
807+
808+
& > :first-child {
809+
width: 100px !important;
810+
}
811+
812+
& > :last-child {
813+
text-align: center !important;
814+
}
815+
816+
.button-setting-item-label {
817+
width: 150px;
818+
overflow: hidden;
819+
text-align: left;
820+
text-overflow: ellipsis;
821+
white-space: nowrap;
822+
}
823+
824+
.editable-title-input {
825+
height: 24px;
826+
max-width: 130px;
827+
margin-left: 4px;
828+
line-height: 24px;
829+
border: 1px solid #d9d9d9;
830+
border-radius: 4px;
831+
transition: all 0.3s;
832+
833+
&:focus {
834+
border-color: #40a9ff;
835+
outline: 0;
836+
box-shadow: 0 0 0 2px rgb(24 144 255 / 20%);
837+
}
838+
}
839+
}
840+
}
841+
</style>

0 commit comments

Comments
 (0)