361 lines
17 KiB
Vue
361 lines
17 KiB
Vue
<template>
|
|
<div>
|
|
<el-tabs class="flow-attr"
|
|
v-model="data.activeKey">
|
|
<el-tab-pane name="flow-method">
|
|
<template #label>
|
|
<div>
|
|
<el-icon style="vertical-align: middle;margin-right: 3px">
|
|
<User/>
|
|
</el-icon>
|
|
<span style="vertical-align: middle;">选择审批对象</span>
|
|
</div>
|
|
</template>
|
|
<el-form label-position="left" class="flow-config-attr" label-width="170px">
|
|
|
|
<div style="margin: 5px 20px">
|
|
<span style="color: red;font-size: 14px">注: 当前审批对象可自定义任意扩展(只需写好接口即可), 满足您分配参与者复杂的场景</span>
|
|
</div>
|
|
|
|
<el-divider> 审批对象设置 </el-divider>
|
|
|
|
<el-form-item label="审批对象类型">
|
|
<el-radio-group style="width: 283px" @change="methods.handleUserKeyValFrom"
|
|
v-model="data.userKeyValFrom">
|
|
<el-radio v-for="(item, index) in DIC_PROP.FLOW_METHOD_TYPE" :key="index" :label="item.value"
|
|
:disabled="item.value === '-1'">
|
|
{{ item.label }}
|
|
</el-radio>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
|
|
<template v-if="data.userKeyValFrom === '0'">
|
|
<div style="margin-left: 15px">※ 发起人本人将作为审批人</div>
|
|
</template>
|
|
|
|
<template v-if="data.userKeyValFrom === '1'">
|
|
<el-divider> </el-divider>
|
|
<el-form-item label="谁的主管">
|
|
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
|
<el-select class="input-attr"
|
|
v-model="data.whoseLeader" @change="methods.changeWhoseLeader"
|
|
clearable filterable
|
|
remote :remote-method="remoteMethod" :reserve-keyword="false">
|
|
<template v-for="(item, index) in dicData.users" :key="index">
|
|
<el-option :label="item.name"
|
|
:value="item.userId">
|
|
</el-option>
|
|
</template>
|
|
</el-select>
|
|
</el-tooltip>
|
|
<el-tooltip placement="top" content="用于指定哪个用户的部门主管">
|
|
<el-icon style="margin-left: 10px"><QuestionFilled /></el-icon>
|
|
</el-tooltip>
|
|
</el-form-item>
|
|
|
|
<el-divider> </el-divider>
|
|
<el-form-item label="指定主管">
|
|
<div>
|
|
<span><{{ data.whoseLeaderName }} 用户>的第  </span>
|
|
<el-input-number :min="1" :max="20" :step="1" style="width: 150px"
|
|
v-model="data.leaderLevel"></el-input-number>
|
|
<span>  级主管</span>
|
|
<div style="color: #409EFF; font-size: small;">👉 指定主管为 第 {{ data.leaderLevel }} 级主管</div>
|
|
</div>
|
|
</el-form-item>
|
|
|
|
<el-divider> </el-divider>
|
|
<el-form-item label="提取规则">
|
|
<el-radio-group style="width: 283px"
|
|
v-model="data.levelExtract">
|
|
<el-radio v-for="(item, index) in EXTRACTS.SINGLE_EXTRACT" :key="index" :label="item.value">
|
|
{{ item.label }}
|
|
</el-radio>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
</template>
|
|
|
|
<template v-if="data.userKeyValFrom === '2'">
|
|
<el-divider> </el-divider>
|
|
<el-form-item label="谁的主管">
|
|
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
|
<el-select class="input-attr"
|
|
v-model="data.whoseLeader" @change="methods.changeWhoseLeader"
|
|
clearable filterable
|
|
remote :remote-method="remoteMethod" :reserve-keyword="false">
|
|
<template v-for="(item, index) in dicData.users" :key="index">
|
|
<el-option :label="item.name"
|
|
:value="item.userId">
|
|
</el-option>
|
|
</template>
|
|
</el-select>
|
|
</el-tooltip>
|
|
<el-tooltip placement="top" content="用于指定哪个用户的部门主管">
|
|
<el-icon style="margin-left: 10px"><QuestionFilled /></el-icon>
|
|
</el-tooltip>
|
|
</el-form-item>
|
|
|
|
<el-divider> </el-divider>
|
|
<el-form-item label="审批终点">
|
|
<el-radio-group style="width: 200px" v-model="data.auditEndpoint">
|
|
<el-radio label="0">直到最上层主管</el-radio>
|
|
<el-radio label="1">不超过<{{ data.whoseLeaderName }} 用户>的</el-radio>
|
|
</el-radio-group>
|
|
<div class="audit-endpoint">
|
|
第 <el-input-number :min="1" :max="20" :step="1" style="width: 80px" controls-position="right"
|
|
v-model="data.leaderLevel"></el-input-number> 级主管
|
|
</div>
|
|
</el-form-item>
|
|
|
|
<el-divider> </el-divider>
|
|
<el-form-item label="依次审批顺序">
|
|
<el-tooltip content="当节点属性【多人审批方式】为依次审批时,审批顺序由选择的顺序决定" placement="bottom">
|
|
<el-radio-group style="width: 200px" v-model="data.seqAuditSort">
|
|
<el-radio label="0">下级到上级</el-radio>
|
|
<el-radio label="1">上级到下级</el-radio>
|
|
</el-radio-group>
|
|
</el-tooltip>
|
|
|
|
<el-button v-if="data.seqAuditSort" text type="primary" icon="delete" @click="data.seqAuditSort = null">
|
|
清空
|
|
</el-button>
|
|
</el-form-item>
|
|
|
|
<el-divider> </el-divider>
|
|
<el-form-item label="提取规则">
|
|
<el-radio-group style="width: 283px"
|
|
v-model="data.levelExtract">
|
|
<el-radio v-for="(item, index) in EXTRACTS.MULTI_EXTRACT" :key="index" :label="item.value">
|
|
{{ item.label }}
|
|
</el-radio>
|
|
</el-radio-group>
|
|
<el-tooltip placement="top" content="必须保证最终至少存在一个主管">
|
|
<el-icon class="audit-endpoint-extract"><QuestionFilled /></el-icon>
|
|
</el-tooltip>
|
|
</el-form-item>
|
|
</template>
|
|
|
|
<template v-if="data.userKeyValFrom === '3'">
|
|
<el-divider> </el-divider>
|
|
<el-form-item label="哪个部门">
|
|
<el-tooltip content="请输入部门名称进行模糊搜索" placement="top">
|
|
<el-select class="input-attr"
|
|
v-model="data.appointDeptId"
|
|
clearable filterable
|
|
remote :remote-method="remoteMethodDept" :reserve-keyword="false">
|
|
<template v-for="(item, index) in dicData.depts" :key="index">
|
|
<el-option :label="item.name"
|
|
:value="item.deptId">
|
|
</el-option>
|
|
</template>
|
|
</el-select>
|
|
</el-tooltip>
|
|
<el-tooltip placement="top" content="用于指定哪个部门的主管">
|
|
<el-icon style="margin-left: 10px"><QuestionFilled /></el-icon>
|
|
</el-tooltip>
|
|
</el-form-item>
|
|
|
|
<el-divider> </el-divider>
|
|
<el-form-item label="提取规则">
|
|
<el-radio-group style="width: 283px"
|
|
v-model="data.levelExtract">
|
|
<el-radio v-for="(item, index) in EXTRACTS.DEPT_EXTRACT" :key="index" :label="item.value">
|
|
{{ item.label }}
|
|
</el-radio>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
</template>
|
|
|
|
<template v-if="data.userKeyValFrom === '4'">
|
|
<el-divider> </el-divider>
|
|
<el-form-item label="表单字段">
|
|
<el-select v-model="data.userKeyVal"
|
|
clearable
|
|
filterable>
|
|
<el-option
|
|
v-for="(item, index) in data.formFieldPerms"
|
|
:key="index"
|
|
:label="item.label"
|
|
:value="item.prop">
|
|
</el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
</template>
|
|
|
|
<el-button
|
|
type="primary" round style="margin-left: 185px; margin-top: 50px; width: 200px"
|
|
@click="methods.confirmMethods">
|
|
确定
|
|
</el-button>
|
|
</el-form>
|
|
</el-tab-pane>
|
|
<el-tab-pane name="flow-rule">
|
|
<template #label>
|
|
<div>
|
|
<el-icon style="vertical-align: middle;margin-right: 3px">
|
|
<Setting/>
|
|
</el-icon>
|
|
<span style="vertical-align: middle;">设置审批规则</span>
|
|
</div>
|
|
</template>
|
|
<el-form label-position="left" class="flow-config-attr" label-width="150px">
|
|
<flow-user-rule :currSelect="props.currSelect" :currFlowForm="props.currFlowForm" :flowData="props.flowData"></flow-user-rule>
|
|
</el-form>
|
|
</el-tab-pane>
|
|
|
|
<el-tab-pane name="flow-curr-job" v-if="methods.validateNodeJobCurrJob()">
|
|
<template #label>
|
|
<div>
|
|
<el-icon style="vertical-align: middle;margin-right: 3px">
|
|
<Setting/>
|
|
</el-icon>
|
|
<span style="vertical-align: middle;">节点参与者列表</span>
|
|
</div>
|
|
</template>
|
|
<el-form label-position="left" class="flow-config-attr" label-width="150px">
|
|
<flow-curr-job :currSelect="props.currSelect"></flow-curr-job>
|
|
</el-form>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts" name="FlowMethod">
|
|
import {useI18n} from "vue-i18n";
|
|
import {useMessage} from "/@/hooks/message";
|
|
import {validateNull} from "/@/utils/validate";
|
|
import {onFormLoadedUrl, onLoadDicUrl, remoteMethodByKey} from "/@/flow/components/convert-name/convert";
|
|
import {validateListFormOption} from "../../utils/form-perm";
|
|
import {parseUserKeyValName, revParseUserKeyValName, revParseWhoseLeaderName} from "./index";
|
|
|
|
const { proxy } = getCurrentInstance();
|
|
const FlowUserRule = defineAsyncComponent(() => import('./flow-user-rule.vue'));
|
|
const FlowCurrJob = defineAsyncComponent(() => import('./flow-curr-job.vue'));
|
|
const $emit = defineEmits(["openFlowMethods"]);
|
|
|
|
const {t} = useI18n();
|
|
const $message = useMessage();
|
|
const props = defineProps({
|
|
currFlowForm: {
|
|
type: Object,
|
|
default: null,
|
|
},
|
|
currSelect: {
|
|
type: Object,
|
|
default: {},
|
|
},
|
|
flowData: {
|
|
type: Object,
|
|
default: null,
|
|
},
|
|
});
|
|
|
|
const EXTRACTS = {
|
|
SINGLE_EXTRACT: [{
|
|
label: '无主管时由上级主管代审批',
|
|
value: '0'
|
|
}, {
|
|
label: '无主管时[报错]处理',
|
|
value: '1'
|
|
}],
|
|
MULTI_EXTRACT: [{
|
|
label: '无主管时由上级主管代审批,直到满足等级的人数',
|
|
value: '0'
|
|
}, {
|
|
label: '无主管时[按空]处理',
|
|
value: '1'
|
|
}],
|
|
DEPT_EXTRACT: [{
|
|
label: '无主管时由上级主管代审批',
|
|
value: '0'
|
|
}, {
|
|
label: '无主管时[报错]处理',
|
|
value: '1'
|
|
}],
|
|
}
|
|
const data = reactive({
|
|
activeKey: 'flow-method',
|
|
formFieldPerms: [],
|
|
userKeyValFrom: '1',
|
|
whoseLeader: null,
|
|
whoseLeaderName: '请先指定',
|
|
leaderLevel: 1,
|
|
auditEndpoint: '0',
|
|
seqAuditSort: null,
|
|
levelExtract: '0',
|
|
appointDeptId: null,
|
|
userKeyVal: null,
|
|
})
|
|
|
|
// 定义字典
|
|
const dicData = reactive({});
|
|
const onLoad = onLoadDicUrl();
|
|
const onFormLoaded = onFormLoadedUrl({key: "users", field: "whoseLeader"}, {key: "depts", field: "appointDeptId"});
|
|
onMounted(async () => {
|
|
// await onLoad(dicData);
|
|
|
|
methods.changeTabPane(props.currSelect)
|
|
})
|
|
|
|
function remoteMethodDept(query: string) {
|
|
remoteMethodByKey(query, onLoad, dicData, 'deptName', "depts")
|
|
}
|
|
|
|
async function remoteMethod(query: string) {
|
|
await remoteMethodByKey(query, onLoad, dicData, 'userName', "users")
|
|
revParseWhoseLeaderName(data, dicData)
|
|
}
|
|
|
|
const methods = {
|
|
handleUserKeyValFrom(type) {
|
|
if (type !== '4' || !validateNull(data.formFieldPerms)) return
|
|
validateListFormOption(data, props, $message)
|
|
},
|
|
confirmMethods() {
|
|
parseUserKeyValName(props, data, methods)
|
|
$emit("openFlowMethods", false);
|
|
},
|
|
$message(type) {
|
|
if (type === 'whoseLeader') $message.warning('请选择谁的主管');
|
|
if (type === 'appointDeptId') $message.warning('请选择指定部门');
|
|
},
|
|
changeWhoseLeader(userId) {
|
|
if (!userId) {
|
|
data.whoseLeaderName = '请先指定'
|
|
return
|
|
}
|
|
data.whoseLeaderName = dicData.users.find(f => f.userId === userId).name;
|
|
},
|
|
validateNodeJobCurrJob() {
|
|
return !validateNull(props.currSelect.attributes) && props.currSelect.attributes.attrs.cdata.defJob
|
|
&& !validateNull(props.currSelect.attributes.attrs.cdata.defJob.currRunJobs);
|
|
},
|
|
async changeTabPane(val) {
|
|
if (Object.keys(val).length === 0) {
|
|
data.activeKey = ''
|
|
return
|
|
}
|
|
// 反解析出已配置项
|
|
await revParseUserKeyValName(props, data, dicData, methods)
|
|
await onFormLoaded(dicData, data)
|
|
revParseWhoseLeaderName(data, dicData)
|
|
},
|
|
}
|
|
// 监听双向绑定
|
|
watch(
|
|
() => props.currSelect,
|
|
(val) => {
|
|
if (validateNull(val) || Object.keys(val).length === 0) {
|
|
data.activeKey = ''
|
|
return
|
|
}
|
|
methods.changeTabPane(val)
|
|
}
|
|
);
|
|
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
@import '../assets/style/flow-attr.scss';
|
|
</style>
|