diff --git a/src/views/gh/improvementProposal/components/ImprovementProposalBPMForm.vue b/src/views/gh/improvementProposal/components/ImprovementProposalBPMForm.vue index 31f7e73..2ff8be8 100644 --- a/src/views/gh/improvementProposal/components/ImprovementProposalBPMForm.vue +++ b/src/views/gh/improvementProposal/components/ImprovementProposalBPMForm.vue @@ -14,7 +14,7 @@ {{ proposal.proposalNo || '-' }} {{ proposal.proposalName || '-' }} {{ formatDate(proposal.proposalDate) }} - {{ proposal.proposalCategory || '-' }} + {{ proposal.proposalCategory_dictText || proposal.proposalCategory || '-' }} {{ proposal.proposalDeptName || '-' }} {{ proposal.applicantName || '-' }} {{ proposal.teamName || '-' }} @@ -239,6 +239,10 @@ +
+ 加权总分 + {{ weightedTotalPreview }} +
保存评分 评分已锁定,请重新提交流程办理 @@ -325,10 +329,18 @@ if (!currentScore.value) return '未保存'; return scoreLocked.value ? '评分已锁定' : '已保存,待流程提交'; }); - const effectAveragePreview = computed(() => { - const values = ['safetyScore', 'qualityScore', 'efficiencyScore', 'costScore'].map((key) => scoreForm.value[key]); - if (values.some((value) => value === undefined || value === null)) return '-'; - return (values.reduce((sum, value) => sum + Number(value), 0) / values.length).toFixed(2); + // 以前端“分”的整数计算,匹配服务端 BigDecimal 在改善效果和总分阶段的两次 HALF_UP 取整。 + const effectScoreCents = computed(() => calculateEffectScoreCents()); + const effectAveragePreview = computed(() => formatScoreCents(effectScoreCents.value)); + const weightedTotalPreview = computed(() => { + const effectCents = effectScoreCents.value; + const promotionCents = getScoreCents(scoreForm.value.promotionScore); + const originalityCents = getScoreCents(scoreForm.value.originalityScore); + const effortCents = getScoreCents(scoreForm.value.effortScore); + if (effectCents === null || promotionCents === null || originalityCents === null || effortCents === null) return '-'; + + const totalCents = Math.round(effectCents * 0.5 + promotionCents * 0.2 + originalityCents * 0.2 + effortCents * 0.1); + return formatScoreCents(totalCents); }); // 部门评分完成后必须以系统建议奖项为基准,不能回退到初审奖项。 const leaderAwardBase = computed(() => { @@ -532,6 +544,22 @@ }; } + function calculateEffectScoreCents(): number | null { + const values = ['safetyScore', 'qualityScore', 'efficiencyScore', 'costScore'].map((key) => getScoreCents(scoreForm.value[key])); + if (values.some((value) => value === null)) return null; + return Math.round((values as number[]).reduce((sum, value) => sum + value, 0) / values.length); + } + + function getScoreCents(value: unknown): number | null { + if (value === undefined || value === null || value === '') return null; + const score = Number(value); + return Number.isFinite(score) ? Math.round(score * 100) : null; + } + + function formatScoreCents(scoreCents: number | null): string { + return scoreCents === null ? '-' : (scoreCents / 100).toFixed(2); + } + function hasValidScoreValues() { return ['safetyScore', 'qualityScore', 'efficiencyScore', 'costScore', 'promotionScore', 'originalityScore', 'effortScore'].every((key) => { const value = scoreForm.value[key]; @@ -757,6 +785,28 @@ } } + .weighted-total-summary { + display: flex; + align-items: baseline; + justify-content: space-between; + gap: 12px; + margin-top: 16px; + padding: 14px 16px; + border-left: 4px solid #1677ff; + background: #e6f4ff; + color: #1f2937; + font-size: 16px; + font-weight: 700; + + strong { + flex: 0 0 auto; + color: #0958d9; + font-size: 28px; + font-weight: 700; + line-height: 1; + } + } + .score-form-actions { display: flex; align-items: center; @@ -888,6 +938,14 @@ gap: 2px; } + .weighted-total-summary { + padding: 12px; + + strong { + font-size: 24px; + } + } + .score-form-actions { justify-content: stretch;