Files
school-developer/src/flow/designer/components/flow-method.vue
吴红兵 1f645dad3e init
2025-12-02 10:37:49 +08:00

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>&lt;{{ data.whoseLeaderName }} 用户&gt;的第 &nbsp</span>
<el-input-number :min="1" :max="20" :step="1" style="width: 150px"
v-model="data.leaderLevel"></el-input-number>
<span> &nbsp级主管</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">不超过&lt;{{ data.whoseLeaderName }} 用户&gt;</el-radio>
</el-radio-group>
<div class="audit-endpoint">
&nbsp<el-input-number :min="1" :max="20" :step="1" style="width: 80px" controls-position="right"
v-model="data.leaderLevel"></el-input-number>&nbsp级主管
</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>