仿钉钉流程设计器- 删除第1版,新增连续多级部分负责人策略
parent
fd13eb7f8f
commit
ab9ce936a3
|
@ -1,386 +0,0 @@
|
||||||
/* stylelint-disable order/properties-order */
|
|
||||||
<template>
|
|
||||||
<div class="add-node-btn-box">
|
|
||||||
<div class="add-node-btn">
|
|
||||||
<el-popover placement="right-start" v-model="visible" width="auto">
|
|
||||||
<div class="add-node-popover-body">
|
|
||||||
<a class="add-node-popover-item approver" @click="addType(1)">
|
|
||||||
<div class="item-wrapper">
|
|
||||||
<span class="iconfont icon-approve"></span>
|
|
||||||
</div>
|
|
||||||
<p>审批人</p>
|
|
||||||
</a>
|
|
||||||
<!-- TODO 暂时去掉未完成
|
|
||||||
<a class="add-node-popover-item notifier" @click="addType(2)">
|
|
||||||
<div class="item-wrapper">
|
|
||||||
<span class="iconfont"></span>
|
|
||||||
</div>
|
|
||||||
<p>抄送人</p>
|
|
||||||
</a>
|
|
||||||
<a class="add-node-popover-item condition" @click="addType(4)">
|
|
||||||
<div class="item-wrapper">
|
|
||||||
<span class="iconfont"></span>
|
|
||||||
</div>
|
|
||||||
<p>条件分支</p>
|
|
||||||
</a>
|
|
||||||
-->
|
|
||||||
<a class="add-node-popover-item notifier" @click="addType(2)">
|
|
||||||
<div class="item-wrapper">
|
|
||||||
<span class="iconfont icon-copy"></span>
|
|
||||||
</div>
|
|
||||||
<p>抄送人</p>
|
|
||||||
</a>
|
|
||||||
<a class="add-node-popover-item condition" @click="addType(4)">
|
|
||||||
<div class="item-wrapper">
|
|
||||||
<span class="iconfont icon-exclusive"></span>
|
|
||||||
</div>
|
|
||||||
<p>条件分支</p>
|
|
||||||
</a>
|
|
||||||
<a class="add-node-popover-item condition" @click="addType(5)">
|
|
||||||
<div class="item-wrapper">
|
|
||||||
<span class="iconfont icon-parallel"></span>
|
|
||||||
</div>
|
|
||||||
<p>并行分支</p>
|
|
||||||
</a>
|
|
||||||
<a class="add-node-popover-item condition" @click="addType(7)">
|
|
||||||
<div class="item-wrapper">
|
|
||||||
<span class="iconfont icon-Inclusive"></span>
|
|
||||||
</div>
|
|
||||||
<p>包容分支</p>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<template #reference>
|
|
||||||
<button class="btn" type="button" v-if="showAddButton">
|
|
||||||
<span><Icon icon="ep:plus" class="addIcon" :size="14" /></span>
|
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
</el-popover>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { NodeType } from './consts'
|
|
||||||
import { ref } from 'vue'
|
|
||||||
import { generateUUID } from '@/utils'
|
|
||||||
let props = defineProps({
|
|
||||||
childNodeP: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
showAddButton: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
let emits = defineEmits(['update:childNodeP'])
|
|
||||||
let visible = ref(false)
|
|
||||||
const defaultFieldsPermission = inject('defaultFieldsPermission')
|
|
||||||
|
|
||||||
const addType = (type: number) => {
|
|
||||||
visible.value = false
|
|
||||||
// 审核节点
|
|
||||||
if (type === NodeType.APPROVE_USER_NODE) {
|
|
||||||
const data = {
|
|
||||||
name: '审核人',
|
|
||||||
error: true,
|
|
||||||
type: 1,
|
|
||||||
// 审批节点配置
|
|
||||||
attributes: {
|
|
||||||
approveMethod: undefined,
|
|
||||||
candidateStrategy: undefined,
|
|
||||||
candidateParam: undefined,
|
|
||||||
fieldsPermission: defaultFieldsPermission
|
|
||||||
},
|
|
||||||
childNode: props.childNodeP
|
|
||||||
}
|
|
||||||
emits('update:childNodeP', data)
|
|
||||||
}
|
|
||||||
// 抄送节点
|
|
||||||
if (type === NodeType.CC_USER_NODE) {
|
|
||||||
const data = {
|
|
||||||
name: '抄送人',
|
|
||||||
type: 2, // TODO @jason:这个要不要搞成枚举?NodeType 里貌似有枚举
|
|
||||||
error: true,
|
|
||||||
// 抄送节点配置
|
|
||||||
attributes: {
|
|
||||||
candidateStrategy: undefined,
|
|
||||||
candidateParam: undefined
|
|
||||||
},
|
|
||||||
childNode: props.childNodeP
|
|
||||||
}
|
|
||||||
emits('update:childNodeP', data)
|
|
||||||
}
|
|
||||||
// 条件分支
|
|
||||||
if (type === NodeType.EXCLUSIVE_NODE) {
|
|
||||||
const data = {
|
|
||||||
name: '条件分支',
|
|
||||||
type: 4,
|
|
||||||
id: 'GateWay_' + generateUUID(),
|
|
||||||
childNode: props.childNodeP,
|
|
||||||
conditionNodes: [
|
|
||||||
{
|
|
||||||
name: '分支1',
|
|
||||||
error: true,
|
|
||||||
type: 3,
|
|
||||||
priorityLevel: 1,
|
|
||||||
conditionList: [],
|
|
||||||
childNode: null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '其它情况',
|
|
||||||
type: 3,
|
|
||||||
priorityLevel: 2,
|
|
||||||
conditionList: [],
|
|
||||||
childNode: null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
emits('update:childNodeP', data)
|
|
||||||
}
|
|
||||||
// 并行分支 fork
|
|
||||||
if (type === NodeType.PARALLEL_NODE_FORK) {
|
|
||||||
const data = {
|
|
||||||
name: '并行分支_FORK',
|
|
||||||
type: 5,
|
|
||||||
id: 'GateWay_' + generateUUID(),
|
|
||||||
conditionNodes: [
|
|
||||||
{
|
|
||||||
name: '并行1',
|
|
||||||
error: true,
|
|
||||||
type: 3,
|
|
||||||
childNode: null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '并行2',
|
|
||||||
type: 3,
|
|
||||||
childNode: null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
childNode: {
|
|
||||||
id: 'GateWay_' + generateUUID(),
|
|
||||||
name: '并行分支_JOIN',
|
|
||||||
type: 6,
|
|
||||||
error: true,
|
|
||||||
childNode: props.childNodeP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emits('update:childNodeP', data)
|
|
||||||
}
|
|
||||||
// 包容分支 fork
|
|
||||||
if (type === NodeType.INCLUSIVE_NODE_FORK) {
|
|
||||||
const data = {
|
|
||||||
name: '包容分支_FORK',
|
|
||||||
type: 7,
|
|
||||||
id: 'GateWay_' + generateUUID(),
|
|
||||||
conditionNodes: [
|
|
||||||
{
|
|
||||||
name: '分支1',
|
|
||||||
error: true,
|
|
||||||
type: 3,
|
|
||||||
childNode: null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '其它情况',
|
|
||||||
type: 3,
|
|
||||||
childNode: null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
childNode: {
|
|
||||||
id: 'GateWay_' + generateUUID(),
|
|
||||||
name: '包容分支_JOIN',
|
|
||||||
type: 8,
|
|
||||||
error: true,
|
|
||||||
childNode: props.childNodeP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emits('update:childNodeP', data)
|
|
||||||
}
|
|
||||||
// if (type != 4) {
|
|
||||||
// var data
|
|
||||||
// if (type == 1) {
|
|
||||||
// data = {
|
|
||||||
// name: '审核人',
|
|
||||||
// error: true,
|
|
||||||
// type: 1,
|
|
||||||
// // 审批节点配置
|
|
||||||
// attributes : {
|
|
||||||
// approveMethod : undefined,
|
|
||||||
// candidateStrategy: undefined,
|
|
||||||
// candidateParam: undefined
|
|
||||||
// },
|
|
||||||
// childNode: props.childNodeP
|
|
||||||
// }
|
|
||||||
// } else if (type == 2) {
|
|
||||||
// data = {
|
|
||||||
// name: '抄送人',
|
|
||||||
// type: 2,
|
|
||||||
// error: true,
|
|
||||||
// // 抄送节点配置
|
|
||||||
// attributes : {
|
|
||||||
// candidateStrategy: undefined,
|
|
||||||
// candidateParam: undefined
|
|
||||||
// },
|
|
||||||
// childNode: props.childNodeP
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// emits('update:childNodeP', data)
|
|
||||||
// } else {
|
|
||||||
// emits('update:childNodeP', {
|
|
||||||
// name: '路由',
|
|
||||||
// type: 4,
|
|
||||||
// id : 'GateWay_'+ generateUUID(),
|
|
||||||
// childNode: props.childNodeP,
|
|
||||||
// conditionNodes: [
|
|
||||||
// {
|
|
||||||
// name: '条件1',
|
|
||||||
// error: true,
|
|
||||||
// type: 3,
|
|
||||||
// priorityLevel: 1,
|
|
||||||
// conditionList: [],
|
|
||||||
// childNode: null
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: '其它情况',
|
|
||||||
// type: 3,
|
|
||||||
// priorityLevel: 2,
|
|
||||||
// conditionList: [],
|
|
||||||
// childNode: null
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.add-node-btn-box {
|
|
||||||
position: relative;
|
|
||||||
display: inline-flex;
|
|
||||||
width: 240px;
|
|
||||||
-ms-flex-negative: 0;
|
|
||||||
flex-shrink: 0;
|
|
||||||
-webkit-box-flex: 1;
|
|
||||||
-ms-flex-positive: 1;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
z-index: -1;
|
|
||||||
width: 2px;
|
|
||||||
height: 100%;
|
|
||||||
margin: auto;
|
|
||||||
background-color: #cacaca;
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-node-btn {
|
|
||||||
display: flex;
|
|
||||||
width: 240px;
|
|
||||||
padding: 20px 0 32px;
|
|
||||||
justify-content: center;
|
|
||||||
flex-shrink: 0;
|
|
||||||
-webkit-box-flex: 1;
|
|
||||||
-webkit-box-pack: center;
|
|
||||||
user-select: none;
|
|
||||||
flex-grow: 1;
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
position: relative;
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
background: #3296fa;
|
|
||||||
border: none;
|
|
||||||
border-radius: 50%;
|
|
||||||
outline: none;
|
|
||||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
|
|
||||||
-webkit-transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
|
||||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
|
||||||
|
|
||||||
.addIcon {
|
|
||||||
line-height: 30px;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.3);
|
|
||||||
box-shadow: 0 13px 27px 0 rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background: #1e83e9;
|
|
||||||
transform: none;
|
|
||||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-node-popover-body {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
.add-node-popover-item {
|
|
||||||
margin-right: 10px;
|
|
||||||
cursor: pointer;
|
|
||||||
text-align: center;
|
|
||||||
flex: 1;
|
|
||||||
color: #191f25 !important;
|
|
||||||
|
|
||||||
.item-wrapper {
|
|
||||||
display: inline-block;
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
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;
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
font-size: 35px;
|
|
||||||
line-height: 80px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.approver {
|
|
||||||
.item-wrapper {
|
|
||||||
color: #ff943e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.notifier {
|
|
||||||
.item-wrapper {
|
|
||||||
color: #3296fa;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.condition {
|
|
||||||
.item-wrapper {
|
|
||||||
color: #15bc83;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.item-wrapper {
|
|
||||||
background: #3296fa;
|
|
||||||
box-shadow: 0 10px 20px 0 rgba(50, 150, 250, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
.item-wrapper {
|
|
||||||
background: #eaeaea;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,63 +0,0 @@
|
||||||
export enum NodeType {
|
|
||||||
//// -1 根节点流程开始节点 0 发起人 1审批 2抄送 3条件 4路由
|
|
||||||
ROOT_NODE = -1,
|
|
||||||
/**
|
|
||||||
* 发起人节点
|
|
||||||
*/
|
|
||||||
START_USER_NODE = 0,
|
|
||||||
/**
|
|
||||||
* 审批人节点
|
|
||||||
*/
|
|
||||||
APPROVE_USER_NODE = 1,
|
|
||||||
/**
|
|
||||||
* 抄送人节点
|
|
||||||
*/
|
|
||||||
CC_USER_NODE = 2,
|
|
||||||
/**
|
|
||||||
* 条件节点
|
|
||||||
*/
|
|
||||||
CONDITION_NODE = 3,
|
|
||||||
/**
|
|
||||||
* 条件分支节点
|
|
||||||
*/
|
|
||||||
EXCLUSIVE_NODE = 4,
|
|
||||||
/**
|
|
||||||
* 并行分支分叉节点
|
|
||||||
*/
|
|
||||||
PARALLEL_NODE_FORK = 5,
|
|
||||||
/**
|
|
||||||
* 并行分支聚合
|
|
||||||
*/
|
|
||||||
PARALLEL_NODE_JOIN = 6,
|
|
||||||
/**
|
|
||||||
* 包容分支分叉节点
|
|
||||||
*/
|
|
||||||
INCLUSIVE_NODE_FORK = 7,
|
|
||||||
/**
|
|
||||||
* 包容分支聚合节点
|
|
||||||
*/
|
|
||||||
INCLUSIVE_NODE_JOIN = 8
|
|
||||||
}
|
|
||||||
|
|
||||||
export const NODE_BG_COLOR = new Map()
|
|
||||||
NODE_BG_COLOR.set(NodeType.START_USER_NODE, '#87, 106, 149')
|
|
||||||
NODE_BG_COLOR.set(NodeType.APPROVE_USER_NODE, '#255, 148, 62')
|
|
||||||
NODE_BG_COLOR.set(NodeType.CC_USER_NODE, '#50, 150, 250')
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 节点的标题
|
|
||||||
*/
|
|
||||||
export const NODE_TITLE = new Map()
|
|
||||||
NODE_TITLE.set(NodeType.START_USER_NODE, '发起人')
|
|
||||||
NODE_TITLE.set(NodeType.APPROVE_USER_NODE, '审批人')
|
|
||||||
NODE_TITLE.set(NodeType.CC_USER_NODE, '抄送人')
|
|
||||||
|
|
||||||
export type WorkFlowNode = {
|
|
||||||
id: string,
|
|
||||||
type: NodeType,
|
|
||||||
name: string,
|
|
||||||
attributes: any,
|
|
||||||
// 操作人
|
|
||||||
childNode?: WorkFlowNode | undefined,
|
|
||||||
conditionNodes: WorkFlowNode[]
|
|
||||||
}
|
|
|
@ -1,434 +0,0 @@
|
||||||
<!-- eslint-disable vue/html-self-closing -->
|
|
||||||
<template>
|
|
||||||
<el-drawer
|
|
||||||
:append-to-body="true"
|
|
||||||
v-model="visible"
|
|
||||||
:show-close="false"
|
|
||||||
:size="550"
|
|
||||||
:before-close="saveConfig"
|
|
||||||
class="justify-start"
|
|
||||||
>
|
|
||||||
<template #header>
|
|
||||||
<div class="w-full flex flex-col">
|
|
||||||
<span class="text-size-2xl">审批设置</span>
|
|
||||||
<el-divider />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<el-tabs type="border-card">
|
|
||||||
<el-tab-pane label="审批人">
|
|
||||||
<div>
|
|
||||||
<el-form label-position="top" label-width="100px">
|
|
||||||
<el-form-item label="审批方式" prop="approveMethod">
|
|
||||||
<el-select v-model="candidateConfig.approveMethod" style="width: 100%" clearable>
|
|
||||||
<el-option
|
|
||||||
v-for="dict in approveMethods"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item label="审批人规则类型" prop="candidateStrategy">
|
|
||||||
<el-select
|
|
||||||
v-model="candidateConfig.candidateStrategy"
|
|
||||||
style="width: 100%"
|
|
||||||
clearable
|
|
||||||
@change="changecandidateStrategy"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY)"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item
|
|
||||||
v-if="candidateConfig.candidateStrategy == 10"
|
|
||||||
label="指定角色"
|
|
||||||
prop="candidateParam"
|
|
||||||
>
|
|
||||||
<el-select
|
|
||||||
v-model="candidateConfig.candidateParam"
|
|
||||||
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="
|
|
||||||
candidateConfig.candidateStrategy == 20 || candidateConfig.candidateStrategy == 21
|
|
||||||
"
|
|
||||||
label="指定部门"
|
|
||||||
prop="candidateParam"
|
|
||||||
span="24"
|
|
||||||
>
|
|
||||||
<el-tree-select
|
|
||||||
ref="treeRef"
|
|
||||||
v-model="candidateConfig.candidateParam"
|
|
||||||
:data="deptTreeOptions"
|
|
||||||
:props="defaultProps"
|
|
||||||
empty-text="加载中,请稍后"
|
|
||||||
multiple
|
|
||||||
node-key="id"
|
|
||||||
style="width: 100%"
|
|
||||||
show-checkbox
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-if="candidateConfig.candidateStrategy == 22"
|
|
||||||
label="指定岗位"
|
|
||||||
prop="candidateParam"
|
|
||||||
span="24"
|
|
||||||
>
|
|
||||||
<el-select
|
|
||||||
v-model="candidateConfig.candidateParam"
|
|
||||||
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="
|
|
||||||
candidateConfig.candidateStrategy == 30 ||
|
|
||||||
candidateConfig.candidateStrategy == 31 ||
|
|
||||||
candidateConfig.candidateStrategy == 32
|
|
||||||
"
|
|
||||||
label="指定用户"
|
|
||||||
prop="candidateParam"
|
|
||||||
span="24"
|
|
||||||
>
|
|
||||||
<el-select
|
|
||||||
v-model="candidateConfig.candidateParam"
|
|
||||||
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="candidateConfig.candidateStrategy === 40"
|
|
||||||
label="指定用户组"
|
|
||||||
prop="candidateParam"
|
|
||||||
>
|
|
||||||
<el-select
|
|
||||||
v-model="candidateConfig.candidateParam"
|
|
||||||
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="candidateConfig.candidateStrategy === 60"
|
|
||||||
label="流程表达式"
|
|
||||||
prop="candidateParam"
|
|
||||||
>
|
|
||||||
<el-input
|
|
||||||
type="textarea"
|
|
||||||
v-model="candidateConfig.candidateParam[0]"
|
|
||||||
clearable
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
</el-tab-pane>
|
|
||||||
<el-tab-pane label="设置字段权限" v-if="formType === 10">
|
|
||||||
<div class="field-setting-pane h-full w-full flex flex-col">
|
|
||||||
<div class="field-setting-content mr-2 overflow-auto py-4 pr-2">
|
|
||||||
<div class="field-container flex flex-col flex-items-start">
|
|
||||||
<div class="mb-2 ml-4 font-bold">字段权限</div>
|
|
||||||
<div class="field-body ml-4 mt-2">
|
|
||||||
<div class="field-permit-box text-size--13px">
|
|
||||||
<div class="field-permit-title">
|
|
||||||
<span class="setting-title-label">组件名称</span>
|
|
||||||
<span class="setting-title-label">可编辑</span>
|
|
||||||
<span class="setting-title-label">只读</span>
|
|
||||||
<span class="setting-title-label">隐藏</span>
|
|
||||||
</div>
|
|
||||||
<!-- <div class="field-setting-item">
|
|
||||||
<span class="field-setting-item-label">全选</span>
|
|
||||||
<span class="all-checkbox-wrap">
|
|
||||||
<el-checkbox
|
|
||||||
label=""
|
|
||||||
size="large"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<span class="all-checkbox-wrap">
|
|
||||||
<el-checkbox
|
|
||||||
label=""
|
|
||||||
size="large"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<span class="all-checkbox-wrap">
|
|
||||||
<el-checkbox
|
|
||||||
label=""
|
|
||||||
size="large"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div> -->
|
|
||||||
<div class="field-setting-item-check">
|
|
||||||
<div
|
|
||||||
class="field-setting-item"
|
|
||||||
v-for="(item, index) in candidateConfig.fieldsPermission"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<span class="field-setting-item-label"> {{ item.title }}</span>
|
|
||||||
<el-radio-group v-model="item.permission">
|
|
||||||
<div class="item-radio-wrap">
|
|
||||||
<el-radio value="1" size="large" label="1" />
|
|
||||||
</div>
|
|
||||||
<div class="item-radio-wrap">
|
|
||||||
<el-radio value="2" size="large" label="2" />
|
|
||||||
</div>
|
|
||||||
<div class="item-radio-wrap">
|
|
||||||
<el-radio value="3" size="large" label="3" />
|
|
||||||
</div>
|
|
||||||
</el-radio-group>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</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 lang="ts" setup>
|
|
||||||
import { ref, watch, computed, toRaw } from 'vue'
|
|
||||||
import { approveMethods } from '../util'
|
|
||||||
import { useWorkFlowStoreWithOut } from '@/store/modules/bpm/simpleWorkflow'
|
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
|
||||||
import { defaultProps, handleTree } from '@/utils/tree'
|
|
||||||
import * as RoleApi from '@/api/system/role'
|
|
||||||
import * as DeptApi from '@/api/system/dept'
|
|
||||||
import * as PostApi from '@/api/system/post'
|
|
||||||
import * as UserApi from '@/api/system/user'
|
|
||||||
import * as UserGroupApi from '@/api/bpm/userGroup'
|
|
||||||
|
|
||||||
const roleOptions = ref<RoleApi.RoleVO[]>([]) // 角色列表
|
|
||||||
const postOptions = ref<PostApi.PostVO[]>([]) // 岗位列表
|
|
||||||
const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
|
|
||||||
const deptTreeOptions = ref() // 部门树
|
|
||||||
const userGroupOptions = ref<UserGroupApi.UserGroupVO[]>([]) // 用户组列表
|
|
||||||
const candidateConfig = ref({
|
|
||||||
candidateStrategy: undefined,
|
|
||||||
candidateParam: [],
|
|
||||||
approveMethod: undefined,
|
|
||||||
fieldsPermission: []
|
|
||||||
})
|
|
||||||
const store = useWorkFlowStoreWithOut()
|
|
||||||
let { setApproverDrawer, setUserTaskConfig } = store
|
|
||||||
// let approverConfig1 = computed(() => store.approverConfig1)
|
|
||||||
let approverDrawer = computed(() => store.approverDrawer)
|
|
||||||
const userTaskConfig = computed(() => store.userTaskConfig)
|
|
||||||
const formType = inject('formType')
|
|
||||||
let visible = computed({
|
|
||||||
get() {
|
|
||||||
return approverDrawer.value
|
|
||||||
},
|
|
||||||
set() {
|
|
||||||
closeDrawer()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
watch(userTaskConfig, (val) => {
|
|
||||||
if (val.value.attributes) {
|
|
||||||
candidateConfig.value.approveMethod = val.value.attributes.approveMethod
|
|
||||||
candidateConfig.value.candidateStrategy = val.value.attributes.candidateStrategy
|
|
||||||
const candidateParamStr = val.value.attributes.candidateParam
|
|
||||||
if (val.value.attributes.candidateStrategy === 60) {
|
|
||||||
candidateConfig.value.candidateParam = [candidateParamStr]
|
|
||||||
} else {
|
|
||||||
if (candidateParamStr) {
|
|
||||||
candidateConfig.value.candidateParam = candidateParamStr.split(',').map((item) => +item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log('val.value.attributes.fieldsPermission', val.value.attributes.fieldsPermission)
|
|
||||||
candidateConfig.value.fieldsPermission = val.value.attributes.fieldsPermission
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// watch(approverConfig1, (val) => {
|
|
||||||
// approverConfig.value = val.value
|
|
||||||
// })
|
|
||||||
|
|
||||||
const saveConfig = () => {
|
|
||||||
const rawConfig = toRaw(userTaskConfig.value)
|
|
||||||
const { approveMethod, candidateStrategy, candidateParam, fieldsPermission } = toRaw(
|
|
||||||
candidateConfig.value
|
|
||||||
)
|
|
||||||
const candidateParamStr = candidateParam.join(',')
|
|
||||||
rawConfig.value.attributes = {
|
|
||||||
approveMethod,
|
|
||||||
candidateStrategy,
|
|
||||||
candidateParam: candidateParamStr,
|
|
||||||
fieldsPermission: fieldsPermission
|
|
||||||
}
|
|
||||||
rawConfig.flag = true
|
|
||||||
// TODO 进行校验
|
|
||||||
// setApproverConfig({
|
|
||||||
// value: approverConfig.value,
|
|
||||||
// flag: true,
|
|
||||||
// id: approverConfig1.value.id
|
|
||||||
// })
|
|
||||||
setUserTaskConfig({
|
|
||||||
value: rawConfig.value,
|
|
||||||
flag: true,
|
|
||||||
id: userTaskConfig.value.id
|
|
||||||
})
|
|
||||||
closeDrawer()
|
|
||||||
}
|
|
||||||
|
|
||||||
const closeDrawer = () => {
|
|
||||||
setApproverDrawer(false)
|
|
||||||
}
|
|
||||||
const changecandidateStrategy = () => {
|
|
||||||
candidateConfig.value.candidateParam = []
|
|
||||||
}
|
|
||||||
const handleAllCheck = (event, type) => {
|
|
||||||
console.log('event', event)
|
|
||||||
console.log('type', type)
|
|
||||||
event.target.checked = true
|
|
||||||
let permission = '1'
|
|
||||||
if (type === 'edit' && editAllChecked.value) {
|
|
||||||
permission = '1' // TODO @jaosn:这个要不要用枚举里的哈
|
|
||||||
}
|
|
||||||
if (type === 'read' && readAllChecked.value) {
|
|
||||||
permission = '2'
|
|
||||||
}
|
|
||||||
if (type === 'hide' && hideAllChecked.value) {
|
|
||||||
permission = '3'
|
|
||||||
}
|
|
||||||
candidateConfig.value.fieldsPermission.forEach((item) => {
|
|
||||||
item.permission = permission
|
|
||||||
})
|
|
||||||
}
|
|
||||||
onMounted(async () => {
|
|
||||||
// 获得角色列表
|
|
||||||
roleOptions.value = await RoleApi.getSimpleRoleList()
|
|
||||||
// 获得岗位列表
|
|
||||||
postOptions.value = await PostApi.getSimplePostList()
|
|
||||||
// 获得用户列表
|
|
||||||
userOptions.value = await UserApi.getSimpleUserList()
|
|
||||||
// 获得部门列表
|
|
||||||
const deptOptions = await DeptApi.getSimpleDeptList()
|
|
||||||
deptTreeOptions.value = handleTree(deptOptions, 'id')
|
|
||||||
// 获得用户组列表
|
|
||||||
userGroupOptions.value = await UserGroupApi.getUserGroupSimpleList()
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
// ::v-deep .el-drawer__header {
|
|
||||||
// margin-bottom: 2px;
|
|
||||||
// }
|
|
||||||
.field-permit-title {
|
|
||||||
height: 45px;
|
|
||||||
padding: 0 0 0 12px;
|
|
||||||
line-height: 32px;
|
|
||||||
background-color: rgba(248, 250, 252, 0.04);
|
|
||||||
border: 1px solid rgba(31, 56, 88, 0.1);
|
|
||||||
|
|
||||||
.setting-title-label:first-child {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting-title-label {
|
|
||||||
display: inline-block;
|
|
||||||
width: 110px;
|
|
||||||
padding: 5px 0;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 700;
|
|
||||||
color: rgba(0, 0, 0, 0.6);
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-setting-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
height: 38px;
|
|
||||||
padding-bottom: 0;
|
|
||||||
padding-left: 12px;
|
|
||||||
line-height: 38px;
|
|
||||||
border-right: 1px solid rgba(31, 56, 88, 0.1);
|
|
||||||
border-bottom: 1px solid rgba(31, 56, 88, 0.1);
|
|
||||||
border-left: 1px solid rgba(31, 56, 88, 0.1);
|
|
||||||
|
|
||||||
.no-label {
|
|
||||||
font-size: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-setting-item-label {
|
|
||||||
display: inline-block;
|
|
||||||
width: 110px;
|
|
||||||
min-height: 16px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
cursor: text;
|
|
||||||
}
|
|
||||||
|
|
||||||
.all-checkbox-wrap {
|
|
||||||
display: inline-block;
|
|
||||||
width: 110px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-radio-wrap {
|
|
||||||
display: inline-block;
|
|
||||||
width: 110px;
|
|
||||||
padding-left: 6px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.el-radio__label) {
|
|
||||||
opacity: 0; /* 隐藏标签文本 */
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.el-divider--horizontal) {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 1px;
|
|
||||||
margin: 4px 0;
|
|
||||||
border-top: 1px var(--el-border-color) var(--el-border-style);
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,250 +0,0 @@
|
||||||
<template>
|
|
||||||
<el-drawer
|
|
||||||
:append-to-body="true"
|
|
||||||
v-model="visible"
|
|
||||||
:show-close="false"
|
|
||||||
:size="550"
|
|
||||||
:before-close="saveConfig"
|
|
||||||
>
|
|
||||||
<template #header>
|
|
||||||
<div class="copy-task-header">抄送人设置</div>
|
|
||||||
</template>
|
|
||||||
<div>
|
|
||||||
<el-form label-position="top" label-width="100px">
|
|
||||||
<el-form-item label="选择抄送人" prop="candidateStrategy">
|
|
||||||
<el-select
|
|
||||||
v-model="candidateConfig.candidateStrategy"
|
|
||||||
style="width: 100%"
|
|
||||||
clearable
|
|
||||||
@change="changecandidateStrategy"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY)"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item
|
|
||||||
v-if="candidateConfig.candidateStrategy == 10"
|
|
||||||
label="指定角色"
|
|
||||||
prop="candidateParam"
|
|
||||||
>
|
|
||||||
<el-select
|
|
||||||
v-model="candidateConfig.candidateParam"
|
|
||||||
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="candidateConfig.candidateStrategy == 20 || candidateConfig.candidateStrategy == 21"
|
|
||||||
label="指定部门"
|
|
||||||
prop="candidateParam"
|
|
||||||
span="24"
|
|
||||||
>
|
|
||||||
<el-tree-select
|
|
||||||
ref="treeRef"
|
|
||||||
v-model="candidateConfig.candidateParam"
|
|
||||||
:data="deptTreeOptions"
|
|
||||||
:props="defaultProps"
|
|
||||||
empty-text="加载中,请稍后"
|
|
||||||
multiple
|
|
||||||
node-key="id"
|
|
||||||
style="width: 100%"
|
|
||||||
show-checkbox
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-if="candidateConfig.candidateStrategy == 22"
|
|
||||||
label="指定岗位"
|
|
||||||
prop="candidateParam"
|
|
||||||
span="24"
|
|
||||||
>
|
|
||||||
<el-select
|
|
||||||
v-model="candidateConfig.candidateParam"
|
|
||||||
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="
|
|
||||||
candidateConfig.candidateStrategy == 30 ||
|
|
||||||
candidateConfig.candidateStrategy == 31 ||
|
|
||||||
candidateConfig.candidateStrategy == 32
|
|
||||||
"
|
|
||||||
label="指定用户"
|
|
||||||
prop="candidateParam"
|
|
||||||
span="24"
|
|
||||||
>
|
|
||||||
<el-select
|
|
||||||
v-model="candidateConfig.candidateParam"
|
|
||||||
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="candidateConfig.candidateStrategy === 40"
|
|
||||||
label="指定用户组"
|
|
||||||
prop="candidateParam"
|
|
||||||
>
|
|
||||||
<el-select
|
|
||||||
v-model="candidateConfig.candidateParam"
|
|
||||||
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="candidateConfig.candidateStrategy === 60"
|
|
||||||
label="流程表达式"
|
|
||||||
prop="candidateParam"
|
|
||||||
>
|
|
||||||
<el-input
|
|
||||||
type="textarea"
|
|
||||||
v-model="candidateConfig.candidateParam[0]"
|
|
||||||
clearable
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
<div class="demo-drawer__footer clear">
|
|
||||||
<el-button type="primary" @click="saveConfig">确 定</el-button>
|
|
||||||
<el-button @click="closeDrawer">取 消</el-button>
|
|
||||||
</div>
|
|
||||||
</el-drawer>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, watch, computed, toRaw } from 'vue'
|
|
||||||
import { useWorkFlowStoreWithOut } from '@/store/modules/bpm/simpleWorkflow'
|
|
||||||
import { DICT_TYPE, getIntDictOptions, getDictLabel } from '@/utils/dict'
|
|
||||||
import { defaultProps, handleTree } from '@/utils/tree'
|
|
||||||
import * as RoleApi from '@/api/system/role'
|
|
||||||
import * as DeptApi from '@/api/system/dept'
|
|
||||||
import * as PostApi from '@/api/system/post'
|
|
||||||
import * as UserApi from '@/api/system/user'
|
|
||||||
import * as UserGroupApi from '@/api/bpm/userGroup'
|
|
||||||
|
|
||||||
const roleOptions = ref<RoleApi.RoleVO[]>([]) // 角色列表
|
|
||||||
const postOptions = ref<PostApi.PostVO[]>([]) // 岗位列表
|
|
||||||
const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
|
|
||||||
const deptTreeOptions = ref() // 部门树
|
|
||||||
const userGroupOptions = ref<UserGroupApi.UserGroupVO[]>([]) // 用户组列表
|
|
||||||
const candidateConfig = ref({
|
|
||||||
candidateStrategy: undefined,
|
|
||||||
candidateParam: []
|
|
||||||
})
|
|
||||||
const store = useWorkFlowStoreWithOut()
|
|
||||||
const { setCopyerDrawer, setCopyerConfig } = store
|
|
||||||
|
|
||||||
const copyerDrawer = computed(() => store.copyerDrawer)
|
|
||||||
const copyerConfig = computed(() => store.copyerConfig)
|
|
||||||
|
|
||||||
const visible = computed({
|
|
||||||
get() {
|
|
||||||
return copyerDrawer.value
|
|
||||||
},
|
|
||||||
set() {
|
|
||||||
closeDrawer()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
watch(copyerConfig, (val) => {
|
|
||||||
if (val.value.attributes) {
|
|
||||||
console.log('val.value.attributes', val.value.attributes)
|
|
||||||
candidateConfig.value.candidateStrategy = val.value.attributes.candidateStrategy
|
|
||||||
const candidateParamStr = val.value.attributes.candidateParam
|
|
||||||
if (val.value.attributes.candidateStrategy === 60) {
|
|
||||||
candidateConfig.value.candidateParam = [candidateParamStr]
|
|
||||||
} else {
|
|
||||||
if (candidateParamStr) {
|
|
||||||
candidateConfig.value.candidateParam = candidateParamStr.split(',').map((item) => +item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// candidateConfig.value = val.value.attributes
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const saveConfig = () => {
|
|
||||||
const rawConfig = toRaw(copyerConfig.value)
|
|
||||||
const { candidateStrategy, candidateParam } = toRaw(candidateConfig.value)
|
|
||||||
const candidateParamStr = candidateParam.join(',')
|
|
||||||
rawConfig.value.attributes = {
|
|
||||||
candidateStrategy,
|
|
||||||
candidateParam: candidateParamStr
|
|
||||||
}
|
|
||||||
rawConfig.flag = true
|
|
||||||
// TODO 进行校验
|
|
||||||
// setApproverConfig({
|
|
||||||
// value: approverConfig.value,
|
|
||||||
// flag: true,
|
|
||||||
// id: approverConfig1.value.id
|
|
||||||
// })
|
|
||||||
|
|
||||||
setCopyerConfig({
|
|
||||||
value: rawConfig.value,
|
|
||||||
flag: true,
|
|
||||||
id: copyerConfig.value.id
|
|
||||||
})
|
|
||||||
console.log('after is copyerConfig', copyerConfig.value)
|
|
||||||
closeDrawer()
|
|
||||||
}
|
|
||||||
|
|
||||||
const closeDrawer = () => {
|
|
||||||
setCopyerDrawer(false)
|
|
||||||
}
|
|
||||||
const changecandidateStrategy = () => {
|
|
||||||
candidateConfig.value.candidateParam = []
|
|
||||||
}
|
|
||||||
onMounted(async () => {
|
|
||||||
// 获得角色列表
|
|
||||||
roleOptions.value = await RoleApi.getSimpleRoleList()
|
|
||||||
// 获得岗位列表
|
|
||||||
postOptions.value = await PostApi.getSimplePostList()
|
|
||||||
// 获得用户列表
|
|
||||||
userOptions.value = await UserApi.getSimpleUserList()
|
|
||||||
// 获得部门列表
|
|
||||||
const deptOptions = await DeptApi.getSimpleDeptList()
|
|
||||||
deptTreeOptions.value = handleTree(deptOptions, 'id')
|
|
||||||
// 获得用户组列表
|
|
||||||
userGroupOptions.value = await UserGroupApi.getUserGroupSimpleList()
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.copy-task-header {
|
|
||||||
font-size: 16px !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,504 +0,0 @@
|
||||||
<!-- eslint-disable vue/no-mutating-props -->
|
|
||||||
<!--
|
|
||||||
* @Date: 2022-09-21 14:41:53
|
|
||||||
* @LastEditors: StavinLi 495727881@qq.com
|
|
||||||
* @LastEditTime: 2023-05-24 15:20:24
|
|
||||||
* @FilePath: /Workflow-Vue3/src/components/nodeWrap.vue
|
|
||||||
-->
|
|
||||||
<template>
|
|
||||||
<div class="node-wrap" v-if="nodeConfig.type < 3">
|
|
||||||
<div class="node-wrap-box" :class="isTried && nodeConfig.error ? 'active error' : ''">
|
|
||||||
<div class="title" :style="`background: rgb(${bgColors[nodeConfig.type]});`">
|
|
||||||
<span v-if="nodeConfig.type == 0">发起人</span>
|
|
||||||
<template v-else>
|
|
||||||
<span
|
|
||||||
class="iconfont"
|
|
||||||
:class="nodeConfig.type === NodeType.APPROVE_USER_NODE ? 'icon-approve' : 'icon-copy'"
|
|
||||||
>
|
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
v-if="isInput"
|
|
||||||
type="text"
|
|
||||||
class="ant-input editable-title-input"
|
|
||||||
@blur="blurEvent(-1)"
|
|
||||||
@focus="$event.currentTarget?.select()"
|
|
||||||
v-mountedFocus
|
|
||||||
v-model="nodeConfig.name"
|
|
||||||
:placeholder="defaultText"
|
|
||||||
/>
|
|
||||||
<span v-else class="editable-title" @click="clickEvent(-1)">{{ nodeConfig.name }}</span>
|
|
||||||
<i class="anticon anticon-close close" @click="delNode"></i>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div class="content" @click="setPerson">
|
|
||||||
<div class="text">
|
|
||||||
<span class="placeholder" v-if="!showText">请选择{{ defaultText }}</span>
|
|
||||||
<span v-html="showText" class="ellipsis-text" v-else></span>
|
|
||||||
</div>
|
|
||||||
<!-- <div class="icon-box">
|
|
||||||
<i class="anticon anticon-edit" @click="editNode"></i>
|
|
||||||
</div> -->
|
|
||||||
<i class="anticon anticon-right arrow"></i>
|
|
||||||
</div>
|
|
||||||
<div class="error_tip" v-if="isTried && nodeConfig.error">
|
|
||||||
<i class="anticon anticon-exclamation-circle"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<addNode v-model:childNodeP="nodeConfig.childNode" />
|
|
||||||
</div>
|
|
||||||
<div class="branch-wrap" v-if="nodeConfig.type == 4">
|
|
||||||
<div class="branch-box-wrap">
|
|
||||||
<div class="branch-box">
|
|
||||||
<button class="add-branch" @click="addTerm(nodeConfig.type)">添加条件</button>
|
|
||||||
<div class="col-box" v-for="(item, index) in nodeConfig.conditionNodes" :key="index">
|
|
||||||
<div class="condition-node">
|
|
||||||
<div class="condition-node-box">
|
|
||||||
<div class="title-wrapper" :style="`background: rgb(${bgColors[nodeConfig.type]});`">
|
|
||||||
<input
|
|
||||||
v-if="isInputList[index]"
|
|
||||||
type="text"
|
|
||||||
class="ant-input editable-title-input"
|
|
||||||
@blur="blurEvent(index)"
|
|
||||||
@focus="$event.currentTarget?.select()"
|
|
||||||
v-mountedFocus
|
|
||||||
v-model="item.name"
|
|
||||||
/>
|
|
||||||
<span v-else class="editable-title" @click="clickEvent(index)">{{
|
|
||||||
item.name
|
|
||||||
}}</span>
|
|
||||||
<!-- <span class="priority-title" @click="setPerson(item.priorityLevel)"
|
|
||||||
>优先级{{ index + 1 }}</span
|
|
||||||
> -->
|
|
||||||
<i
|
|
||||||
class="anticon anticon-close close"
|
|
||||||
@click="delTerm(nodeConfig.type,index)"
|
|
||||||
v-if="nodeConfig.conditionNodes && index != nodeConfig.conditionNodes?.length - 1"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div class="auto-judge" :class="isTried && item.error ? 'error active' : ''">
|
|
||||||
<!-- <div class="sort-left" v-if="index != 0" @click="arrTransfer(index, -1)"><</div> -->
|
|
||||||
|
|
||||||
<!-- <div
|
|
||||||
class="sort-right"
|
|
||||||
v-if="index != nodeConfig.conditionNodes.length - 1"
|
|
||||||
@click="arrTransfer(index)"
|
|
||||||
>></div
|
|
||||||
> -->
|
|
||||||
<!-- <div class="content" @click="setPerson(item.priorityLevel)">{{
|
|
||||||
conditionStr(nodeConfig, index)
|
|
||||||
}}</div> -->
|
|
||||||
<div class="content">{{ conditionStr(nodeConfig, index) }}</div>
|
|
||||||
<div class="error_tip" v-if="isTried && item.error">
|
|
||||||
<i class="anticon anticon-exclamation-circle"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<addNode v-model:childNodeP="item.childNode" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<nodeWrap v-if="item.childNode" v-model:nodeConfig="item.childNode" />
|
|
||||||
<template v-if="index == 0">
|
|
||||||
<div class="top-left-cover-line"></div>
|
|
||||||
<div class="bottom-left-cover-line"></div>
|
|
||||||
</template>
|
|
||||||
<template v-if="index == nodeConfig.conditionNodes.length - 1">
|
|
||||||
<div class="top-right-cover-line"></div>
|
|
||||||
<div class="bottom-right-cover-line"></div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<addNode v-model:childNodeP="nodeConfig.childNode" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="branch-wrap" v-if="nodeConfig.type == 5">
|
|
||||||
<div class="branch-box-wrap">
|
|
||||||
<div class="branch-box">
|
|
||||||
<button class="add-branch" @click="addTerm(nodeConfig.type)">添加分支</button>
|
|
||||||
<div class="col-box" v-for="(item, index) in nodeConfig.conditionNodes" :key="index">
|
|
||||||
<div class="condition-node">
|
|
||||||
<div class="condition-node-box">
|
|
||||||
<div class="title-wrapper" :style="`background: rgb(${bgColors[nodeConfig.type]});`">
|
|
||||||
<input
|
|
||||||
v-if="isInputList[index]"
|
|
||||||
type="text"
|
|
||||||
class="ant-input editable-title-input"
|
|
||||||
@blur="blurEvent(index)"
|
|
||||||
@focus="$event.currentTarget?.select()"
|
|
||||||
v-mountedFocus
|
|
||||||
v-model="item.name"
|
|
||||||
/>
|
|
||||||
<span v-else class="editable-title" @click="clickEvent(index)">{{
|
|
||||||
item.name
|
|
||||||
}}</span>
|
|
||||||
<i class="anticon anticon-close close" @click="delTerm(nodeConfig.type, index)"></i>
|
|
||||||
</div>
|
|
||||||
<div class="auto-judge" :class="isTried && item.error ? 'error active' : ''">
|
|
||||||
<div class="content">并行执行</div>
|
|
||||||
<div class="error_tip" v-if="isTried && item.error">
|
|
||||||
<i class="anticon anticon-exclamation-circle"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<addNode v-model:childNodeP="item.childNode" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<nodeWrap v-if="item.childNode" v-model:nodeConfig="item.childNode" />
|
|
||||||
<template v-if="index == 0">
|
|
||||||
<div class="top-left-cover-line"></div>
|
|
||||||
<div class="bottom-left-cover-line"></div>
|
|
||||||
</template>
|
|
||||||
<template v-if="index === nodeConfig.conditionNodes.length - 1">
|
|
||||||
<div class="top-right-cover-line"></div>
|
|
||||||
<div class="bottom-right-cover-line"></div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<addNode v-model:childNodeP="nodeConfig.childNode" :show-add-button="false" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="branch-wrap" v-if="nodeConfig.type == 7">
|
|
||||||
<div class="branch-box-wrap">
|
|
||||||
<div class="branch-box">
|
|
||||||
<button class="add-branch" @click="addTerm(nodeConfig.type)">添加分支</button>
|
|
||||||
<div class="col-box" v-for="(item, index) in nodeConfig.conditionNodes" :key="index">
|
|
||||||
<div class="condition-node">
|
|
||||||
<div class="condition-node-box">
|
|
||||||
<div class="title-wrapper" :style="`background: rgb(${bgColors[nodeConfig.type]});`">
|
|
||||||
<input
|
|
||||||
v-if="isInputList[index]"
|
|
||||||
type="text"
|
|
||||||
class="ant-input editable-title-input"
|
|
||||||
@blur="blurEvent(index)"
|
|
||||||
@focus="$event.currentTarget?.select()"
|
|
||||||
v-mountedFocus
|
|
||||||
v-model="item.name"
|
|
||||||
/>
|
|
||||||
<span v-else class="editable-title" @click="clickEvent(index)">
|
|
||||||
{{ item.name }}
|
|
||||||
</span>
|
|
||||||
<i
|
|
||||||
class="anticon anticon-close close"
|
|
||||||
@click="delTerm(nodeConfig.type,index)"
|
|
||||||
v-if="index != nodeConfig.conditionNodes?.length - 1"
|
|
||||||
></i>
|
|
||||||
</div>
|
|
||||||
<div class="auto-judge" :class="isTried && item.error ? 'error active' : ''">
|
|
||||||
<div class="content">{{ conditionStr(nodeConfig, index) }}</div>
|
|
||||||
<div class="error_tip" v-if="isTried && item.error">
|
|
||||||
<i class="anticon anticon-exclamation-circle"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<addNode v-model:childNodeP="item.childNode" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<nodeWrap v-if="item.childNode" v-model:nodeConfig="item.childNode" />
|
|
||||||
<template v-if="index == 0">
|
|
||||||
<div class="top-left-cover-line"></div>
|
|
||||||
<div class="bottom-left-cover-line"></div>
|
|
||||||
</template>
|
|
||||||
<template v-if="index == nodeConfig.conditionNodes.length - 1">
|
|
||||||
<div class="top-right-cover-line"></div>
|
|
||||||
<div class="bottom-right-cover-line"></div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<addNode v-model:childNodeP="nodeConfig.childNode" :show-add-button="false" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="node-wrap" v-if="nodeConfig.type === NodeType.PARALLEL_NODE_JOIN || nodeConfig.type === NodeType.INCLUSIVE_NODE_JOIN">
|
|
||||||
<div class="node-wrap-box">
|
|
||||||
<div class="content">
|
|
||||||
<div class="text">聚合</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<addNode v-model:childNodeP="nodeConfig.childNode" />
|
|
||||||
</div>
|
|
||||||
<nodeWrap v-if="nodeConfig.childNode" v-model:nodeConfig="nodeConfig.childNode" />
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import addNode from './addNode.vue'
|
|
||||||
import { onMounted, ref, watch, getCurrentInstance, computed } from 'vue'
|
|
||||||
import {
|
|
||||||
conditionStr,
|
|
||||||
setApproverStr,
|
|
||||||
copyerStr,
|
|
||||||
bgColors,
|
|
||||||
placeholderList,
|
|
||||||
getApproverShowText
|
|
||||||
} from './util'
|
|
||||||
import { WorkFlowNode, NodeType } from './consts'
|
|
||||||
import { useWorkFlowStoreWithOut } from '@/store/modules/bpm/simpleWorkflow'
|
|
||||||
let _uid = getCurrentInstance().uid
|
|
||||||
import { generateUUID } from '@/utils'
|
|
||||||
let props = defineProps({
|
|
||||||
nodeConfig: {
|
|
||||||
type: Object as () => WorkFlowNode,
|
|
||||||
default: () => ({}) as WorkFlowNode
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
let defaultText = computed(() => {
|
|
||||||
return placeholderList[props.nodeConfig.type]
|
|
||||||
})
|
|
||||||
const isInputList = ref<boolean[]>([])
|
|
||||||
const isInput = ref<boolean>(false)
|
|
||||||
const resetConditionNodesErr = () => {
|
|
||||||
for (var i = 0; i < props.nodeConfig.conditionNodes.length; i++) {
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.conditionNodes[i].error =
|
|
||||||
conditionStr(props.nodeConfig, i) == '请设置条件' &&
|
|
||||||
i != props.nodeConfig.conditionNodes.length - 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onMounted(() => {
|
|
||||||
if (props.nodeConfig.type == 1) {
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.error = !setApproverStr(props.nodeConfig)
|
|
||||||
} else if (props.nodeConfig.type == 2) {
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.error = !copyerStr(props.nodeConfig)
|
|
||||||
} else if (props.nodeConfig.type == 4) {
|
|
||||||
resetConditionNodesErr()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
let emits = defineEmits(['update:nodeConfig'])
|
|
||||||
let store = useWorkFlowStoreWithOut()
|
|
||||||
let {
|
|
||||||
setApproverDrawer,
|
|
||||||
setCopyerDrawer,
|
|
||||||
// setCondition,
|
|
||||||
setCopyerConfig,
|
|
||||||
// setConditionsConfig,
|
|
||||||
setUserTaskConfig
|
|
||||||
} = store
|
|
||||||
// ???
|
|
||||||
const isTried = computed(() => store.isTried)
|
|
||||||
// 审批节点的配置
|
|
||||||
const userTaskConfig = computed(() => store.userTaskConfig)
|
|
||||||
// 抄送节点的配置
|
|
||||||
const copyerConfig = computed(() => store.copyerConfig)
|
|
||||||
// let conditionsConfig1 = computed(() => store.conditionsConfig1)
|
|
||||||
const showText = computed(() => {
|
|
||||||
if (props.nodeConfig.type == 0) return '发起人'
|
|
||||||
if (props.nodeConfig.type == 1) {
|
|
||||||
if (props.nodeConfig.attributes) {
|
|
||||||
return getApproverShowText(
|
|
||||||
props.nodeConfig.attributes.approveMethod,
|
|
||||||
props.nodeConfig.attributes.candidateStrategy
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (props.nodeConfig.type === 2) {
|
|
||||||
if (props.nodeConfig.attributes) {
|
|
||||||
return copyerStr(props.nodeConfig.attributes.candidateStrategy)
|
|
||||||
} else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ''
|
|
||||||
})
|
|
||||||
watch(userTaskConfig, (approver) => {
|
|
||||||
if (approver.flag && approver.id === _uid) {
|
|
||||||
emits('update:nodeConfig', approver.value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
watch(copyerConfig, (copyer) => {
|
|
||||||
console.log('copyer', copyer)
|
|
||||||
if (copyer.flag && copyer.id === _uid) {
|
|
||||||
console.log('copyer id is equal', copyer)
|
|
||||||
emits('update:nodeConfig', copyer.value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// watch(conditionsConfig1, (condition) => {
|
|
||||||
// if (condition.flag && condition.id === _uid) {
|
|
||||||
// emits('update:nodeConfig', condition.value)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
const clickEvent = (index) => {
|
|
||||||
if (index >= 0) {
|
|
||||||
isInputList.value[index] = true
|
|
||||||
} else {
|
|
||||||
isInput.value = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const blurEvent = (index) => {
|
|
||||||
if (index >= 0) {
|
|
||||||
isInputList.value[index] = false
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.conditionNodes[index].name =
|
|
||||||
props.nodeConfig.conditionNodes[index].name || '条件'
|
|
||||||
} else {
|
|
||||||
isInput.value = false
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.name = props.nodeConfig.name || defaultText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const delNode = () => {
|
|
||||||
emits('update:nodeConfig', props.nodeConfig.childNode)
|
|
||||||
}
|
|
||||||
const addTerm = (type:number) => {
|
|
||||||
const len = props.nodeConfig.conditionNodes.length
|
|
||||||
let lastIndex = props.nodeConfig.conditionNodes.length - 1
|
|
||||||
let nodeName = '分支' + len
|
|
||||||
if(type === NodeType.PARALLEL_NODE_FORK) {
|
|
||||||
nodeName = '并行' + (len+1);
|
|
||||||
lastIndex = props.nodeConfig.conditionNodes.length;
|
|
||||||
}
|
|
||||||
const conditionData = {
|
|
||||||
id: 'SequenceFlow'+ generateUUID(),
|
|
||||||
name: nodeName,
|
|
||||||
type: NodeType.CONDITION_NODE,
|
|
||||||
childNode: undefined,
|
|
||||||
conditionNodes:[],
|
|
||||||
attributes : undefined
|
|
||||||
};
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.conditionNodes.splice(lastIndex, 0, conditionData)
|
|
||||||
resetConditionNodesErr()
|
|
||||||
emits('update:nodeConfig', props.nodeConfig)
|
|
||||||
}
|
|
||||||
const delTerm = (nodeType: number, index: number) => {
|
|
||||||
if (props.nodeConfig.conditionNodes) {
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.conditionNodes.splice(index, 1)
|
|
||||||
if (nodeType === NodeType.PARALLEL_NODE_FORK) {
|
|
||||||
props.nodeConfig.conditionNodes.map((item, index) => {
|
|
||||||
item.name = `并行${index + 1}`
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
props.nodeConfig.conditionNodes.map((item, index) => {
|
|
||||||
// item.priorityLevel = index + 1
|
|
||||||
if (index !== props.nodeConfig.conditionNodes.length - 1) {
|
|
||||||
item.name = `分支${index + 1}`
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
resetConditionNodesErr()
|
|
||||||
emits('update:nodeConfig', props.nodeConfig)
|
|
||||||
if (props.nodeConfig.conditionNodes.length == 1) {
|
|
||||||
if (nodeType === NodeType.PARALLEL_NODE_FORK || nodeType === NodeType.INCLUSIVE_NODE_FORK) {
|
|
||||||
const joinNode = props.nodeConfig.childNode;
|
|
||||||
if (joinNode?.childNode) {
|
|
||||||
if (props.nodeConfig.conditionNodes[0].childNode) {
|
|
||||||
reData(props.nodeConfig.conditionNodes[0].childNode, joinNode?.childNode)
|
|
||||||
} else {
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.conditionNodes[0].childNode = joinNode?.childNode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emits('update:nodeConfig', props.nodeConfig.conditionNodes[0].childNode)
|
|
||||||
} else {
|
|
||||||
if (props.nodeConfig.childNode) {
|
|
||||||
if (props.nodeConfig.conditionNodes[0].childNode) {
|
|
||||||
reData(props.nodeConfig.conditionNodes[0].childNode, props.nodeConfig.childNode)
|
|
||||||
} else {
|
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.nodeConfig.conditionNodes[0].childNode = props.nodeConfig.childNode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emits('update:nodeConfig', props.nodeConfig.conditionNodes[0].childNode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const reData = (data, addData) => {
|
|
||||||
if (!data.childNode) {
|
|
||||||
data.childNode = addData
|
|
||||||
} else {
|
|
||||||
reData(data.childNode, addData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const setPerson = (priorityLevel) => {
|
|
||||||
console.log('priorityLevel', priorityLevel)
|
|
||||||
const { type } = props.nodeConfig
|
|
||||||
console.log('type', type)
|
|
||||||
if (type == 0) {
|
|
||||||
// setPromoter(true)
|
|
||||||
} else if (type == 1) {
|
|
||||||
setApproverDrawer(true)
|
|
||||||
// if (_uid === userTaskConfig.value.id) {
|
|
||||||
// showText = userTaskConfig.value.showText
|
|
||||||
// }
|
|
||||||
setUserTaskConfig({
|
|
||||||
value: {
|
|
||||||
...JSON.parse(JSON.stringify(props.nodeConfig)),
|
|
||||||
id: 'Activity_' + _uid
|
|
||||||
},
|
|
||||||
flag: false,
|
|
||||||
id: _uid
|
|
||||||
})
|
|
||||||
} else if (type == 2) {
|
|
||||||
setCopyerDrawer(true)
|
|
||||||
setCopyerConfig({
|
|
||||||
value: {
|
|
||||||
...JSON.parse(JSON.stringify(props.nodeConfig)),
|
|
||||||
id: 'Activity_' + _uid
|
|
||||||
},
|
|
||||||
flag: false,
|
|
||||||
id: _uid
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// setCondition(true)
|
|
||||||
// setConditionsConfig({
|
|
||||||
// value: {
|
|
||||||
// ...JSON.parse(JSON.stringify(props.nodeConfig)),
|
|
||||||
// id: 'Gateway_' + _uid
|
|
||||||
// },
|
|
||||||
// priorityLevel,
|
|
||||||
// flag: false,
|
|
||||||
// id: _uid
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// const arrTransfer = (index, type = 1) => {
|
|
||||||
// //向左-1,向右1
|
|
||||||
// // eslint-disable-next-line vue/no-mutating-props
|
|
||||||
// props.nodeConfig.conditionNodes[index] = props.nodeConfig.conditionNodes.splice(
|
|
||||||
// index + type,
|
|
||||||
// 1,
|
|
||||||
// props.nodeConfig.conditionNodes[index]
|
|
||||||
// )[0]
|
|
||||||
// props.nodeConfig.conditionNodes.map((item, index) => {
|
|
||||||
// item.priorityLevel = index + 1
|
|
||||||
// })
|
|
||||||
// resetConditionNodesErr()
|
|
||||||
// emits('update:nodeConfig', props.nodeConfig)
|
|
||||||
// }
|
|
||||||
</script>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.ellipsis-text {
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.start-event-node {
|
|
||||||
color: #191f2566;
|
|
||||||
text-align: left;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.start-event-node-circle {
|
|
||||||
display: flex;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
// margin: auto;
|
|
||||||
// background: #dbdcdc;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #f8f8fa;
|
|
||||||
background-image: linear-gradient(90deg, #ff6a00, #f78b3e), linear-gradient(#ff6a00, #ff6a00);
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.start-event-node-text {
|
|
||||||
margin-top: 5px;
|
|
||||||
font-size: 14px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,218 +0,0 @@
|
||||||
// @ts-ignore
|
|
||||||
import { DictDataVO } from '@/api/system/dict/types'
|
|
||||||
import { DICT_TYPE, getDictLabel } from '@/utils/dict'
|
|
||||||
/**
|
|
||||||
* todo
|
|
||||||
*/
|
|
||||||
export const arrToStr = (arr?: [{ name: string }]) => {
|
|
||||||
if (arr) {
|
|
||||||
return arr
|
|
||||||
.map((item) => {
|
|
||||||
return item.name
|
|
||||||
})
|
|
||||||
.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const setApproverStr = (nodeConfig: any) => {
|
|
||||||
if (nodeConfig.settype == 1) {
|
|
||||||
if (nodeConfig.nodeUserList.length == 1) {
|
|
||||||
return nodeConfig.nodeUserList[0].name
|
|
||||||
} else if (nodeConfig.nodeUserList.length > 1) {
|
|
||||||
if (nodeConfig.examineMode == 1) {
|
|
||||||
return arrToStr(nodeConfig.nodeUserList)
|
|
||||||
} else if (nodeConfig.examineMode == 2) {
|
|
||||||
return nodeConfig.nodeUserList.length + '人会签'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (nodeConfig.settype == 2) {
|
|
||||||
const level =
|
|
||||||
nodeConfig.directorLevel == 1 ? '直接主管' : '第' + nodeConfig.directorLevel + '级主管'
|
|
||||||
if (nodeConfig.examineMode == 1) {
|
|
||||||
return level
|
|
||||||
} else if (nodeConfig.examineMode == 2) {
|
|
||||||
return level + '会签'
|
|
||||||
}
|
|
||||||
} else if (nodeConfig.settype == 4) {
|
|
||||||
if (nodeConfig.selectRange == 1) {
|
|
||||||
return '发起人自选'
|
|
||||||
} else {
|
|
||||||
if (nodeConfig.nodeUserList.length > 0) {
|
|
||||||
if (nodeConfig.selectRange == 2) {
|
|
||||||
return '发起人自选'
|
|
||||||
} else {
|
|
||||||
return '发起人从' + nodeConfig.nodeUserList[0].name + '中自选'
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (nodeConfig.settype == 5) {
|
|
||||||
return '发起人自己'
|
|
||||||
} else if (nodeConfig.settype == 7) {
|
|
||||||
return '从直接主管到通讯录中级别最高的第' + nodeConfig.examineEndDirectorLevel + '个层级主管'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export const approveMethods: DictDataVO [] = [
|
|
||||||
{ label: '单人审批', value: 1 }
|
|
||||||
// { label: '多人审批(所有人审批通过)', value: 2 }
|
|
||||||
// TODO 更多的类型
|
|
||||||
];
|
|
||||||
|
|
||||||
export const getApproverShowText = (approveMethod :number, candidateStrategy: number) => {
|
|
||||||
let appoveMethodText = '单人审批'
|
|
||||||
if(candidateStrategy) {
|
|
||||||
approveMethods.forEach((item) => {
|
|
||||||
if (item.value == approveMethod) {
|
|
||||||
appoveMethodText = item.label
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const strategyText = getDictLabel(
|
|
||||||
DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY,
|
|
||||||
candidateStrategy
|
|
||||||
)
|
|
||||||
return `审批方式:${appoveMethodText} <br/>
|
|
||||||
审批人规则类型:按${strategyText}`
|
|
||||||
} else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const copyerStr = ( candidateStrategy: number) => {
|
|
||||||
// if (nodeConfig.nodeUserList.length != 0) {
|
|
||||||
// return arrToStr(nodeConfig.nodeUserList)
|
|
||||||
// } else {
|
|
||||||
// if (nodeConfig.ccSelfSelectFlag == 1) {
|
|
||||||
// return '发起人自选'
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
console.log('candidateStrategy', candidateStrategy);
|
|
||||||
|
|
||||||
if(candidateStrategy) {
|
|
||||||
const strategyText = getDictLabel(
|
|
||||||
DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY,
|
|
||||||
candidateStrategy
|
|
||||||
)
|
|
||||||
return `抄送人类型:按${strategyText}`
|
|
||||||
} else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export const conditionStr = (nodeConfig, index) => {
|
|
||||||
// const { conditionList, nodeUserList } = nodeConfig.conditionNodes[index]
|
|
||||||
// if (conditionList.length == 0) {
|
|
||||||
// return index == nodeConfig.conditionNodes.length - 1 &&
|
|
||||||
// nodeConfig.conditionNodes[0].conditionList.length != 0
|
|
||||||
// ? '其他条件进入此流程'
|
|
||||||
// : '请设置条件'
|
|
||||||
// return index == nodeConfig.conditionNodes.length - 1 &&
|
|
||||||
// nodeConfig.conditionNodes[0].conditionList.length != 0
|
|
||||||
// ? '其他条件进入此流程'
|
|
||||||
// : '请设置条件'
|
|
||||||
// console.log('index===>', index);
|
|
||||||
// console.log('nodeConfig.conditionNodes.length===>', nodeConfig.conditionNodes.length);
|
|
||||||
if( index === nodeConfig.conditionNodes.length - 1) {
|
|
||||||
return '其它情况将进入该分支'
|
|
||||||
} else {
|
|
||||||
return '请设置条件'
|
|
||||||
}
|
|
||||||
|
|
||||||
// } else {
|
|
||||||
// let str = ''
|
|
||||||
// for (let i = 0; i < conditionList.length; i++) {
|
|
||||||
// const {
|
|
||||||
// columnId,
|
|
||||||
// columnType,
|
|
||||||
// showType,
|
|
||||||
// showName,
|
|
||||||
// optType,
|
|
||||||
// zdy1,
|
|
||||||
// opt1,
|
|
||||||
// zdy2,
|
|
||||||
// opt2,
|
|
||||||
// fixedDownBoxValue
|
|
||||||
// } = conditionList[i]
|
|
||||||
// if (columnId == 0) {
|
|
||||||
// if (nodeUserList.length != 0) {
|
|
||||||
// str += '发起人属于:'
|
|
||||||
// str +=
|
|
||||||
// nodeUserList
|
|
||||||
// .map((item) => {
|
|
||||||
// return item.name
|
|
||||||
// })
|
|
||||||
// .join('或') + ' 并且 '
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (columnType == 'String' && showType == '3') {
|
|
||||||
// if (zdy1) {
|
|
||||||
// str += showName + '属于:' + dealStr(zdy1, JSON.parse(fixedDownBoxValue)) + ' 并且 '
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (columnType == 'Double') {
|
|
||||||
// if (optType != 6 && zdy1) {
|
|
||||||
// const optTypeStr = ['', '<', '>', '≤', '=', '≥'][optType]
|
|
||||||
// str += `${showName} ${optTypeStr} ${zdy1} 并且 `
|
|
||||||
// } else if (optType == 6 && zdy1 && zdy2) {
|
|
||||||
// str += `${zdy1} ${opt1} ${showName} ${opt2} ${zdy2} 并且 `
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// str ? str.substring(0, str.length - 4) :
|
|
||||||
return '请设置条件'
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// export const dealStr = (str: string, obj) => {
|
|
||||||
// const arr = []
|
|
||||||
// const list = str.split(',')
|
|
||||||
// for (const elem in obj) {
|
|
||||||
// list.map((item) => {
|
|
||||||
// if (item == elem) {
|
|
||||||
// arr.push(obj[elem].value)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// return arr.join('或')
|
|
||||||
// }
|
|
||||||
|
|
||||||
export const removeEle = (arr, elem, key = 'id') => {
|
|
||||||
let includesIndex
|
|
||||||
arr.map((item, index) => {
|
|
||||||
if (item[key] == elem[key]) {
|
|
||||||
includesIndex = index
|
|
||||||
}
|
|
||||||
})
|
|
||||||
arr.splice(includesIndex, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const bgColors = ['87, 106, 149', '255, 148, 62', '50, 150, 250','50, 150, 250','248, 107, 248','244, 118, 118','23, 148, 46','23, 148, 46']
|
|
||||||
export const placeholderList = ['发起人', '审核人', '抄送人']
|
|
||||||
export const setTypes = [
|
|
||||||
{ value: 1, label: '指定成员' },
|
|
||||||
{ value: 2, label: '主管' },
|
|
||||||
{ value: 4, label: '发起人自选' },
|
|
||||||
{ value: 5, label: '发起人自己' },
|
|
||||||
{ value: 7, label: '连续多级主管' }
|
|
||||||
]
|
|
||||||
|
|
||||||
export const selectModes = [
|
|
||||||
{ value: 1, label: '选一个人' },
|
|
||||||
{ value: 2, label: '选多个人' }
|
|
||||||
]
|
|
||||||
|
|
||||||
export const selectRanges = [
|
|
||||||
{ value: 1, label: '全公司' },
|
|
||||||
{ value: 2, label: '指定成员' },
|
|
||||||
{ value: 3, label: '指定角色' }
|
|
||||||
]
|
|
||||||
|
|
||||||
export const optTypes = [
|
|
||||||
{ value: '1', label: '小于' },
|
|
||||||
{ value: '2', label: '大于' },
|
|
||||||
{ value: '3', label: '小于等于' },
|
|
||||||
{ value: '4', label: '等于' },
|
|
||||||
{ value: '5', label: '大于等于' },
|
|
||||||
{ value: '6', label: '介于两个数之间' }
|
|
||||||
]
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -146,9 +146,9 @@ onMounted(async () => {
|
||||||
processNodeTree.value = {
|
processNodeTree.value = {
|
||||||
name: '开始',
|
name: '开始',
|
||||||
type: NodeType.START_EVENT_NODE,
|
type: NodeType.START_EVENT_NODE,
|
||||||
id: 'StartEvent_1', // TODO @jason:这个我们要不要 StartEvent 哈?
|
id: 'StartEvent',
|
||||||
childNode: {
|
childNode: {
|
||||||
id: 'EndEvent_1',
|
id: 'EndEvent',
|
||||||
name: '结束',
|
name: '结束',
|
||||||
type: NodeType.END_EVENT_NODE
|
type: NodeType.END_EVENT_NODE
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { DictDataVO } from '@/api/system/dict/types'
|
import { DictDataVO } from '@/api/system/dict/types'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 节点类型
|
* 节点类型
|
||||||
*/
|
*/
|
||||||
|
@ -85,13 +86,17 @@ export enum CandidateStrategy {
|
||||||
*/
|
*/
|
||||||
ROLE = 10,
|
ROLE = 10,
|
||||||
/**
|
/**
|
||||||
* 指定部门成员
|
* 部门成员
|
||||||
*/
|
*/
|
||||||
DEPT_MEMBER = 20,
|
DEPT_MEMBER = 20,
|
||||||
/**
|
/**
|
||||||
* 部门的负责人
|
* 部门的负责人
|
||||||
*/
|
*/
|
||||||
DEPT_LEADER = 21,
|
DEPT_LEADER = 21,
|
||||||
|
/**
|
||||||
|
* 连续多级部门的负责人
|
||||||
|
*/
|
||||||
|
MULTI_LEVEL_DEPT_LEADER = 23,
|
||||||
/**
|
/**
|
||||||
* 指定岗位
|
* 指定岗位
|
||||||
*/
|
*/
|
||||||
|
@ -108,6 +113,14 @@ export enum CandidateStrategy {
|
||||||
* 发起人自己
|
* 发起人自己
|
||||||
*/
|
*/
|
||||||
START_USER = 36,
|
START_USER = 36,
|
||||||
|
/**
|
||||||
|
* 发起人部门负责人
|
||||||
|
*/
|
||||||
|
START_USER_DEPT_LEADER = 37,
|
||||||
|
/**
|
||||||
|
* 发起人连续多级部门的负责人
|
||||||
|
*/
|
||||||
|
START_USER_MULTI_LEVEL_DEPT_LEADER = 38,
|
||||||
/**
|
/**
|
||||||
* 指定用户组
|
* 指定用户组
|
||||||
*/
|
*/
|
||||||
|
@ -280,6 +293,21 @@ NODE_DEFAULT_NAME.set(NodeType.USER_TASK_NODE, '审批人')
|
||||||
NODE_DEFAULT_NAME.set(NodeType.COPY_TASK_NODE, '抄送人')
|
NODE_DEFAULT_NAME.set(NodeType.COPY_TASK_NODE, '抄送人')
|
||||||
NODE_DEFAULT_NAME.set(NodeType.CONDITION_NODE, '条件')
|
NODE_DEFAULT_NAME.set(NodeType.CONDITION_NODE, '条件')
|
||||||
|
|
||||||
|
// 候选人策略。暂时不从字典中取。 后续可能调整。控制显示顺序
|
||||||
|
export const CANDIDATE_STRATEGY: DictDataVO[] = [
|
||||||
|
{ label: '指定成员', value: CandidateStrategy.USER },
|
||||||
|
{ label: '指定角色', value: CandidateStrategy.ROLE },
|
||||||
|
{ label: '部门成员', value: CandidateStrategy.DEPT_MEMBER },
|
||||||
|
{ label: '部门负责人', value: CandidateStrategy.DEPT_LEADER },
|
||||||
|
{ label: '连续多级部门负责人', value: CandidateStrategy.MULTI_LEVEL_DEPT_LEADER },
|
||||||
|
{ label: '发起人自选', value: CandidateStrategy.START_USER_SELECT },
|
||||||
|
{ label: '发起人本人', value: CandidateStrategy.START_USER },
|
||||||
|
{ label: '发起人部门负责人', value: CandidateStrategy.START_USER_DEPT_LEADER },
|
||||||
|
{ label: '发起人连续部门负责人', value: CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER },
|
||||||
|
{ label: '用户组', value: CandidateStrategy.USER_GROUP },
|
||||||
|
{ label: '流程表达式', value: CandidateStrategy.EXPRESSION }
|
||||||
|
]
|
||||||
|
|
||||||
export const APPROVE_METHODS: DictDataVO[] = [
|
export const APPROVE_METHODS: DictDataVO[] = [
|
||||||
{ label: '随机挑选一人审批', value: ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE },
|
{ label: '随机挑选一人审批', value: ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE },
|
||||||
{ label: '多人会签(按通过比例%)', value: ApproveMethodType.APPROVE_BY_RATIO },
|
{ label: '多人会签(按通过比例%)', value: ApproveMethodType.APPROVE_BY_RATIO },
|
||||||
|
@ -355,3 +383,21 @@ export const DEFAULT_BUTTON_SETTING: ButtonSetting[] = [
|
||||||
{ id: OpsButtonType.ADD_SIGN, displayName: '加签', enable: false },
|
{ id: OpsButtonType.ADD_SIGN, displayName: '加签', enable: false },
|
||||||
{ id: OpsButtonType.RETURN, displayName: '回退', enable: false }
|
{ id: OpsButtonType.RETURN, displayName: '回退', enable: false }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
export const MULTI_LEVEL_DEPT: DictDataVO = [
|
||||||
|
{ label: '第1级部门', value: 1 },
|
||||||
|
{ label: '第2级部门', value: 2 },
|
||||||
|
{ label: '第3级部门', value: 3 },
|
||||||
|
{ label: '第4级部门', value: 4 },
|
||||||
|
{ label: '第5级部门', value: 5 },
|
||||||
|
{ label: '第6级部门', value: 6 },
|
||||||
|
{ label: '第7级部门', value: 7 },
|
||||||
|
{ label: '第8级部门', value: 8 },
|
||||||
|
{ label: '第9级部门', value: 9 },
|
||||||
|
{ label: '第10级部门', value: 10 },
|
||||||
|
{ label: '第11级部门', value: 11 },
|
||||||
|
{ label: '第12级部门', value: 12 },
|
||||||
|
{ label: '第13级部门', value: 13 },
|
||||||
|
{ label: '第14级部门', value: 14 },
|
||||||
|
{ label: '第15级部门', value: 15 }
|
||||||
|
]
|
||||||
|
|
|
@ -89,9 +89,16 @@ export function useFormFieldsPermission() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type UserTaskFormType = {
|
export type UserTaskFormType = {
|
||||||
candidateParamArray: any[]
|
//candidateParamArray: any[]
|
||||||
candidateStrategy: CandidateStrategy
|
candidateStrategy: CandidateStrategy
|
||||||
approveMethod: ApproveMethodType
|
approveMethod: ApproveMethodType
|
||||||
|
roleIds?: number[] // 角色
|
||||||
|
deptIds?: number[] // 部门
|
||||||
|
deptLevel?: number // 部门层级
|
||||||
|
userIds?: number[] // 用户
|
||||||
|
userGroups?: number[] // 用户组
|
||||||
|
postIds?: number[] // 岗位
|
||||||
|
expression?: string // 流程表达式
|
||||||
approveRatio?: number
|
approveRatio?: number
|
||||||
rejectHandlerType?: RejectHandlerType
|
rejectHandlerType?: RejectHandlerType
|
||||||
returnNodeId?: string
|
returnNodeId?: string
|
||||||
|
@ -103,8 +110,15 @@ export type UserTaskFormType = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CopyTaskFormType = {
|
export type CopyTaskFormType = {
|
||||||
candidateParamArray: any[]
|
// candidateParamArray: any[]
|
||||||
candidateStrategy: CandidateStrategy
|
candidateStrategy: CandidateStrategy
|
||||||
|
roleIds?: number[] // 角色
|
||||||
|
deptIds?: number[] // 部门
|
||||||
|
deptLevel?: number // 部门层级
|
||||||
|
userIds?: number[] // 用户
|
||||||
|
userGroups?: number[] // 用户组
|
||||||
|
postIds?: number[] // 岗位
|
||||||
|
expression?: string // 流程表达式
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -120,7 +134,7 @@ export function useNodeForm(nodeType: NodeType) {
|
||||||
const configForm = ref<UserTaskFormType | CopyTaskFormType>()
|
const configForm = ref<UserTaskFormType | CopyTaskFormType>()
|
||||||
if (nodeType === NodeType.USER_TASK_NODE) {
|
if (nodeType === NodeType.USER_TASK_NODE) {
|
||||||
configForm.value = {
|
configForm.value = {
|
||||||
candidateParamArray: [],
|
//candidateParamArray: [],
|
||||||
candidateStrategy: CandidateStrategy.USER,
|
candidateStrategy: CandidateStrategy.USER,
|
||||||
approveMethod: ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE,
|
approveMethod: ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE,
|
||||||
approveRatio: 100,
|
approveRatio: 100,
|
||||||
|
@ -134,7 +148,7 @@ export function useNodeForm(nodeType: NodeType) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
configForm.value = {
|
configForm.value = {
|
||||||
candidateParamArray: [],
|
//candidateParamArray: [],
|
||||||
candidateStrategy: CandidateStrategy.USER
|
candidateStrategy: CandidateStrategy.USER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,10 +157,10 @@ export function useNodeForm(nodeType: NodeType) {
|
||||||
let showText = ''
|
let showText = ''
|
||||||
// 指定成员
|
// 指定成员
|
||||||
if (configForm.value?.candidateStrategy === CandidateStrategy.USER) {
|
if (configForm.value?.candidateStrategy === CandidateStrategy.USER) {
|
||||||
if (configForm.value.candidateParamArray?.length > 0) {
|
if (configForm.value?.userIds!.length > 0) {
|
||||||
const candidateNames: string[] = []
|
const candidateNames: string[] = []
|
||||||
userOptions?.value.forEach((item) => {
|
userOptions?.value.forEach((item) => {
|
||||||
if (configForm.value?.candidateParamArray.includes(item.id)) {
|
if (configForm.value?.userIds!.includes(item.id)) {
|
||||||
candidateNames.push(item.nickname)
|
candidateNames.push(item.nickname)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -155,10 +169,10 @@ export function useNodeForm(nodeType: NodeType) {
|
||||||
}
|
}
|
||||||
// 指定角色
|
// 指定角色
|
||||||
if (configForm.value?.candidateStrategy === CandidateStrategy.ROLE) {
|
if (configForm.value?.candidateStrategy === CandidateStrategy.ROLE) {
|
||||||
if (configForm.value.candidateParamArray?.length > 0) {
|
if (configForm.value.roleIds!.length > 0) {
|
||||||
const candidateNames: string[] = []
|
const candidateNames: string[] = []
|
||||||
roleOptions?.value.forEach((item) => {
|
roleOptions?.value.forEach((item) => {
|
||||||
if (configForm.value?.candidateParamArray.includes(item.id)) {
|
if (configForm.value?.roleIds!.includes(item.id)) {
|
||||||
candidateNames.push(item.name)
|
candidateNames.push(item.name)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -168,29 +182,32 @@ export function useNodeForm(nodeType: NodeType) {
|
||||||
// 指定部门
|
// 指定部门
|
||||||
if (
|
if (
|
||||||
configForm.value?.candidateStrategy === CandidateStrategy.DEPT_MEMBER ||
|
configForm.value?.candidateStrategy === CandidateStrategy.DEPT_MEMBER ||
|
||||||
configForm.value?.candidateStrategy === CandidateStrategy.DEPT_LEADER
|
configForm.value?.candidateStrategy === CandidateStrategy.DEPT_LEADER ||
|
||||||
|
configForm.value?.candidateStrategy === CandidateStrategy.MULTI_LEVEL_DEPT_LEADER
|
||||||
) {
|
) {
|
||||||
if (configForm.value?.candidateParamArray?.length > 0) {
|
if (configForm.value?.deptIds!.length > 0) {
|
||||||
const candidateNames: string[] = []
|
const candidateNames: string[] = []
|
||||||
deptOptions?.value.forEach((item) => {
|
deptOptions?.value.forEach((item) => {
|
||||||
if (configForm.value?.candidateParamArray.includes(item.id)) {
|
if (configForm.value?.deptIds!.includes(item.id!)) {
|
||||||
candidateNames.push(item.name)
|
candidateNames.push(item.name)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (configForm.value.candidateStrategy === CandidateStrategy.DEPT_MEMBER) {
|
if (configForm.value.candidateStrategy === CandidateStrategy.DEPT_MEMBER) {
|
||||||
showText = `部门成员:${candidateNames.join(',')}`
|
showText = `部门成员:${candidateNames.join(',')}`
|
||||||
} else {
|
} else if (configForm.value.candidateStrategy === CandidateStrategy.DEPT_LEADER) {
|
||||||
showText = `部门的负责人:${candidateNames.join(',')}`
|
showText = `部门的负责人:${candidateNames.join(',')}`
|
||||||
|
} else {
|
||||||
|
showText = `多级部门的负责人:${candidateNames.join(',')}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 指定岗位
|
// 指定岗位
|
||||||
if (configForm.value?.candidateStrategy === CandidateStrategy.POST) {
|
if (configForm.value?.candidateStrategy === CandidateStrategy.POST) {
|
||||||
if (configForm.value.candidateParamArray?.length > 0) {
|
if (configForm.value.postIds!.length > 0) {
|
||||||
const candidateNames: string[] = []
|
const candidateNames: string[] = []
|
||||||
postOptions?.value.forEach((item) => {
|
postOptions?.value.forEach((item) => {
|
||||||
if (configForm.value?.candidateParamArray.includes(item.id)) {
|
if (configForm.value?.postIds!.includes(item.id!)) {
|
||||||
candidateNames.push(item.name)
|
candidateNames.push(item.name)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -199,10 +216,10 @@ export function useNodeForm(nodeType: NodeType) {
|
||||||
}
|
}
|
||||||
// 指定用户组
|
// 指定用户组
|
||||||
if (configForm.value?.candidateStrategy === CandidateStrategy.USER_GROUP) {
|
if (configForm.value?.candidateStrategy === CandidateStrategy.USER_GROUP) {
|
||||||
if (configForm.value?.candidateParamArray?.length > 0) {
|
if (configForm.value?.userGroups!.length > 0) {
|
||||||
const candidateNames: string[] = []
|
const candidateNames: string[] = []
|
||||||
userGroupOptions?.value.forEach((item) => {
|
userGroupOptions?.value.forEach((item) => {
|
||||||
if (configForm.value?.candidateParamArray.includes(item.id)) {
|
if (configForm.value?.userGroups!.includes(item.id)) {
|
||||||
candidateNames.push(item.name)
|
candidateNames.push(item.name)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -218,16 +235,116 @@ export function useNodeForm(nodeType: NodeType) {
|
||||||
if (configForm.value?.candidateStrategy === CandidateStrategy.START_USER) {
|
if (configForm.value?.candidateStrategy === CandidateStrategy.START_USER) {
|
||||||
showText = `发起人自己`
|
showText = `发起人自己`
|
||||||
}
|
}
|
||||||
|
// 发起人的部门负责人
|
||||||
|
if (configForm.value?.candidateStrategy === CandidateStrategy.START_USER_DEPT_LEADER) {
|
||||||
|
showText = `发起人的部门负责人`
|
||||||
|
}
|
||||||
|
// 发起人的部门负责人
|
||||||
|
if (
|
||||||
|
configForm.value?.candidateStrategy === CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER
|
||||||
|
) {
|
||||||
|
showText = `发起人连续部门负责人`
|
||||||
|
}
|
||||||
// 流程表达式
|
// 流程表达式
|
||||||
if (configForm.value?.candidateStrategy === CandidateStrategy.EXPRESSION) {
|
if (configForm.value?.candidateStrategy === CandidateStrategy.EXPRESSION) {
|
||||||
if (configForm.value.candidateParamArray?.length > 0) {
|
showText = `流程表达式:${configForm.value.expression}`
|
||||||
showText = `流程表达式:${configForm.value.candidateParamArray[0]}`
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return showText
|
return showText
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理候选人参数的赋值
|
||||||
|
*/
|
||||||
|
const handleCandidateParam = () => {
|
||||||
|
let candidateParam: undefined | string = undefined
|
||||||
|
if (!configForm.value) {
|
||||||
|
return candidateParam
|
||||||
|
}
|
||||||
|
switch (configForm.value.candidateStrategy) {
|
||||||
|
case CandidateStrategy.USER:
|
||||||
|
candidateParam = configForm.value.userIds!.join(',')
|
||||||
|
break
|
||||||
|
case CandidateStrategy.ROLE:
|
||||||
|
candidateParam = configForm.value.roleIds!.join(',')
|
||||||
|
break
|
||||||
|
case CandidateStrategy.POST:
|
||||||
|
candidateParam = configForm.value.postIds!.join(',')
|
||||||
|
break
|
||||||
|
case CandidateStrategy.USER_GROUP:
|
||||||
|
candidateParam = configForm.value.userGroups!.join(',')
|
||||||
|
break
|
||||||
|
case CandidateStrategy.EXPRESSION:
|
||||||
|
candidateParam = configForm.value.expression!
|
||||||
|
break
|
||||||
|
case CandidateStrategy.DEPT_MEMBER:
|
||||||
|
case CandidateStrategy.DEPT_LEADER:
|
||||||
|
candidateParam = configForm.value.deptIds!.join(',')
|
||||||
|
break
|
||||||
|
// 发起人部门负责人
|
||||||
|
case CandidateStrategy.START_USER_DEPT_LEADER:
|
||||||
|
case CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER:
|
||||||
|
candidateParam = configForm.value.deptLevel + ''
|
||||||
|
break
|
||||||
|
// 指定连续多级部门的负责人
|
||||||
|
case CandidateStrategy.MULTI_LEVEL_DEPT_LEADER: {
|
||||||
|
// TODO 是否允许选多个部门
|
||||||
|
const deptIds = configForm.value.deptIds!.join(',')
|
||||||
|
candidateParam = deptIds.concat(',' + configForm.value.deptLevel + '')
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return candidateParam
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 解析候选人参数
|
||||||
|
*/
|
||||||
|
const parseCandidateParam = (
|
||||||
|
candidateStrategy: CandidateStrategy,
|
||||||
|
candidateParam: string | undefined
|
||||||
|
) => {
|
||||||
|
if (!configForm.value || !candidateParam) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch (candidateStrategy) {
|
||||||
|
case CandidateStrategy.USER: {
|
||||||
|
configForm.value.userIds = candidateParam.split(',').map((item) => +item)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case CandidateStrategy.ROLE:
|
||||||
|
configForm.value.roleIds = candidateParam.split(',').map((item) => +item)
|
||||||
|
break
|
||||||
|
case CandidateStrategy.POST:
|
||||||
|
configForm.value.postIds = candidateParam.split(',').map((item) => +item)
|
||||||
|
break
|
||||||
|
case CandidateStrategy.USER_GROUP:
|
||||||
|
configForm.value.userGroups = candidateParam.split(',').map((item) => +item)
|
||||||
|
break
|
||||||
|
case CandidateStrategy.EXPRESSION:
|
||||||
|
configForm.value.expression = candidateParam
|
||||||
|
break
|
||||||
|
case CandidateStrategy.DEPT_MEMBER:
|
||||||
|
case CandidateStrategy.DEPT_LEADER:
|
||||||
|
configForm.value.deptIds = candidateParam.split(',').map((item) => +item)
|
||||||
|
break
|
||||||
|
// 发起人部门负责人
|
||||||
|
case CandidateStrategy.START_USER_DEPT_LEADER:
|
||||||
|
case CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER:
|
||||||
|
configForm.value.deptLevel = +candidateParam
|
||||||
|
break
|
||||||
|
// 指定连续多级部门的负责人
|
||||||
|
case CandidateStrategy.MULTI_LEVEL_DEPT_LEADER: {
|
||||||
|
// 暂时只能选一个部门
|
||||||
|
const paramArray = candidateParam.split(',')
|
||||||
|
configForm.value.deptIds = [+paramArray[0]]
|
||||||
|
configForm.value.deptLevel = +paramArray[1]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
configForm,
|
configForm,
|
||||||
roleOptions,
|
roleOptions,
|
||||||
|
@ -235,6 +352,8 @@ export function useNodeForm(nodeType: NodeType) {
|
||||||
userOptions,
|
userOptions,
|
||||||
userGroupOptions,
|
userGroupOptions,
|
||||||
deptTreeOptions,
|
deptTreeOptions,
|
||||||
|
handleCandidateParam,
|
||||||
|
parseCandidateParam,
|
||||||
getShowText
|
getShowText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,14 +46,9 @@
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="configForm.candidateStrategy == CandidateStrategy.ROLE"
|
v-if="configForm.candidateStrategy == CandidateStrategy.ROLE"
|
||||||
label="指定角色"
|
label="指定角色"
|
||||||
prop="candidateParamArray"
|
prop="roleIds"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select v-model="configForm.roleIds" clearable multiple style="width: 100%">
|
||||||
v-model="configForm.candidateParamArray"
|
|
||||||
clearable
|
|
||||||
multiple
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in roleOptions"
|
v-for="item in roleOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
@ -68,12 +63,12 @@
|
||||||
configForm.candidateStrategy == CandidateStrategy.DEPT_LEADER
|
configForm.candidateStrategy == CandidateStrategy.DEPT_LEADER
|
||||||
"
|
"
|
||||||
label="指定部门"
|
label="指定部门"
|
||||||
prop="candidateParamArray"
|
prop="deptIds"
|
||||||
span="24"
|
span="24"
|
||||||
>
|
>
|
||||||
<el-tree-select
|
<el-tree-select
|
||||||
ref="treeRef"
|
ref="treeRef"
|
||||||
v-model="configForm.candidateParamArray"
|
v-model="configForm.deptIds"
|
||||||
:data="deptTreeOptions"
|
:data="deptTreeOptions"
|
||||||
:props="defaultProps"
|
:props="defaultProps"
|
||||||
empty-text="加载中,请稍后"
|
empty-text="加载中,请稍后"
|
||||||
|
@ -86,15 +81,10 @@
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="configForm.candidateStrategy == CandidateStrategy.POST"
|
v-if="configForm.candidateStrategy == CandidateStrategy.POST"
|
||||||
label="指定岗位"
|
label="指定岗位"
|
||||||
prop="candidateParamArray"
|
prop="postIds"
|
||||||
span="24"
|
span="24"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select v-model="configForm.postIds" clearable multiple style="width: 100%">
|
||||||
v-model="configForm.candidateParamArray"
|
|
||||||
clearable
|
|
||||||
multiple
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in postOptions"
|
v-for="item in postOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
@ -106,15 +96,10 @@
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="configForm.candidateStrategy == CandidateStrategy.USER"
|
v-if="configForm.candidateStrategy == CandidateStrategy.USER"
|
||||||
label="指定用户"
|
label="指定用户"
|
||||||
prop="candidateParamArray"
|
prop="userIds"
|
||||||
span="24"
|
span="24"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select v-model="configForm.userIds" clearable multiple style="width: 100%">
|
||||||
v-model="configForm.candidateParamArray"
|
|
||||||
clearable
|
|
||||||
multiple
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in userOptions"
|
v-for="item in userOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
@ -126,14 +111,9 @@
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="configForm.candidateStrategy === CandidateStrategy.USER_GROUP"
|
v-if="configForm.candidateStrategy === CandidateStrategy.USER_GROUP"
|
||||||
label="指定用户组"
|
label="指定用户组"
|
||||||
prop="candidateParamArray"
|
prop="userGroups"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select v-model="configForm.userGroups" clearable multiple style="width: 100%">
|
||||||
v-model="configForm.candidateParamArray"
|
|
||||||
clearable
|
|
||||||
multiple
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in userGroupOptions"
|
v-for="item in userGroupOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
@ -146,11 +126,11 @@
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="configForm.candidateStrategy === CandidateStrategy.EXPRESSION"
|
v-if="configForm.candidateStrategy === CandidateStrategy.EXPRESSION"
|
||||||
label="流程表达式"
|
label="流程表达式"
|
||||||
prop="candidateParamArray"
|
prop="expression"
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
type="textarea"
|
type="textarea"
|
||||||
v-model="configForm.candidateParamArray[0]"
|
v-model="configForm.expression"
|
||||||
clearable
|
clearable
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
/>
|
/>
|
||||||
|
@ -200,7 +180,7 @@
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { SimpleFlowNode, CandidateStrategy, NodeType } from '../consts'
|
import { SimpleFlowNode, CandidateStrategy, NodeType, CANDIDATE_STRATEGY } from '../consts'
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
import {
|
import {
|
||||||
useWatchNode,
|
useWatchNode,
|
||||||
|
@ -235,7 +215,12 @@ const formRef = ref() // 表单 Ref
|
||||||
// 表单校验规则
|
// 表单校验规则
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
candidateStrategy: [{ required: true, message: '抄送人设置不能为空', trigger: 'change' }],
|
candidateStrategy: [{ required: true, message: '抄送人设置不能为空', trigger: 'change' }],
|
||||||
candidateParamArray: [{ required: true, message: '选项不能为空', trigger: 'blur' }]
|
userIds: [{ required: true, message: '用户不能为空', trigger: 'change' }],
|
||||||
|
roleIds: [{ required: true, message: '角色不能为空', trigger: 'change' }],
|
||||||
|
deptIds: [{ required: true, message: '部门不能为空', trigger: 'change' }],
|
||||||
|
userGroups: [{ required: true, message: '用户组不能为空', trigger: 'change' }],
|
||||||
|
postIds: [{ required: true, message: '岗位不能为空', trigger: 'change' }],
|
||||||
|
expression: [{ required: true, message: '流程表达式不能为空', trigger: 'blur' }]
|
||||||
})
|
})
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -245,12 +230,14 @@ const {
|
||||||
userOptions,
|
userOptions,
|
||||||
userGroupOptions,
|
userGroupOptions,
|
||||||
deptTreeOptions,
|
deptTreeOptions,
|
||||||
getShowText
|
getShowText,
|
||||||
|
handleCandidateParam,
|
||||||
|
parseCandidateParam
|
||||||
} = useNodeForm(NodeType.COPY_TASK_NODE)
|
} = useNodeForm(NodeType.COPY_TASK_NODE)
|
||||||
const configForm = tempConfigForm as Ref<CopyTaskFormType>
|
const configForm = tempConfigForm as Ref<CopyTaskFormType>
|
||||||
// 抄送人策略, 去掉发起人自选 和 发起人自己
|
// 抄送人策略, 去掉发起人自选 和 发起人自己
|
||||||
const copyUserStrategies = computed(() => {
|
const copyUserStrategies = computed(() => {
|
||||||
return getIntDictOptions(DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY).filter(
|
return CANDIDATE_STRATEGY.filter(
|
||||||
(item) =>
|
(item) =>
|
||||||
item.value !== CandidateStrategy.START_USER_SELECT &&
|
item.value !== CandidateStrategy.START_USER_SELECT &&
|
||||||
item.value !== CandidateStrategy.START_USER
|
item.value !== CandidateStrategy.START_USER
|
||||||
|
@ -258,7 +245,12 @@ const copyUserStrategies = computed(() => {
|
||||||
})
|
})
|
||||||
// 改变抄送人设置策略
|
// 改变抄送人设置策略
|
||||||
const changeCandidateStrategy = () => {
|
const changeCandidateStrategy = () => {
|
||||||
configForm.value.candidateParamArray = []
|
configForm.value.userIds = []
|
||||||
|
configForm.value.deptIds = []
|
||||||
|
configForm.value.roleIds = []
|
||||||
|
configForm.value.postIds = []
|
||||||
|
configForm.value.userGroups = []
|
||||||
|
configForm.value.deptLevel = 1
|
||||||
}
|
}
|
||||||
// 保存配置
|
// 保存配置
|
||||||
const saveConfig = async () => {
|
const saveConfig = async () => {
|
||||||
|
@ -269,7 +261,7 @@ const saveConfig = async () => {
|
||||||
const showText = getShowText()
|
const showText = getShowText()
|
||||||
if (!showText) return false
|
if (!showText) return false
|
||||||
currentNode.value.name = nodeName.value!
|
currentNode.value.name = nodeName.value!
|
||||||
currentNode.value.candidateParam = configForm.value.candidateParamArray?.join(',')
|
handleCandidateParam()
|
||||||
currentNode.value.candidateStrategy = configForm.value.candidateStrategy
|
currentNode.value.candidateStrategy = configForm.value.candidateStrategy
|
||||||
currentNode.value.showText = showText
|
currentNode.value.showText = showText
|
||||||
currentNode.value.fieldsPermission = fieldsPermissionConfig.value
|
currentNode.value.fieldsPermission = fieldsPermissionConfig.value
|
||||||
|
@ -281,14 +273,7 @@ const showCopyTaskNodeConfig = (node: SimpleFlowNode) => {
|
||||||
nodeName.value = node.name
|
nodeName.value = node.name
|
||||||
// 抄送人设置
|
// 抄送人设置
|
||||||
configForm.value.candidateStrategy = node.candidateStrategy!
|
configForm.value.candidateStrategy = node.candidateStrategy!
|
||||||
const strCandidateParam = node?.candidateParam
|
parseCandidateParam(node.candidateStrategy!, node?.candidateParam)
|
||||||
if (node.candidateStrategy === CandidateStrategy.EXPRESSION) {
|
|
||||||
configForm.value.candidateParamArray[0] = strCandidateParam
|
|
||||||
} else {
|
|
||||||
if (strCandidateParam) {
|
|
||||||
configForm.value.candidateParamArray = strCandidateParam.split(',').map((item) => +item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 表单字段权限
|
// 表单字段权限
|
||||||
getNodeConfigFormFields(node.fieldsPermission)
|
getNodeConfigFormFields(node.fieldsPermission)
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
@change="changeCandidateStrategy"
|
@change="changeCandidateStrategy"
|
||||||
>
|
>
|
||||||
<el-radio
|
<el-radio
|
||||||
v-for="(dict, index) in getIntDictOptions(DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY)"
|
v-for="(dict, index) in CANDIDATE_STRATEGY"
|
||||||
:key="index"
|
:key="index"
|
||||||
:value="dict.value"
|
:value="dict.value"
|
||||||
:label="dict.value"
|
:label="dict.value"
|
||||||
|
@ -47,14 +47,9 @@
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="configForm.candidateStrategy == CandidateStrategy.ROLE"
|
v-if="configForm.candidateStrategy == CandidateStrategy.ROLE"
|
||||||
label="指定角色"
|
label="指定角色"
|
||||||
prop="candidateParamArray"
|
prop="roleIds"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select v-model="configForm.roleIds" clearable multiple style="width: 100%">
|
||||||
v-model="configForm.candidateParamArray"
|
|
||||||
clearable
|
|
||||||
multiple
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in roleOptions"
|
v-for="item in roleOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
@ -66,15 +61,16 @@
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="
|
v-if="
|
||||||
configForm.candidateStrategy == CandidateStrategy.DEPT_MEMBER ||
|
configForm.candidateStrategy == CandidateStrategy.DEPT_MEMBER ||
|
||||||
configForm.candidateStrategy == CandidateStrategy.DEPT_LEADER
|
configForm.candidateStrategy == CandidateStrategy.DEPT_LEADER ||
|
||||||
|
configForm.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER
|
||||||
"
|
"
|
||||||
label="指定部门"
|
label="指定部门"
|
||||||
prop="candidateParamArray"
|
prop="deptIds"
|
||||||
span="24"
|
span="24"
|
||||||
>
|
>
|
||||||
<el-tree-select
|
<el-tree-select
|
||||||
ref="treeRef"
|
ref="treeRef"
|
||||||
v-model="configForm.candidateParamArray"
|
v-model="configForm.deptIds"
|
||||||
:data="deptTreeOptions"
|
:data="deptTreeOptions"
|
||||||
:props="defaultProps"
|
:props="defaultProps"
|
||||||
empty-text="加载中,请稍后"
|
empty-text="加载中,请稍后"
|
||||||
|
@ -85,17 +81,31 @@
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="configForm.candidateStrategy == CandidateStrategy.POST"
|
v-if="
|
||||||
label="指定岗位"
|
configForm.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER ||
|
||||||
prop="candidateParamArray"
|
configForm.candidateStrategy == CandidateStrategy.START_USER_DEPT_LEADER ||
|
||||||
|
configForm.candidateStrategy == CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER
|
||||||
|
"
|
||||||
|
:label="deptLevelLabel!"
|
||||||
|
prop="deptLevel"
|
||||||
span="24"
|
span="24"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select v-model="configForm.deptLevel" clearable>
|
||||||
v-model="configForm.candidateParamArray"
|
<el-option
|
||||||
clearable
|
v-for="(item, index) in MULTI_LEVEL_DEPT"
|
||||||
multiple
|
:key="index"
|
||||||
style="width: 100%"
|
:label="item.label"
|
||||||
>
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</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
|
<el-option
|
||||||
v-for="item in postOptions"
|
v-for="item in postOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
@ -107,11 +117,11 @@
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="configForm.candidateStrategy == CandidateStrategy.USER"
|
v-if="configForm.candidateStrategy == CandidateStrategy.USER"
|
||||||
label="指定用户"
|
label="指定用户"
|
||||||
prop="candidateParamArray"
|
prop="userIds"
|
||||||
span="24"
|
span="24"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="configForm.candidateParamArray"
|
v-model="configForm.userIds"
|
||||||
clearable
|
clearable
|
||||||
multiple
|
multiple
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
@ -128,14 +138,9 @@
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="configForm.candidateStrategy === CandidateStrategy.USER_GROUP"
|
v-if="configForm.candidateStrategy === CandidateStrategy.USER_GROUP"
|
||||||
label="指定用户组"
|
label="指定用户组"
|
||||||
prop="candidateParamArray"
|
prop="userGroups"
|
||||||
>
|
>
|
||||||
<el-select
|
<el-select v-model="configForm.userGroups" clearable multiple style="width: 100%">
|
||||||
v-model="configForm.candidateParamArray"
|
|
||||||
clearable
|
|
||||||
multiple
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in userGroupOptions"
|
v-for="item in userGroupOptions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
@ -147,11 +152,11 @@
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="configForm.candidateStrategy === CandidateStrategy.EXPRESSION"
|
v-if="configForm.candidateStrategy === CandidateStrategy.EXPRESSION"
|
||||||
label="流程表达式"
|
label="流程表达式"
|
||||||
prop="candidateParamArray"
|
prop="expression"
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
type="textarea"
|
type="textarea"
|
||||||
v-model="configForm.candidateParamArray[0]"
|
v-model="configForm.expression"
|
||||||
clearable
|
clearable
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
/>
|
/>
|
||||||
|
@ -364,9 +369,11 @@ import {
|
||||||
REJECT_HANDLER_TYPES,
|
REJECT_HANDLER_TYPES,
|
||||||
DEFAULT_BUTTON_SETTING,
|
DEFAULT_BUTTON_SETTING,
|
||||||
OPERATION_BUTTON_NAME,
|
OPERATION_BUTTON_NAME,
|
||||||
ButtonSetting
|
ButtonSetting,
|
||||||
|
MULTI_LEVEL_DEPT,
|
||||||
|
CANDIDATE_STRATEGY
|
||||||
} from '../consts'
|
} from '../consts'
|
||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
|
||||||
import {
|
import {
|
||||||
useWatchNode,
|
useWatchNode,
|
||||||
useNodeName,
|
useNodeName,
|
||||||
|
@ -390,6 +397,15 @@ const props = defineProps({
|
||||||
const emits = defineEmits<{
|
const emits = defineEmits<{
|
||||||
'find:returnTaskNodes': [nodeList: SimpleFlowNode[]]
|
'find:returnTaskNodes': [nodeList: SimpleFlowNode[]]
|
||||||
}>()
|
}>()
|
||||||
|
const deptLevelLabel = computed(() => {
|
||||||
|
let label = '部门负责人来源'
|
||||||
|
if (configForm.value.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER) {
|
||||||
|
label = label + '(指定部门向上)'
|
||||||
|
} else {
|
||||||
|
label = label + '(发起人部门向上)'
|
||||||
|
}
|
||||||
|
return label
|
||||||
|
})
|
||||||
// 监控节点的变化
|
// 监控节点的变化
|
||||||
const currentNode = useWatchNode(props)
|
const currentNode = useWatchNode(props)
|
||||||
// 抽屉配置
|
// 抽屉配置
|
||||||
|
@ -409,7 +425,12 @@ const formRef = ref() // 表单 Ref
|
||||||
// 表单校验规则
|
// 表单校验规则
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
candidateStrategy: [{ required: true, message: '审批人设置不能为空', trigger: 'change' }],
|
candidateStrategy: [{ required: true, message: '审批人设置不能为空', trigger: 'change' }],
|
||||||
candidateParamArray: [{ 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' }],
|
||||||
|
postIds: [{ required: true, message: '岗位不能为空', trigger: 'change' }],
|
||||||
|
expression: [{ required: true, message: '流程表达式不能为空', trigger: 'blur' }],
|
||||||
approveMethod: [{ required: true, message: '多人审批方式不能为空', trigger: 'change' }],
|
approveMethod: [{ required: true, message: '多人审批方式不能为空', trigger: 'change' }],
|
||||||
approveRatio: [{ required: true, message: '通过比例不能为空', trigger: 'blur' }],
|
approveRatio: [{ required: true, message: '通过比例不能为空', trigger: 'blur' }],
|
||||||
returnNodeId: [{ required: true, message: '驳回节点不能为空', trigger: 'change' }],
|
returnNodeId: [{ required: true, message: '驳回节点不能为空', trigger: 'change' }],
|
||||||
|
@ -426,6 +447,8 @@ const {
|
||||||
userOptions,
|
userOptions,
|
||||||
userGroupOptions,
|
userGroupOptions,
|
||||||
deptTreeOptions,
|
deptTreeOptions,
|
||||||
|
handleCandidateParam,
|
||||||
|
parseCandidateParam,
|
||||||
getShowText
|
getShowText
|
||||||
} = useNodeForm(NodeType.USER_TASK_NODE)
|
} = useNodeForm(NodeType.USER_TASK_NODE)
|
||||||
const configForm = tempConfigForm as Ref<UserTaskFormType>
|
const configForm = tempConfigForm as Ref<UserTaskFormType>
|
||||||
|
@ -433,7 +456,12 @@ const configForm = tempConfigForm as Ref<UserTaskFormType>
|
||||||
const notAllowedMultiApprovers = ref(false)
|
const notAllowedMultiApprovers = ref(false)
|
||||||
// 改变审批人设置策略
|
// 改变审批人设置策略
|
||||||
const changeCandidateStrategy = () => {
|
const changeCandidateStrategy = () => {
|
||||||
configForm.value.candidateParamArray = []
|
configForm.value.userIds = []
|
||||||
|
configForm.value.deptIds = []
|
||||||
|
configForm.value.roleIds = []
|
||||||
|
configForm.value.postIds = []
|
||||||
|
configForm.value.userGroups = []
|
||||||
|
configForm.value.deptLevel = 1
|
||||||
configForm.value.approveMethod = ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE
|
configForm.value.approveMethod = ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE
|
||||||
if (
|
if (
|
||||||
configForm.value.candidateStrategy === CandidateStrategy.START_USER ||
|
configForm.value.candidateStrategy === CandidateStrategy.START_USER ||
|
||||||
|
@ -447,7 +475,8 @@ const changeCandidateStrategy = () => {
|
||||||
// 改变审批候选人
|
// 改变审批候选人
|
||||||
const changedCandidateUsers = () => {
|
const changedCandidateUsers = () => {
|
||||||
if (
|
if (
|
||||||
configForm.value.candidateParamArray?.length <= 1 &&
|
configForm.value.userIds &&
|
||||||
|
configForm.value.userIds?.length <= 1 &&
|
||||||
configForm.value.candidateStrategy === CandidateStrategy.USER
|
configForm.value.candidateStrategy === CandidateStrategy.USER
|
||||||
) {
|
) {
|
||||||
configForm.value.approveMethod = ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE
|
configForm.value.approveMethod = ApproveMethodType.RRANDOM_SELECT_ONE_APPROVE
|
||||||
|
@ -488,7 +517,8 @@ const saveConfig = async () => {
|
||||||
if (!showText) return false
|
if (!showText) return false
|
||||||
currentNode.value.name = nodeName.value!
|
currentNode.value.name = nodeName.value!
|
||||||
currentNode.value.candidateStrategy = configForm.value.candidateStrategy
|
currentNode.value.candidateStrategy = configForm.value.candidateStrategy
|
||||||
currentNode.value.candidateParam = configForm.value.candidateParamArray?.join(',')
|
// 处理 candidateParam 参数
|
||||||
|
currentNode.value.candidateParam = handleCandidateParam()
|
||||||
// 设置审批方式
|
// 设置审批方式
|
||||||
currentNode.value.approveMethod = configForm.value.approveMethod
|
currentNode.value.approveMethod = configForm.value.approveMethod
|
||||||
if (configForm.value.approveMethod === ApproveMethodType.APPROVE_BY_RATIO) {
|
if (configForm.value.approveMethod === ApproveMethodType.APPROVE_BY_RATIO) {
|
||||||
|
@ -521,19 +551,9 @@ const showUserTaskNodeConfig = (node: SimpleFlowNode) => {
|
||||||
nodeName.value = node.name
|
nodeName.value = node.name
|
||||||
//1.1 审批人设置
|
//1.1 审批人设置
|
||||||
configForm.value.candidateStrategy = node.candidateStrategy!
|
configForm.value.candidateStrategy = node.candidateStrategy!
|
||||||
const strCandidateParam = node?.candidateParam
|
// 解析候选人参数
|
||||||
if (node.candidateStrategy === CandidateStrategy.EXPRESSION) {
|
parseCandidateParam(node.candidateStrategy!, node?.candidateParam)
|
||||||
configForm.value.candidateParamArray[0] = strCandidateParam
|
if (configForm.value.deptIds && configForm.value.deptIds.length > 1) {
|
||||||
} else {
|
|
||||||
if (strCandidateParam) {
|
|
||||||
configForm.value.candidateParamArray = strCandidateParam.split(',').map((item) => +item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
(configForm.value.candidateParamArray?.length <= 1 &&
|
|
||||||
node.candidateStrategy === CandidateStrategy.USER) ||
|
|
||||||
node.candidateStrategy === CandidateStrategy.START_USER
|
|
||||||
) {
|
|
||||||
notAllowedMultiApprovers.value = true
|
notAllowedMultiApprovers.value = true
|
||||||
} else {
|
} else {
|
||||||
notAllowedMultiApprovers.value = false
|
notAllowedMultiApprovers.value = false
|
||||||
|
|
Loading…
Reference in New Issue