404 lines
16 KiB
Vue
404 lines
16 KiB
Vue
<template>
|
||
<el-form label-position="top" label-width="90px">
|
||
<el-form-item label="⚙ 选择审批对象" prop="text" class="user-type">
|
||
<el-radio-group v-model="nodeProps.assignedType">
|
||
<el-radio v-for="item in approvalTypes" :label="item.type" :key="item.type">{{ item.name }}</el-radio>
|
||
</el-radio-group>
|
||
<div v-if="nodeProps.assignedType === 'ASSIGN_USER'">
|
||
<el-button size="mini" icon="Plus" type="primary" @click="showSysRolePicker" round>
|
||
选择人员
|
||
</el-button>
|
||
<user-picker title="请选择系统角色" :multiple="false" ref="sysRolePicker" :v-model="assignedUser" @ok="selectedUser"/>
|
||
<!-- <ellipsis :row="3" :user-info="assignedUser"/>-->
|
||
<role-items v-model="assignedUser"/>
|
||
</div>
|
||
<div v-else-if="nodeProps.assignedType === 'SELF_SELECT'">
|
||
<el-radio-group size="mini" v-model="nodeProps.selfSelect.multiple">
|
||
<el-radio-button :label="false">自选一个人</el-radio-button>
|
||
<el-radio-button :label="true">自选多个人</el-radio-button>
|
||
</el-radio-group>
|
||
</div>
|
||
<div v-else-if="nodeProps.assignedType === 'LEADER_TOP'">
|
||
<el-divider/>
|
||
<el-form-item label="审批终点" prop="text" class="approve-end">
|
||
<el-radio-group v-model="nodeProps.leaderTop.endCondition">
|
||
<el-radio label="TOP">直到最上层主管</el-radio>
|
||
<el-radio label="LEAVE">不超过发起人的</el-radio>
|
||
</el-radio-group>
|
||
<div class="approve-end-leave" v-if="nodeProps.leaderTop.endCondition === 'LEAVE'">
|
||
<span>第 </span>
|
||
<el-input-number :min="1" :max="20" :step="1" size="mini" v-model="nodeProps.leaderTop.level"/>
|
||
<span> 级主管</span>
|
||
</div>
|
||
</el-form-item>
|
||
</div>
|
||
<div v-else-if="nodeProps.assignedType === 'LEADER'">
|
||
<el-divider/>
|
||
<el-form-item label="指定主管" prop="text">
|
||
<span>发起人的第 </span>
|
||
<el-input-number :min="1" :max="20" :step="1" size="mini"
|
||
v-model="nodeProps.leader.level"></el-input-number>
|
||
<span> 级主管</span>
|
||
<div style="color: #409EFF; font-size: small;">👉 直接主管为 第 1 级主管</div>
|
||
</el-form-item>
|
||
</div>
|
||
<div v-else-if="nodeProps.assignedType === 'ROLE'">
|
||
<el-button size="mini" icon="Plus" type="primary" @click="showRolePicker" round>
|
||
选择系统角色
|
||
</el-button>
|
||
<role-picker title="请选择人员" :multiple="false" ref="rolePicker" :v-model="roleList" @ok="selectedRole"/>
|
||
<role-items v-model="roleList"/>
|
||
</div>
|
||
<div v-else-if="nodeProps.assignedType === 'FORM_USER'">
|
||
<el-form-item label="选择表单联系人项" prop="text" class="approve-end">
|
||
<el-select style="width: 80%;" size="small" v-model="nodeProps.formUser" placeholder="请选择包含联系人的表单项" filterable>
|
||
<el-option v-for="(op,i) in forms" :label="op.title" :value="op.id" :key="i"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
</div>
|
||
<div v-else>
|
||
<span class="item-desc">发起人自己作为审批人进行审批</span>
|
||
</div>
|
||
</el-form-item>
|
||
<el-divider></el-divider>
|
||
<el-form-item label="👤 审批人为空时" prop="text" class="line-mode">
|
||
<el-radio-group v-model="nodeProps.nobody.handler">
|
||
<el-radio label="TO_PASS">自动通过</el-radio>
|
||
<el-radio label="TO_REFUSE">自动驳回</el-radio>
|
||
<el-radio label="TO_ADMIN">转交审批管理员</el-radio>
|
||
<el-radio label="TO_USER">转交到指定人员</el-radio>
|
||
</el-radio-group>
|
||
<div style="margin-top: 10px" v-if="nodeProps.nobody.handler === 'TO_USER'">
|
||
<el-button size="mini" icon="Plus" type="primary" @click="showUserPicker()" round>
|
||
选择人员
|
||
</el-button>
|
||
<user-picker title="请指定用户" :multiple="false" ref="toUserPicker" :v-model="nobodyAssignedUser"
|
||
@ok="selectNoSetUser"/>
|
||
<ellipsis :row="3" :user-info="nobodyAssignedUser"/>
|
||
</div>
|
||
</el-form-item>
|
||
|
||
<div v-if="showMode">
|
||
<el-divider/>
|
||
<el-form-item label="👩👦👦 多人审批时审批方式" prop="text" class="approve-mode">
|
||
<el-radio-group v-model="nodeProps.mode">
|
||
<el-radio label="NEXT">会签 (按选择顺序审批,每个人必须同意)</el-radio>
|
||
<el-radio label="AND">会签(可同时审批,每个人必须同意)</el-radio>
|
||
<el-radio label="OR">或签(有一人同意即可)</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
</div>
|
||
|
||
<el-divider>高级设置</el-divider>
|
||
<el-form-item label="✍ 审批同意时是否需要签字" prop="text">
|
||
<el-switch inactive-text="不用" active-text="需要" v-model="nodeProps.sign"></el-switch>
|
||
<el-tooltip class="item" effect="dark" content="如果全局设置了需要签字,则此处不生效" placement="top-start">
|
||
<i class="el-icon-question" style="margin-left: 10px; font-size: medium; color: #b0b0b1"></i>
|
||
</el-tooltip>
|
||
</el-form-item>
|
||
<el-form-item label="⏱ 审批期限(为 0 则不生效)" prop="timeLimit">
|
||
<el-input style="width: 180px;" placeholder="时长" type="number"
|
||
v-model="nodeProps.timeLimit.timeout.value">
|
||
<el-select style="width: 75px;" v-model="nodeProps.timeLimit.timeout.unit" slot="append" placeholder="请选择" filterable>
|
||
<el-option label="天" value="D"></el-option>
|
||
<el-option label="小时" value="H"></el-option>
|
||
</el-select>
|
||
</el-input>
|
||
</el-form-item>
|
||
<el-form-item label="审批期限超时后执行" prop="level" v-if="nodeProps.timeLimit.timeout.value > 0">
|
||
<el-radio-group v-model="nodeProps.timeLimit.handler.type">
|
||
<el-radio label="PASS">自动通过</el-radio>
|
||
<el-radio label="REFUSE">自动驳回</el-radio>
|
||
<el-radio label="NOTIFY">发送提醒</el-radio>
|
||
</el-radio-group>
|
||
<div v-if="nodeProps.timeLimit.handler.type === 'NOTIFY'">
|
||
<div style="color:#409EEF; font-size: small">默认提醒当前审批人</div>
|
||
<el-switch inactive-text="循环" active-text="一次" v-model="nodeProps.timeLimit.handler.notify.once"></el-switch>
|
||
<span style="margin-left: 20px" v-if="!nodeProps.timeLimit.handler.notify.once">
|
||
每隔
|
||
<el-input-number :min="0" :max="10000" :step="1" size="mini"
|
||
v-model="nodeProps.timeLimit.handler.notify.hour"/>
|
||
小时提醒一次
|
||
</span>
|
||
</div>
|
||
</el-form-item>
|
||
<el-form-item label="🙅 如果审批被驳回 👇">
|
||
<el-radio-group v-model="nodeProps.refuse.type">
|
||
<el-radio label="TO_INITIAL">重新开始流程</el-radio>
|
||
<el-radio label="TO_BEFORE">驳回到上级审批节点</el-radio>
|
||
<el-radio label="TO_NODE">驳回到指定节点</el-radio>
|
||
</el-radio-group>
|
||
<div v-if="nodeProps.refuse.type === 'TO_NODE'">
|
||
<span>指定节点:</span>
|
||
<el-select style="margin-left: 10px; width: 150px;" placeholder="选择跳转步骤" size="small"
|
||
v-model="nodeProps.refuse.target" filterable>
|
||
<el-option v-for="(node, index) in nodeOptions" :key="index" :label="node.name"
|
||
:value="node.id"></el-option>
|
||
</el-select>
|
||
</div>
|
||
</el-form-item>
|
||
<el-form-item label="自定义监听器">
|
||
<div slot="label">
|
||
<span style="margin-left: 20px">使用自定义监听器: </span>
|
||
<!-- <el-switch v-model="config.listener.state" @change="getListener"></el-switch>-->
|
||
</div>
|
||
<div v-if="config.listener.state">
|
||
<div slot="label">
|
||
<span style="margin-right: 10px">设置监听器</span>
|
||
<el-button type="primary" @click="addListener(config.listener.list)" link> + 添加</el-button>
|
||
</div>
|
||
<div v-for="(listen, index) in config.listener.list" :key="index">
|
||
<el-input v-if="listen.isSys" placeholder="监听器名称" :disabled="true" size="small" style="width: 100px;"
|
||
v-model="listen.listenerName"/>
|
||
<el-input v-if="!listen.isSys" placeholder="监听器名称" size="small" style="width: 100px;"
|
||
v-model="listen.listenerName"/>
|
||
<el-radio-group size="small" style="margin: 0 5px;" @change="typeChange(listen)" v-model="listen.isSys">
|
||
<el-radio-button :label="true">内置</el-radio-button>
|
||
<el-radio-button :label="false">自定义</el-radio-button>
|
||
</el-radio-group>
|
||
<el-select v-if="listen.isSys" style="width: 180px;" v-model="listen.listenerValue" size="small"
|
||
@change="listenerOptionChange(listen)"
|
||
placeholder="请选择表单字段" filterable>
|
||
<el-option v-for="option in listenerOption" :key="option.value" :label="option.label"
|
||
:value="option.value"/>
|
||
</el-select>
|
||
<!-- <el-input v-if="listen.isSys" placeholder="请设置字段值" size="small" v-model="listen.listenerValue" style="width: 180px;"/>-->
|
||
<el-button v-if="!listen.isSys" type="primary" size="small" @click="settingListener(listen)" link>设置</el-button>
|
||
<el-button @click="delListener(config.listener.list, index)"
|
||
class="el-icon-delete" type="primary"
|
||
style="margin-left: 5px; color: #c75450;" link/>
|
||
</div>
|
||
</div>
|
||
</el-form-item>
|
||
</el-form>
|
||
<!--
|
||
<el-dialog custom-class="custom-dialog" class="border" width="600px" title="定义监听器设置"
|
||
append-to-body :close-on-click-modal="true"
|
||
:destroy-on-close="true" :visible.sync="editListenShow">
|
||
<el-form ref="listenerForm" label-position="left" label-width="100px" :rules="listenerRules">
|
||
<el-form-item label="监听器名称" prop="listenerName" class="listen">
|
||
<el-input placeholder="请设置监听器名称" size="small" v-model="selectListen.listenerName"/>
|
||
</el-form-item>
|
||
<el-form-item label="监听器类型" prop="eventType" class="listen">
|
||
<el-select placeholder="请选择监听器类型" @change="selectListen.eventType = []"
|
||
v-model="selectListen.listenerType" filterable>
|
||
<el-option :value="'1'" label="任务监听"/>
|
||
<el-option :value="'2'" label="执行监听"/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="事件类型" prop="listenerType" class="listen">
|
||
<el-select multiple placeholder="请选择事件类型" v-model="selectListen.eventType" filterable>
|
||
<el-option value="create" label="create"/>
|
||
<el-option v-if="selectListen.listenerType === '2'" value="end" label="end"/>
|
||
<el-option v-if="selectListen.listenerType === '2'" value="take" label="take"/>
|
||
<el-option v-if="selectListen.listenerType === '1'" value="assignment" label="assignment"/>
|
||
<el-option v-if="selectListen.listenerType === '1'" value="complete" label="complete"/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="值类型" prop="listenerValueType" class="listen">
|
||
<el-radio-group size="small" style="margin: 0 5px;" @change="listenerValueTypeChange"
|
||
v-model="selectListen.listenerValueType">
|
||
<el-radio-button :label="'0'">Java类</el-radio-button>
|
||
<el-radio-button :label="'1'">表达式</el-radio-button>
|
||
<el-radio-button :label="'2'">代理表达式</el-radio-button>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<el-form-item label="值" prop="listenerValue" class="listen">
|
||
<el-input :placeholder="listenerValuePlaceholder" size="small" v-model="selectListen.listenerValue"/>
|
||
</el-form-item>
|
||
</el-form>
|
||
<div slot="footer">
|
||
<el-button size="mini" @click="editListenShow = false">取消</el-button>
|
||
<el-button size="mini" type="primary" @click="editListenShow = false">确认</el-button>
|
||
</div>
|
||
</el-dialog>-->
|
||
</template>
|
||
<script setup>
|
||
import {useProcessStore} from '@/stores/processStore.js'
|
||
import UserPicker from '../common/UserPicker.vue'
|
||
import RolePicker from '../common/RolePicker.vue'
|
||
import Ellipsis from '../common/Ellipsis.vue'
|
||
import RoleItems from "../common/RoleItems.vue";
|
||
import {computed, defineProps} from 'vue'
|
||
|
||
const processStore = useProcessStore()
|
||
|
||
const toUserPicker = ref()
|
||
const rolePicker = ref()
|
||
const sysRolePicker = ref()
|
||
const showOrgSelect = ref(false)
|
||
const orgPickerSelected = ref([])
|
||
const approvalTypes = reactive([
|
||
{name: "指定人员", type: "ASSIGN_USER"},
|
||
{name: "发起人自选", type: "SELF_SELECT"},
|
||
{name: "连续多级主管", type: "LEADER_TOP"},
|
||
{name: "主管", type: "LEADER"},
|
||
{name: "角色", type: "ROLE"},
|
||
{name: "发起人自己", type: "SELF"},
|
||
{name: "表单内联系人", type: "FORM_USER"}
|
||
])
|
||
const listenerOption = ref([])
|
||
const selectListen = ref({})
|
||
const editListenShow = ref(false)
|
||
const listenerValuePlaceholder = ref('请输入类路径')
|
||
const listenerRules = ref({
|
||
listenerName: [
|
||
{required: true, message: '监听器名称不能为空', trigger: 'blur'}
|
||
],
|
||
eventType: [
|
||
{required: true, message: '监听器类型不能为空', trigger: 'blur'},
|
||
// {validator: checkLength,trigger:'blur'}
|
||
],
|
||
listenerType: [
|
||
{required: true, message: '监听器类型不能为空', trigger: 'blur'},
|
||
],
|
||
listenerValue: [
|
||
{required: true, message: '值不能为空', trigger: 'blur'}
|
||
],
|
||
})
|
||
|
||
|
||
const props = defineProps({
|
||
config: {
|
||
type: Object,
|
||
default: () => {
|
||
return {};
|
||
}
|
||
}
|
||
})
|
||
|
||
|
||
const nodeProps = computed(() => {
|
||
return processStore.getSelectedNode().props;
|
||
})
|
||
|
||
const assignedUser = computed({
|
||
get() {
|
||
return props.config.assignedUser || [];
|
||
},
|
||
set(val) {
|
||
props.config.assignedUser = val
|
||
}
|
||
})
|
||
|
||
|
||
const nobodyAssignedUser = computed({
|
||
get() {
|
||
return props.config.nobody.assignedUser || [];
|
||
},
|
||
set(val) {
|
||
props.config.nobody.assignedUser = val
|
||
}
|
||
})
|
||
|
||
const roleList = computed({
|
||
get() {
|
||
return props.config.roleList || [];
|
||
},
|
||
set(val) {
|
||
props.config.roleList = val
|
||
}
|
||
})
|
||
watch(()=>props.config.roleList,(value)=>{
|
||
roleList.value = value
|
||
})
|
||
|
||
const forms = computed(() => {
|
||
return processStore.getDesign().formItems.filter(f => {
|
||
return f.name === "UserPicker";
|
||
});
|
||
})
|
||
|
||
|
||
const nodeOptions = computed(() => {
|
||
let values = [];
|
||
const excType = ["ROOT", "EMPTY", "CONDITION", "CONDITIONS", "CONCURRENT", "CONCURRENTS", "CC", "END", "TRIGGER"];
|
||
processStore.nodeMap.forEach((v) => {
|
||
if (excType.indexOf(v.type) === -1) {
|
||
values.push({id: v.id, name: v.name});
|
||
}
|
||
});
|
||
return values;
|
||
})
|
||
|
||
|
||
const showMode = computed(() => {
|
||
let props = processStore.getSelectedNode().props;
|
||
switch (props.assignedType) {
|
||
case "ASSIGN_USER":
|
||
return props.assignedUser.length > 0;
|
||
case "SELF_SELECT":
|
||
return props.selfSelect.multiple;
|
||
case "LEADER_TOP":
|
||
return props.formUser !== "";
|
||
case "FORM_USER":
|
||
case "ROLE":
|
||
return true;
|
||
default:
|
||
return false;
|
||
}
|
||
})
|
||
//指定人员
|
||
const showSysRolePicker = () => {
|
||
sysRolePicker.value.showUserPicker()
|
||
}
|
||
//点击转交给指定人员
|
||
const showUserPicker = () => {
|
||
toUserPicker.value.showUserPicker()
|
||
}
|
||
//选择系统角色
|
||
const showRolePicker = () => {
|
||
rolePicker.value.showRolePicker()
|
||
}
|
||
const checkLength = (rule, value, callback) => {
|
||
if (value.length === 0) {
|
||
callback(new Error("事件类型不能为空!"))
|
||
} else {
|
||
callback()
|
||
}
|
||
}
|
||
|
||
const selectNoSetUser = (select) => {
|
||
let userInfoList = []
|
||
for (let val of select) {
|
||
let userInfo = {
|
||
id: val.id,
|
||
name: val.name,
|
||
avatar: val.avatar,
|
||
}
|
||
userInfoList.push(userInfo)
|
||
}
|
||
nobodyAssignedUser.value = userInfoList
|
||
}
|
||
|
||
|
||
const selectedRole = (select) => {
|
||
let roleInfoList = []
|
||
for (let val of select) {
|
||
let userInfo = {
|
||
value: val.roleId,
|
||
name: val.roleName
|
||
}
|
||
roleInfoList.push(userInfo)
|
||
}
|
||
roleList.value = roleInfoList
|
||
}
|
||
const selectedUser = (select) => {
|
||
let userInfoList = []
|
||
for (let val of select) {
|
||
let userInfo = {
|
||
id: val.id,
|
||
name: val.name,
|
||
avatar: val.avatar,
|
||
}
|
||
userInfoList.push(userInfo)
|
||
}
|
||
assignedUser.value = userInfoList
|
||
}
|
||
|
||
</script>
|
||
|
||
<style scoped>
|
||
|
||
</style>
|