Files
geg-gas-web/src/components/SecondDev/OpinionDialogSelected.vue
‘huanghaiixia’ b36a9b2186 日期
2026-03-11 14:18:51 +08:00

381 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<a-modal :mask-closable="false" :title="dialogTitle" :visible="isOpen" :width="500" centered class="geg" @cancel="onClickCancel">
<template #footer>
<a-button :disabled="loading || isStart" @click="onClickCancel">{{ isStart ? '请注意流程已发起' : '取消' }}</a-button>
<a-button :loading="loading" type="primary" @click="onClickOK">确定</a-button>
</template>
<div class="dialog-wrap">
<a-form :label-col="{ span: 6 }" :model="formState" autocomplete="off">
<a-form-item v-if="_action === 'agree'" label="下一节点" name="nextNodeName">
<span>{{ getNextNodesName() }}</span>
</a-form-item>
<!--选择任意节点 start-->
<a-form-item v-if="_action === 'select'" label="审批节点" name="selectNextNodeName">
<a-select v-model:value="selected.taskId" :options="allTaskNodes" placeholder="请选择审批节点" :filterOption="search" :field-names="{ label: 'taskName', value: 'taskId' }" :disabled="editable"></a-select>
</a-form-item>
<a-form-item v-if="_action === 'select'" label="审批人">
<SelectUser :selectedIds="selected.userId" :multiple="selected.multiple" @change="getUserList" placeholder="请选择审核人">
<a-input v-model:value="selected.userName" placeholder="请选择审批人" :disabled="editable" />
</SelectUser>
</a-form-item>
<a-form-item v-if="_action === 'select' && selected.choseTime" label="审批时间">
<a-date-picker :inputReadOnly="true" show-time format="YYYY-MM-DD HH:mm:ss" placeholder="请选择时间" v-model:value="selected.time" @change="onChange" @ok="onOk" />
</a-form-item>
<!--选择任意节点 end-->
<template v-for="node in flowNextNodes">
<a-form-item v-if="_action === 'agree' && !isEnd" :label="flowNextNodes.length > 1 ? node.activityName + '审批人' : '审批人'">
<a-select
v-show="node.chooseAssign"
v-model:value="node.assignees"
:options="node.nextAssignees"
:placeholder="'请选择' + node.activityName + '的审批人'"
max-tag-count="responsive"
mode="multiple"
:filterOption="search"
></a-select>
<span v-show="!node.chooseAssign">{{ getAssigneeText(node) }}</span>
</a-form-item>
</template>
<a-form-item v-if="_action === 'reject'" label="退回至" name="rejectNode">
<a-select v-model:value="rejectNodeId">
<a-select-option v-for="(item, index) in rejectNodeList" :key="index" :value="item.activityId">{{ item.activityName }}</a-select-option>
</a-select>
</a-form-item>
<!--选择任意节点填写备注-->
<a-form-item v-if="_action === 'select'" :label="selected.choseTime ? '审批意见' : '备注'" name="selectOpinion">
<a-dropdown placement="bottom" v-if="selected.choseTime">
<a-button type="link" class="opinion-but">常用审批意见</a-button>
<template #overlay>
<a-menu>
<a-menu-item v-for="item in normalOpinionList" @click="clickMenu(item.text)">
<a href="javascript:;">{{ item.text }}</a>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
<a-textarea v-model:value="selected.opinion" :maxlength="200" :rows="3" style="margin-top: 35px" placeholder="请输入内容不超过200字" :rules="[{ required: true, message: '必须填写!' }]" />
</a-form-item>
<!--选择任意节点填写备注-->
<a-form-item v-if="_action != 'select'" label="审批意见" name="opinion" :rules="[{ required: true, message: '审批意见必须填写!' }]">
<a-dropdown placement="bottom">
<a-button type="link" class="opinion-but">常用审批意见</a-button>
<template #overlay>
<a-menu>
<a-menu-item v-for="item in normalOpinionList" @click="clickMenu(item.text)">
<a href="javascript:;">{{ item.text }}</a>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
<a-textarea v-model:value="formState.opinion" :maxlength="200" :rows="3" style="margin-top: 35px" placeholder="请输入审批意见不超过200字" />
</a-form-item>
</a-form>
</div>
</a-modal>
</template>
<script setup>
import { computed, reactive, ref } from 'vue';
import { getRejectNodeList } from '/@/api/workflow/task';
import { getUserMulti } from '/@/api/system/user';
import { SelectUser } from '/@/components/SelectOrganizational/index';
import { message, Dropdown } from 'ant-design-vue';
import dayjs, { Dayjs } from 'dayjs';
const aDropdown = Dropdown;
const dialogTitle = ref('审批');
const isOpen = ref(false);
const rejectNodeList = ref([]);
const rejectNodeId = ref('');
const loading = ref(false);
const isEnd = ref(false);
const isStart = ref(false);
let _action = ref('agree');
let _processId = '';
let _taskId = '';
let flowNextNodes = ref([]);
let allTaskNodes = ref([]);
let selectedNode = ref('');
let _callback = null;
let _onCancel = null;
const normalOpinionList = [
{
text: '请批准。'
},
{
text: '同意。'
},
{
text: '批准。'
},
{
text: '不同意。'
},
{
text: '请修改。'
}
];
const formState = reactive({
opinion: '',
opinionList: ['同意。', '请领导审批。']
});
function clickMenu(val) {
formState.opinion = val;
selected.opinion = val;
}
const selected = reactive({
taskId: '',
userId: [],
userName: '',
opinion: '',
selectedList: [],
time: '',
choseTime: false,
multiple: true
});
const editable = ref(false);
const taskName = computed(() => {
let name = allTaskNodes.value.map((ele) => {
if (ele.taskId === selected.taskId) {
return ele.taskName;
}
});
return name;
});
function getAssigneeText(node) {
// 注意这里用的是下拉框的数据结构 所以字段是value和label
return (node.nextAssignees || [])
.filter((item) => node.assignees.includes(item.value))
.map((item) => item.label)
.join('、');
}
function getNextNodesName() {
return flowNextNodes.value.length > 1 ? '多个并行节点' : flowNextNodes.value[0].activityName;
}
function toggleDialog({ isClose, isCreateFlow, action, callback, rejectCancel, processId, taskId, nextNodes, schemaId, choseTime, title, multiple, taskNode, edit, record } = {}) {
if (isClose) {
isOpen.value = false;
loading.value = false;
return;
}
isOpen.value = true;
_action.value = action;
_callback = callback;
_onCancel = rejectCancel;
_processId = processId;
_taskId = taskId;
flowNextNodes.value = nextNodes;
isStart.value = isCreateFlow;
formState.opinion = '';
dialogTitle.value = title ? title : '审批';
selected.choseTime = choseTime;
selected.multiple = multiple == false ? multiple : true;
editable.value = edit ? edit : false;
if (action === 'select') {
allTaskNodes.value = taskNode;
console.log(11111111111, taskNode);
console.log(22222222222, allTaskNodes);
}
if (taskId) selected.taskId = taskId;
if (record != null) {
console.log(record);
selected.selectedList = record.approveUserId;
selected.opinion = record.approveComment;
selected.time = dayjs(record.approveTime, 'YYYY-MM-DD HH:mm:ss');
selected.userName = record.approveUserName;
}
if (nextNodes && nextNodes.length) {
// 下一个节点唯一时(可能有并行节点)
const nNode = nextNodes[0];
//formState.nextNodeName = nNode.activityName;
isEnd.value = nNode.isEnd;
nextNodes.forEach((nNode) => {
if (!nNode.userList?.length) {
return;
}
const selected = [];
nNode.nextAssignees = nNode.userList.map((item) => {
if (item.checked || nNode.userList.length === 1) {
// 只有一个人的时候必须选他
selected.push(item['F_UserId']);
}
return {
value: item['F_UserId'],
label: item['F_RealName'],
item: item
};
});
nNode.assignees = selected;
if (!nNode.chooseAssign) {
// 不需要选审批人的时候 所有备选人都要放到下个节点
nNode.assignees = nNode.userList.map((item) => item['F_UserId']);
}
nNode.chooseAssign = nNode.chooseAssign;
});
flowNextNodes.value = nextNodes;
}
if (action === 'reject') {
loadRejectNodeList();
}
}
function search(inputValue, option) {
return inputValue ? option.item.F_Account.indexOf(inputValue) > -1 || option.item.F_RealName.indexOf(inputValue) > -1 : true;
}
async function loadRejectNodeList() {
rejectNodeId.value = '';
let res = await getRejectNodeList(_processId, _taskId);
if (res && Array.isArray(res) && res.length > 0) {
rejectNodeList.value = res;
dialogTitle.value = `退回`;
if (res?.length) {
res.forEach((nNode) => {
if (!nNode.userList?.length) {
return;
}
const selected = [];
nNode.nextAssignees = nNode.userList.map((item) => {
if (item.checked || nNode.userList.length === 1) {
// 只有一个人的时候必须选他
selected.push(item['F_UserId']);
}
return {
value: item['F_UserId'],
label: item['F_RealName'] + (item.remarks ? '(' + item.remarks + ')' : ''),
item: item
};
});
nNode.assignees = selected;
if (!nNode.chooseAssign) {
// 不需要选审批人的时候 所有备选人都要放到下个节点
nNode.assignees = nNode.userList.map((item) => item['F_UserId']);
}
nNode.chooseAssign = nNode.chooseAssign;
});
}
}
}
function onClickOK() {
if (_action.value === 'select') {
// if (!selected.choseTime) {
// if (selected.opinion === null || selected.opinion.trim() === '') {
// return message.error('请填写备注');
// }
// }
if (selected.opinion === null || selected.opinion.trim() === '') {
return message.error('请填写备注');
}
if (_callback && typeof _callback === 'function') {
_callback({
info: selected,
taskName: taskName
});
isOpen.value = false;
clearSelectVal();
} else {
isOpen.value = false;
}
} else {
const nextTaskUser = {};
if (_action.value === 'agree' && !isEnd.value) {
const isEmpty = flowNextNodes.value.find((node) => !node.assignees?.length);
if (isEmpty) {
return message.error('请选择审批人');
}
flowNextNodes.value.forEach((nNode) => {
nextTaskUser[nNode.activityId] = isEnd.value ? '' : nNode.assignees.join(',');
});
}
if (_action.value === 'reject') {
const isChoose = rejectNodeList.value.find((node) => node.activityId == rejectNodeId.value && node.assignees?.length);
if (!isChoose) {
return message.error('请选择审批人');
}
rejectNodeList.value.forEach((nNode) => {
if (nNode.activityId == rejectNodeId.value) {
nextTaskUser[nNode.activityId] = isEnd.value ? '' : nNode.assignees.join(',');
}
});
}
if (formState.opinion === null || formState.opinion.trim() === '') {
return message.error('请填写审批意见');
}
if (_callback && typeof _callback === 'function') {
loading.value = true;
_callback({
opinion: formState.opinion,
rejectNodeId: rejectNodeId.value,
nextTaskUser,
isEnd
});
} else {
isOpen.value = false;
}
}
}
function onClickCancel() {
clearSelectVal();
if (isStart.value) {
return;
}
if (_onCancel && typeof _onCancel === 'function') {
_onCancel();
}
isOpen.value = false;
}
function clearSelectVal() {
selected.taskId = '';
selected.userId = [];
selected.opinion = '';
selected.userName = '';
selected.time = null;
}
function stopLoading() {
loading.value = false;
}
async function getUserList(list) {
selected.selectedList = await getUserMulti(list.join(','));
selected.userName = selected.selectedList
.map((ele) => {
return ele.name;
})
.join(',');
}
defineExpose({
toggleDialog,
stopLoading,
clearSelectVal
});
</script>
<style lang="less" scoped>
.dialog-wrap {
padding: 10px 15px 0 0;
}
.opinion-but {
position: absolute;
top: 0;
right: 0;
}
</style>