yxk-20260729

改善提案
在 Task_improve004 增加所级评议人员选择。经办人选择 improve_suoleader 角色中的一人或多人后,通过通用“提交/办理”保存名单、初始化待投票记录,并写入流程变量 suoleadervotelist,供 Task_improve005 多实例任务使用。
This commit is contained in:
ye1023
2026-07-29 10:18:51 +08:00
parent f8290836f9
commit 8161e498bd
2 changed files with 68 additions and 8 deletions
@@ -21,6 +21,8 @@ enum Api {
bpmDeptScore = '/improvementproposal/improvementProposal/bpm/deptScore',
bpmSubmitDeptScore = '/improvementproposal/improvementProposal/bpm/submitDeptScore',
bpmLeaderAward = '/improvementproposal/improvementProposal/bpm/leaderAward',
bpmInstituteVoteCandidates = '/improvementproposal/improvementProposal/bpm/instituteVoteCandidates',
bpmInstituteVoteMembers = '/improvementproposal/improvementProposal/bpm/instituteVoteMembers',
bpmArchiveAward = '/improvementproposal/improvementProposal/bpm/archiveAward',
bpmInstituteVote = '/improvementproposal/improvementProposal/bpm/instituteVote',
}
@@ -109,5 +111,7 @@ export const queryMyDeptScore = (params) => defHttp.get({ url: Api.bpmMyDeptScor
export const saveDeptScore = (params) => defHttp.post({ url: Api.bpmDeptScore, params });
export const submitDeptScore = (params) => defHttp.post({ url: Api.bpmSubmitDeptScore, params });
export const saveLeaderAward = (params) => defHttp.post({ url: Api.bpmLeaderAward, params });
export const queryInstituteVoteCandidates = (params) => defHttp.get({ url: Api.bpmInstituteVoteCandidates, params });
export const saveInstituteVoteMembers = (params) => defHttp.post({ url: Api.bpmInstituteVoteMembers, params });
export const saveArchiveAward = (params) => defHttp.post({ url: Api.bpmArchiveAward, params });
export const castInstituteVote = (params) => defHttp.post({ url: Api.bpmInstituteVote, params });
@@ -72,9 +72,16 @@
</template>
<template v-if="isTask('Task_improve004')">
<a-form-item label="所级评议人员">
<a-table row-key="id" size="small" bordered :columns="voteMemberColumns" :data-source="voteRows" :pagination="false" />
<div class="form-help">所级评议人员选择和投票记录初始化将在后续功能中接入</div>
<a-form-item label="负责人确认奖项">{{ awardLabel(proposal.leaderFinalAward) }}</a-form-item>
<a-form-item label="所级评议人员" required>
<a-checkbox-group v-model:value="selectedInstituteVoterIds" class="vote-member-grid">
<a-checkbox v-for="member in instituteVoteCandidates" :key="member.id" :value="member.id" class="vote-member-option">
<span class="vote-member-name">{{ member.realname || member.username }}</span>
<span class="vote-member-username">{{ member.username }}</span>
</a-checkbox>
</a-checkbox-group>
<div v-if="!instituteVoteCandidates.length" class="form-help">未查询到所级评议小组人员</div>
<div v-else class="form-help">请选择本次所级评议投票人员提交办理后将生成对应投票待办</div>
</a-form-item>
</template>
@@ -173,11 +180,13 @@
import {
castInstituteVote,
queryDataById,
queryInstituteVoteCandidates,
queryImprovementInstituteVoteListByMainId,
queryMyDeptScore,
saveArchiveAward,
saveDeptScore,
saveInitialReview,
saveInstituteVoteMembers,
saveLeaderAward,
submitDeptScore,
} from '../ImprovementProposal.api';
@@ -197,6 +206,8 @@
const proposal = ref<Recordable>({});
const currentScore = ref<Recordable | null>(null);
const voteRows = ref<Recordable[]>([]);
const instituteVoteCandidates = ref<Recordable[]>([]);
const selectedInstituteVoterIds = ref<string[]>([]);
const initialAward = ref('');
const leaderFinalAward = ref('');
const finalAward = ref('');
@@ -210,11 +221,6 @@
{ value: '2', label: '铜奖' },
{ value: '3', label: '参与奖' },
];
const voteMemberColumns = [
{ title: '评委', dataIndex: 'voterName', width: 180 },
{ title: '状态', dataIndex: 'voteStatus', width: 120 },
];
// 流程引擎在运行待办中提供 taskDefKey,节点功能只依赖该稳定标识而非表单 URL 参数。
const processInfo = computed(() => ({
mainId: props.formData?.processDataId || props.formData?.dataId,
@@ -263,6 +269,8 @@
proposal.value = {};
currentScore.value = null;
voteRows.value = [];
instituteVoteCandidates.value = [];
selectedInstituteVoterIds.value = [];
return;
}
loading.value = true;
@@ -280,6 +288,17 @@
initialAward.value = proposal.value.initialAward || '';
leaderFinalAward.value = proposal.value.leaderFinalAward || '';
finalAward.value = proposal.value.finalAward || '';
if (isTask('Task_improve004') && processInfo.value.processInstanceId && processInfo.value.taskId) {
instituteVoteCandidates.value = await queryInstituteVoteCandidates(processInfo.value);
const candidateIds = new Set(instituteVoteCandidates.value.map((item) => String(item.id)));
// 流程提交失败后重新打开 Task4 时,回显本次尚未流转的有效名单。
selectedInstituteVoterIds.value = voteRows.value
.map((item) => String(item.voterId))
.filter((voterId) => candidateIds.has(voterId));
} else {
instituteVoteCandidates.value = [];
selectedInstituteVoterIds.value = [];
}
} catch (error) {
createMessage.warning('提案数据加载失败');
} finally {
@@ -323,6 +342,13 @@
}
await saveLeaderAward(actionPayload({ leaderFinalAward: leaderFinalAward.value }));
}
if (isTask('Task_improve004')) {
if (!selectedInstituteVoterIds.value.length) {
createMessage.warning('请至少选择一名所级评议人员');
return false;
}
await saveInstituteVoteMembers(actionPayload({ voterIds: selectedInstituteVoterIds.value }));
}
if (isTask('Task_improve005') && currentVote.value?.voteStatus !== 'voted') {
createMessage.warning('请先完成投票');
return false;
@@ -477,6 +503,36 @@
margin-bottom: 16px;
}
.vote-member-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 10px 12px;
width: 100%;
}
.vote-member-option {
display: flex;
align-items: center;
min-height: 42px;
margin-inline-start: 0;
padding: 8px 10px;
border: 1px solid #d9e2ec;
border-radius: 4px;
background: #fff;
}
.vote-member-name {
margin-left: 6px;
color: #1f2937;
font-weight: 500;
}
.vote-member-username {
margin-left: 6px;
color: #64748b;
font-size: 12px;
}
@media (max-width: 768px) {
.attachment-grid {
grid-template-columns: 1fr;