阅读
build / build-push (push) Successful in 54s

This commit is contained in:
wanghu
2026-09-23 10:56:26 +08:00
parent 14b4e4c24f
commit 07c409c83c
4 changed files with 33 additions and 8 deletions
@@ -43,8 +43,14 @@ public class ActivityProgress {
/** 待处理回执(名额超额/待定),统计用,列表场景恒为 0 */
private int pendingReview;
/** 已读人数(fa_activity_read 班级粒度投影到学生,与详情 readnumcount 同口径) */
private int readCount;
/** 阅读率(readCount / should,四舍五入取整 %) */
private int readRate;
public ActivityProgress(int should, int signed, int confirmed, int canceled, int unsigned,
double signupRate, int quota, int usedQuota, boolean full) {
this(should, signed, confirmed, canceled, unsigned, signupRate, quota, usedQuota, full, 0);
this(should, signed, confirmed, canceled, unsigned, signupRate, quota, usedQuota, full, 0, 0, 0);
}
}
@@ -40,6 +40,9 @@ public class SignupBrief {
/** 是否已回执/已报名 */
private boolean hasReceipt;
/** 阅读状态:该生所在班是否已读(fa_activity_read 班级粒度投影) */
private boolean read;
/** 备注(如过敏史、随行人数说明) */
private String remark;
}
@@ -504,13 +504,21 @@ public class ActivityService implements IActivityService {
.collect(Collectors.toList());
Map<Integer, SchClassDto> classes = schoolClasses(schId);
// 已读统计:fa_activity_read 为班级粒度,投影到学生数并与接收班级求交(与详情 readnumcount 同口径);
// readClassIds 供名单行按"该生所在班是否已读"填充 read(与 SignupDetail 的 findRead 判定一致)
List<ActivityRead> reads = activityReadRepository.findByActivityId(serid);
Set<String> readClassIds = reads.stream()
.map(ActivityRead::getClassId)
.collect(Collectors.toSet());
Map<String, List<ActivitySignup>> byClass = filtered.stream()
.collect(Collectors.groupingBy(r -> r.getClassName() != null ? r.getClassName()
: classNameOf(classes, parseSafe(r.getClassId())), LinkedHashMap::new, Collectors.toList()));
List<SignupGroup> groups = byClass.entrySet().stream()
.map(e -> new SignupGroup(e.getKey(), e.getValue().stream()
.map(this::toBrief).collect(Collectors.toList())))
.map(r -> toBrief(r, readClassIds)).collect(Collectors.toList())))
.collect(Collectors.toList());
Map<Integer, List<SchStudentDto>> byClassStudents = studentsByClass(schId, targetClassIds(activity, classes));
@@ -518,6 +526,9 @@ public class ActivityService implements IActivityService {
if (should == 0 && !records.isEmpty()) {
should = records.size(); // 班级数据不可达时降级为回执表实有人数
}
int readCount = reads.stream()
.mapToInt(r -> byClassStudents.getOrDefault(parseSafe(r.getClassId()), Collections.emptyList()).size())
.sum();
SignupsResultVo vo = new SignupsResultVo();
vo.setActivityId(activity.getId());
@@ -532,7 +543,10 @@ public class ActivityService implements IActivityService {
ReceiptModeEnum mode = ReceiptModeEnum.of(activity.getReceiptMode());
vo.setReceiptMode(mode.getCode());
vo.setReceiptModeDesc(mode.getDesc());
vo.setSummary(computeProgress(activity, records, should));
ActivityProgress summary = computeProgress(activity, records, should);
summary.setReadCount(readCount);
summary.setReadRate(should > 0 ? (int) Math.round(readCount * 100.0 / should) : 0);
vo.setSummary(summary);
vo.setGroups(groups);
return vo;
}
@@ -1272,7 +1286,8 @@ public class ActivityService implements IActivityService {
boolean full = quota > 0 && usedQuota >= quota;
double rate = should > 0 ? Math.round((signed + confirmed) * 1000.0 / should) / 10.0 : 0;
int pending = quota > 0 ? Math.max(0, usedQuota - quota) : 0;
return new ActivityProgress(should, signed, confirmed, canceled, unsigned, rate, quota, usedQuota, full, pending);
// readCount/readRate 由调用方按 fa_activity_read 投影填充(如 Signups 汇总),此处缺省 0
return new ActivityProgress(should, signed, confirmed, canceled, unsigned, rate, quota, usedQuota, full, pending, 0, 0);
}
private int usedQuota(List<ActivitySignup> records) {
@@ -1591,7 +1606,7 @@ public class ActivityService implements IActivityService {
return vo;
}
private SignupBrief toBrief(ActivitySignup r) {
private SignupBrief toBrief(ActivitySignup r, Set<String> readClassIds) {
SignupBrief brief = new SignupBrief();
brief.setSignupId(r.getId());
brief.setStudentId(r.getStudentId());
@@ -1605,6 +1620,7 @@ public class ActivityService implements IActivityService {
brief.setSignedAt(fmt(r.getSignedAt()));
boolean receipt = !SignupStatusEnum.NONE.getCode().equalsIgnoreCase(r.getStatus());
brief.setHasReceipt(receipt);
brief.setRead(readClassIds.contains(r.getClassId()));
brief.setRemark(r.getRemark());
return brief;
}