From b3d3ce4aaba5dd495d7d6288d3fb35da0d7604de Mon Sep 17 00:00:00 2001 From: wanghu Date: Sun, 20 Sep 2026 21:07:15 +0800 Subject: [PATCH] =?UTF-8?q?=E8=8E=B7=E5=8F=96=E4=BB=BB=E6=95=99=E7=8F=AD?= =?UTF-8?q?=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../homework/service/impl/RosterService.java | 170 ++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 src/main/java/com/yunhai/homework/service/impl/RosterService.java diff --git a/src/main/java/com/yunhai/homework/service/impl/RosterService.java b/src/main/java/com/yunhai/homework/service/impl/RosterService.java new file mode 100644 index 0000000..62ba227 --- /dev/null +++ b/src/main/java/com/yunhai/homework/service/impl/RosterService.java @@ -0,0 +1,170 @@ +package com.yunhai.homework.service.impl; + +import com.yunhai.homework.model.bsch.SchClassDto; +import com.yunhai.homework.model.bsch.SchInfoDto; +import com.yunhai.homework.model.bsch.SchStudentDto; +import com.yunhai.homework.service.IClassService; +import com.yunhai.homework.utils.UserContext; +import com.yunhai.platform.apistd.BizException; +import com.yunhai.platform.utils.exception.ErrorCode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 实时名册门面(bschclass 直连,无本地快照): + * 学生名单 GetClaArrStulist(按班级集合)、全校学生 GetSchStulist(学生端身份)、 + * 班级名 GetVClassList 映射、学校 GUID GetUserSchFirst。 + * 班级ID/学生ID 均为用户中心数字ID 域(classId 即 bschclass sch_class.class_id)。 + */ +@Service +public class RosterService { + + private static final Logger log = LoggerFactory.getLogger(RosterService.class); + + private final IClassService classService; + + public RosterService(IClassService classService) { + this.classService = classService; + } + + /** + * 名册条目:进度聚合/学生矩阵/提醒名单共用的 班级×学生 维度。 + */ + public static class RosterEntry { + public Integer studentId; + public String studentName; + public Integer classId; + public String className; + } + + /** + * 指定班级集合的在班学生(实时 bschclass GetClaArrStulist,一次批量外呼)。 + * 同班同学生去重;班级名经 GetVClassList 映射,缺失回退班级ID。 + */ + public List roster(List classIds) { + if (classIds == null || classIds.isEmpty()) { + return new ArrayList<>(); + } + Map names = classNames(classIds); + Map distinct = new LinkedHashMap<>(); + for (SchStudentDto s : classService.getClaArrStuList(classIds)) { + if (s == null || s.getStuId() == null || s.getClassId() == null || !classIds.contains(s.getClassId())) { + continue; + } + RosterEntry e = new RosterEntry(); + e.studentId = s.getStuId(); + e.studentName = s.getStuName(); + e.classId = s.getClassId(); + e.className = names.getOrDefault(s.getClassId(), String.valueOf(s.getClassId())); + distinct.putIfAbsent(s.getClassId() + ":" + s.getStuId(), e); + } + return new ArrayList<>(distinct.values()); + } + + /** + * 指定班级的在班学生数(一次批量外呼按班级分组计数;传入班级无学生计 0)。 + */ + public Map studentCounts(List classIds) { + Map counts = new LinkedHashMap<>(); + for (Integer classId : classIds == null ? Collections.emptyList() : classIds) { + counts.put(classId, 0); + } + for (RosterEntry e : roster(classIds)) { + counts.merge(e.classId, 1, Integer::sum); + } + return counts; + } + + /** + * 班级ID → 班级名(bschclass GetVClassList 映射)。 + * 远端不可用或无学校身份时降级为空映射,由调用方回退班级ID展示,不阻断名单本身。 + */ + public Map classNames(Collection classIds) { + Map names = new LinkedHashMap<>(); + if (classIds == null || classIds.isEmpty()) { + return names; + } + try { + String schSerId = currentSchSerId(); + if (schSerId == null) { + return names; + } + Set pending = new LinkedHashSet<>(classIds); + for (SchClassDto c : classService.getSchClassList(schSerId)) { + if (c != null && c.getClassId() != null && pending.remove(c.getClassId()) + && StringUtils.hasText(c.getClassName())) { + names.put(c.getClassId(), c.getClassName()); + } + } + } catch (BizException e) { + log.warn("[roster] 班级名称映射失败, 回退班级ID展示: {}", e.getMessage()); + } + return names; + } + + /** 班级ID → 班级名(单班便捷方法,缺失回退班级ID) */ + public String className(Integer classId) { + if (classId == null) { + return null; + } + String name = classNames(Collections.singletonList(classId)).get(classId); + return StringUtils.hasText(name) ? name : String.valueOf(classId); + } + + /** + * 当前登录学生所在班级条目(实时 bschclass 全校学生按登录人用户ID过滤)。 + * 学生ID = 登录人用户中心数字ID;一人多班各一条。 + * + * @throws BizException 未登录 / 无学校身份 / 未匹配到学生名册 + */ + public List mine() { + Integer userId = UserContext.getUserId(); + if (userId == null) { + throw new BizException(ErrorCode.FORBIDDEN, "未获取到登录身份"); + } + String schSerId = currentSchSerId(); + if (schSerId == null) { + throw new BizException(ErrorCode.FORBIDDEN, "未获取到学校身份"); + } + List mine = new ArrayList<>(); + for (SchStudentDto s : classService.getSchStuList(schSerId)) { + if (s != null && userId.equals(s.getStuId()) && s.getClassId() != null) { + RosterEntry e = new RosterEntry(); + e.studentId = s.getStuId(); + e.studentName = s.getStuName(); + e.classId = s.getClassId(); + mine.add(e); + } + } + if (mine.isEmpty()) { + throw new BizException(ErrorCode.FORBIDDEN, "当前用户未匹配到学生名册,请联系管理员确认班级名册"); + } + Map names = classNames(mine.stream().map(e -> e.classId).collect(Collectors.toSet())); + for (RosterEntry e : mine) { + e.className = names.getOrDefault(e.classId, String.valueOf(e.classId)); + } + return mine; + } + + /** 当前登录人学校的 bschclass GUID(无学校身份或上游未映射时返回 null) */ + private String currentSchSerId() { + Integer schId = UserContext.getSchId(); + if (schId == null) { + return null; + } + SchInfoDto sch = classService.getSchFirst(schId); + return sch == null ? null : sch.getSchSerId(); + } +}