This commit is contained in:
吴红兵
2025-12-02 10:37:49 +08:00
commit 1f645dad3e
1183 changed files with 147673 additions and 0 deletions

View File

@@ -0,0 +1,370 @@
<template>
<div>
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="110px" v-loading="loading"
:disabled="operType === 'view'">
<el-row :gutter="24">
<!-- <el-col :span="24" class="mb20">
<el-form-item>
<div style="color: red;font-size: 14px">备注: 当不指定待分配节点时, 默认对当前相同userKey进行全局统一分配</div>
</el-form-item>
</el-col>-->
<el-col :span="12" class="mb20">
<el-form-item :label="t('distPerson.code')" prop="code">
<el-select v-model="form.code" :placeholder="t('distPerson.inputCodeTip')" clearable filterable disabled
@change="cascadeChange('code', ['flowInstId'])">
<el-option v-for="(item, index) in dicData.code" :key="index" :label="item.code" :value="item.code"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('distPerson.flowKey')" prop="flowInstId">
<el-select v-model="form.flowInstId" :placeholder="t('distPerson.inputFlowKeyTip')" clearable filterable disabled
@change="cascadeChange('flowInstId', ['runNodeId'])">
<el-option v-for="(item, index) in cascadeDic.flowInstId" :key="index" :label="item.flowName" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('distPerson.runNodeId')" prop="runNodeId">
<el-select v-model="form.runNodeId" :placeholder="t('distPerson.inputRunNodeIdTip')" clearable filterable
:disabled="!!props.currJob.distFlowNodeId"
@change="cascadeChange('runNodeId', ['distRunJobId'])">
<el-option v-for="(item, index) in cascadeDic.runNodeId" :key="index" :label="item.nodeName" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('distPerson.runJobId')" prop="runJobId">
<el-select v-model="form.runJobId" :placeholder="t('distPerson.inputRunJobIdTip')" clearable filterable @change="runJobIdChange">
<el-option v-for="(item, index) in cascadeDic.distRunJobId" :key="index" :label="item.jobName" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item :label="t('distPerson.userKey')" prop="userKey" disabled>
<el-input v-model="form.userKey" :placeholder="t('distPerson.inputUserKeyTip')" disabled/>
</el-form-item>
</el-col>
<!-- <el-col :span="12" class="mb20">
<el-form-item :label="t('distPerson.isNowRun')" prop="isNowRun" disabled>
<el-radio-group disabled v-model="form.isNowRun">
<el-radio v-for="(item, index) in DIC_PROP.YES_OR_NO" :key="index" :label="item.value">
{{ getLabelByLanguage(item) }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>-->
</el-row>
<el-row :gutter="48">
<el-col :span="24" class="mb20">
<el-form-item>
<div style="color: red;font-size: 14px">: 分配参与者允许为任意的节点分配参与者, 让分配参与者更自由</div>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item :label="t('distPerson.roleUserId')" prop="roleUserId">
<el-table :data="form.roleUserId" border style="width: 100%" max-height="500">
<el-table-column type="index" :label="t('distPerson.index')" width="80">
<template #header>
<el-button icon="Plus" size="small" type="primary" circle
@click="methods.onAddItem"></el-button>
</template>
<template #default="scope">
<el-button icon="Minus" size="small" type="danger" circle :disabled="scope.row.isDisabled"
@click="methods.handleDelete(scope.$index, scope.row)"></el-button>
</template>
</el-table-column>
<el-table-column prop="jobType" :label="t('distPerson.jobType')" show-overflow-tooltip >
<template #default="scope">
<el-select v-model="scope.row.jobType" :placeholder="t('distPerson.inputJobTypeTip')" clearable filterable
@change="handleRoleType" :disabled="scope.row.isDisabled">
<el-option v-for="(item, index) in DIC_PROP.JOB_USER_TYPE" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="roleId" :label="t('distPerson.roleId')" show-overflow-tooltip>
<template #default="scope">
<el-tooltip content="请输入名称进行模糊搜索" placement="top">
<el-select v-model="scope.row.roleId" :placeholder="t('distPerson.inputRoleIdTip')" clearable filterable
:disabled="scope.row.isDisabled"
remote :remote-method="(query) => remoteMethodAll(query, scope.row.jobType)" :reserve-keyword="false">
<el-option v-for="(item, index) in dicData.users" :key="index" :label="item.name" :value="item.userId"
v-if="scope.row.jobType === DIC_PROP.JOB_USER_TYPE[0].value"></el-option>
<el-option v-for="(item, index) in dicData.roles" :key="index" :label="item.roleName" :value="item.roleId"
v-if="scope.row.jobType === DIC_PROP.JOB_USER_TYPE[1].value"></el-option>
<el-option v-for="(item, index) in dicData.posts" :key="index" :label="item.postName" :value="item.postId"
v-if="scope.row.jobType === DIC_PROP.JOB_USER_TYPE[2].value"></el-option>
<el-option v-for="(item, index) in dicData.depts" :key="index" :label="item.name" :value="item.deptId"
v-if="scope.row.jobType === DIC_PROP.JOB_USER_TYPE[3].value"></el-option>
</el-select>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="jobName" :label="t('distPerson.jobName')" show-overflow-tooltip>
<template #default="scope">
<el-tooltip placement="top" content="可为空为空时参与者的任务名称都相同">
<el-input v-model="scope.row.jobName" :placeholder="t('distPerson.inputJobNameTip')" :disabled="scope.row.isDisabled"/>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="sort" :label="t('distPerson.sort')" show-overflow-tooltip>
<template #default="scope">
<el-tooltip placement="top" content="可为空为空时参与者的任务排序值都相同">
<el-input-number :min="1" :max="1000" v-model="scope.row.sort" :placeholder="t('distPerson.inputSortTip')"
:disabled="scope.row.isDisabled"></el-input-number>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template v-if="operType !== 'view'">
<footer class="el-dialog__footer">
<span class="dialog-footer">
<el-button type="primary" @click="methods.handleUpdate" :disabled="loading">{{
$t('common.confirmButtonText')
}}</el-button>
</span>
</footer>
</template>
</div>
</template>
<script setup lang="ts" name="DistPersonFlow">
import {useMessage} from "/@/hooks/message";
import {getByFlowInstId, saveByFlowInstId} from '/@/api/jsonflow/dist-person'
import {useI18n} from "vue-i18n"
import {
onCascadeChange,
onFormLoadedUrl,
onLoadDicUrl,
remoteMethodAllByKey
} from "/@/flow/components/convert-name/convert";
import {setPropsDataValue, setPropsNull} from '/@/flow/support/common'
import * as orderVue from "/@/api/order/order-key-vue";
import { useUserInfo } from '/@/stores/userInfo';
import {validateNull} from "/@/utils/validate";
import {DIC_PROP} from "/@/flow/support/dict-prop";
import {handleChangeJobType} from "/@/flow";
import {PROP_CONST} from "/@/flow/support/prop-const";
const {t} = useI18n();
const userInfo = useUserInfo();
const emits = defineEmits(["handleJob"]);
// 定义变量内容
const dataFormRef = ref();
const loading = ref(false);
const operType = ref(false);
// 定义字典
const dicData = reactive({});
const onLoad = onLoadDicUrl({key: "code"});
const onFormLoaded = onFormLoadedUrl(...PROP_CONST.LOAD_USER_ROLE);
onMounted(async () => {
await onLoad(dicData);
});
const fields = ['userKey', 'valType', 'isNowRun'];
const cascadeDic = reactive({});
const onCascade = onCascadeChange(cascadeDic, {key: "code", cascades: ["flowInstId"]}, {key: "flowInstId", cascades: ["runNodeId"]}, {key: "runNodeId", cascades: ["distRunJobId"]});
async function cascadeChange(key, cascades) {
await onCascade(form, {key: key, cascades: cascades});
if (key === 'runNodeId') {
setPropsNull(form, ...fields)
form.roleUserId = []
if (!validateNull(cascadeDic.distRunJobId)) return
useMessage().info("当前节点任务非指定参与者KEY类型不允许前端分配参与者");
}
}
function runJobIdChange(newVal){
form.roleUserId = []
if (!newVal) {
setPropsNull(form, ...fields)
return
}
const runJob = cascadeDic.distRunJobId.find(f => f.id === newVal)
setPropsDataValue(form, runJob, fields)
if (form.valType !== DIC_PROP.VAL_TYPE[1].value) {
form.runJobId = null
useMessage().info("当前节点任务非指定参与者KEY类型不允许前端分配参与者");
return;
}
form.runJobId = newVal;
// 重新查询分配信息
methods.handleGetObj(form)
}
function handleRoleType() {
handleChangeJobType(dicData, form)
}
// 提交表单数据
const form = reactive({
code: '',
runNodeId: '',
runJobId: '',
userKey: '',
flowInstId: '',
flowKey: '',
roleUserId: [],
});
// 定义校验规则
const dataRules = ref({
code: [{required: true, message: '工单编号不能为空', trigger: 'blur'}],
runNodeId: [{required: true, message: '节点名称不能为空', trigger: 'blur'}],
runJobId: [{required: true, message: '任务名称不能为空', trigger: 'blur'}],
userKey: [{required: true, message: '参与者KEY不能为空', trigger: 'blur'}],
// roleUserId: [{required: true, message: '参与者不能为空', trigger: 'blur'}],
})
const props = defineProps({
currJob: {
type: Object,
default: null,
},
currElTab: {
type: Object,
default: {},
},
});
function remoteMethodAll(query: string, jobType) {
remoteMethodAllByKey(onLoad, dicData, query, jobType)
}
const methods = {
disableForm() {
operType.value = "view"
},
enableForm() {
operType.value = "flow"
},
async initJobData() {
// 判断是否仅查看
if (props.currElTab.id) {
await orderVue.currElTabIsView(methods, props.currJob, props.currElTab.id, methods.handleUpdate)
}
setPropsDataValue(form, props.currJob, 'code', 'flowKey', 'flowInstId')
await onCascade(form);
form.flowNodeId = props.currJob.distFlowNodeId
// 判断待分配参与者节点ID
if (!form.flowNodeId) return
form.runNodeId = cascadeDic.runNodeId.find(f => form.flowNodeId === f.flowNodeId).id;
await cascadeChange('runNodeId', ['distRunJobId'])
// 动态加减签其中一个即可
runJobIdChange(cascadeDic.distRunJobId[0]?.id)
},
handleGetObj(form) {
// 查询已分配参与者
getByFlowInstId(form).then(response => {
let roleUserId = response.data.roleUserId
// 排除该节点非本人分配参与者(除查看)
roleUserId.forEach(f => {
let b = f.createUser !== userInfo.userInfos.user.userId;
if (b) f.isDisabled = true
})
form.roleUserId = roleUserId
if (validateNull(roleUserId)) return
onFormLoaded(dicData, roleUserId)
})
},
async handleUpdate() {
const valid = await dataFormRef.value.validate().catch(() => {
});
if (!valid) return false;
const validateRoleUser = await methods.validateRoleUser(form)
if (validateRoleUser) {
if (props.currElTab.id) {
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, emits)
}
return
}
try {
loading.value = true;
await saveByFlowInstId(form);
if (props.currElTab.id) {
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, emits)
}
useMessage().success("分配参与者成功");
} catch (err: any) {
useMessage().error(err.msg);
} finally {
loading.value = false;
}
},
// 校验分配数据
async validateRoleUser(row) {
if (validateNull(row.roleUserId)) return false
if (row.flowNodeId === props.currJob.flowNodeId) {
useMessage().error('待分配参与者节点不能是当前节点本身')
return true
}
// 分配参与者判断是否重复
if (methods.validateDupRoleId(row, 0, '人员')) return true
if (methods.validateDupRoleId(row, 1, '角色')) return true
if (methods.validateDupRoleId(row, 2, '岗位')) return true
if (methods.validateDupRoleId(row, 3, '部门')) return true
return false
},
// 分配参与者判断是否重复
validateDupRoleId(row, typeIndex, msg) {
let roleIds = row.roleUserId.filter(f => f.roleId && f.jobType === DIC_PROP.JOB_USER_TYPE[typeIndex].value).map(roleUser => {
return roleUser.roleId
})
if (new Set(roleIds).size !== roleIds.length) {
useMessage().info("分配的办理 " + msg + " 不能重复, 请重新选择")
return true
}
return false
},
onAddItem() {
if (props.currElTab.id) {
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, false)
}
let obj = {};
form.roleUserId.push(obj);
},
handleDelete(index: number, row: any) {
form.roleUserId.splice(index, 1)
}
}
// 监听双向绑定
watch(
() => props.currJob.id,
() => {
methods.initJobData();
}
);
onMounted(() => {
methods.initJobData()
});
</script>
<style lang="scss" scoped>
.el-dialog__footer {
text-align: center;
.dialog-footer {
text-align: center;
}
}
</style>