This commit is contained in:
clay
2024-03-04 19:13:43 +08:00
commit e44edd71c0
350 changed files with 52288 additions and 0 deletions

View File

@@ -0,0 +1,402 @@
<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"/>
<avatar-ellipsis :row="3" :user-info="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="nodeProps.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"/>
<avatar-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 AvatarEllipsis from '../common/AvatarEllipsis.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 = {
roleId: val.roleId,
roleName: 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>