fix(detail): 评分 4 维度改走 /business/project/rate + manager_score 同步回写

P0 #1 修复: 评分之前写到 biz_project (错表), 4 维度 (scoreQuality/Speed/Coordination/Compliance) 实体无字段, mapper 无 <if>, Spring Boot Jackson 默认丢弃未知字段 — 全部失效。

改动:
- 后端 BizProjectController.rate: 同步聚合该项目所有 compliance 评分的 4 维度总分之平均, 写回 biz_project.manager_score (1 位小数, HALF_UP)。复用现有 selectList, 不动 mapper xml。
- 前端 ManagerProjectDetail.submitScore: 改调 POST /business/project/rate, body 用后端字段名 (qualityScore/responseScore/cooperationScore/complianceScore), raterRole='compliance' 跟原型"角色:合规"对齐。加 totalScore<4 校验。
- 附: _self/manager_projects_detail.md 11 章审查报告 (含本修复)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
郭庆泰
2026-08-20 23:59:20 +08:00
co-authored by Claude
parent 25be0d5d89
commit 99b9807270
3 changed files with 579 additions and 7 deletions
@@ -1,5 +1,7 @@
package com.ruoyi.business.controller;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
@@ -193,6 +195,8 @@ public class BizProjectController extends BaseController
* 通用评分 upsert (任何角色: sponsor / executor / compliance)
* POST /business/project/rate
* 不做可见性校验 — 评分公开
* 评分写入 biz_project_rating 后, 同步回写 biz_project.manager_score
* = 该项目所有 compliance 角色评分的 4 维度总分之平均 (decimal(3,1) 1 位小数)
*/
@Log(title = "项目评分", businessType = BusinessType.UPDATE)
@PostMapping("/rate")
@@ -206,9 +210,30 @@ public class BizProjectController extends BaseController
body.setCreateBy(SecurityUtils.getUsername());
body.setUpdateBy(SecurityUtils.getUsername());
int rows = bizProjectRatingService.upsertRating(body);
// 同步回写 biz_project.manager_score (仅 compliance 角色聚合)
if ("compliance".equals(body.getRaterRole())) {
BizProjectRating q = new BizProjectRating();
q.setProjectId(body.getProjectId());
q.setRaterRole("compliance");
List<BizProjectRating> all = bizProjectRatingService.selectList(q);
BigDecimal sum = BigDecimal.ZERO;
int cnt = 0;
for (BizProjectRating r : all) {
int s = safeLong(r.getQualityScore()) + safeLong(r.getResponseScore())
+ safeLong(r.getCooperationScore()) + safeLong(r.getComplianceScore());
if (s > 0) { sum = sum.add(BigDecimal.valueOf(s)); cnt++; }
}
BizProject p = new BizProject();
p.setProjectId(body.getProjectId());
p.setManagerScore(cnt == 0 ? null : sum.divide(BigDecimal.valueOf(cnt), 1, RoundingMode.HALF_UP));
bizProjectService.updateByPrimaryKey(p); // mapper `<if test="managerScore != null">` 仅更新这一列
}
return toAjax(rows);
}
private static long safeLong(Long v) { return v == null ? 0 : v; }
/**
* 查某项目的所有评分 (公开, 任何角色可读)
* GET /business/project/ratings?projectId=X