项目背景和目标
高校推优(推荐优秀团员作为入党积极分子)工作长期依赖 Excel 和纸质材料,存在几个痛点:
评分口径不统一:不同班级、不同团支书对同一份文件的理解不同,算出来的分数不一致。
材料收集散乱:入党申请书、学习心得、活动证明分散在微信群、邮箱、纸质档案中,难汇总。
推优依据不透明:学生不知道自己的分数怎么来的,容易产生争议。
数据无法沉淀:每学期的推优数据难以跨期对比、难以追溯。
目标: 做一个面向高校党建推优场景的量化评分系统,把"分数怎么算"标准化、"材料怎么交"线上化、"评分依据"透明化。
软件功能
系统有四种角色:
角色 主要功能
学生 上传入党申请书、学习心得;查看自己的推优总分和分项明细
班级团支书 录入本班学生的思政课成绩、群众评议分、缺勤次数
教师 查看本学院排名、导出成绩数据
管理员 用户管理、班级填报解锁、数据中台同步、孤儿文件清理、审计日志
核心功能
推优总分自动计算:把"政治理论与表现(40 分)+ 实践与创新(30 分)+ 群众评议(30 分)"三部分,按规则自动算分。
数据中台积分同步:对接学校数据中台的积分认定接口,自动拉取学生的活动、获奖、志愿服务记录,作为评分的客观依据。
材料上传与管理:学生上传入党申请书、学习心得,后端用签名 URL 保护文件访问。
班级填报闭环:团支书录入班级数据,24 小时后锁定,管理员可解锁。
排名与导出:教师查看本班/本院排名,导出 CSV。
业务流程:
学生登录——上传材料——系统自动计算得分
团支书登录——录入班级数据——提交——24h锁定
管理员登录——同步数据中台——管理用户——解锁填报——导出数据
功能路径描述:
学生:登录 ——首页(查看总分和分项)——理论研学与思考(上传材料)——材料保存后自动重算分数
团支书:登录 ——录入成绩 ——选择班级 ——填写思政课成绩/群众评议/缺勤 ——24 小时内可修改
登录 ——首页(查看排名)——选择班级 ——查看排名 ——导出 CSV
登录 —— 管理首页 ——用户管理 / 班级填报管理 / 数据中台同步 / 孤儿文件清理 / 审计日志
整体架构:微信小程序通过 HTTPS 向 Nginx 发送请求,Nginx 进行 SSL 终止后将请求以 HTTP 转发给 Spring Boot 后端服务,Spring Boot 通过 JDBC 操作 MySQL 数据库,同时通过 HTTPS 调用学校数据中台的积分认定接口。
设计思路:
前后端分离:小程序只负责 UI 和交互,业务逻辑在后端。
数据中台作为客观数据源:学生的活动、获奖记录从中台拉取,避免手工录入。
本地缓存 + 定时同步:中台数据拉取后落库,学生查询读本地,减少对中台的实时压力。
文件签名 URL:上传文件不公开,用 HMAC 签名 URL 保护,2 小时有效。
异步任务 + 暂存表:全量同步用"暂存表 + 原子替换",同步中断不影响线上数据。
我负责的模块和结果
我负责全部模块:
后端:3 个 Controller、5 个 Service、4 个安全组件。
前端:15 个页面、14 个工具模块。
部署:Docker Compose 部署、Nginx 反代、MySQL 字符集迁移。
结果:
成功同步 549,418 条中台记录,与中台报告总数完全一致。
覆盖 24,396 名学生。
解决了 8 天无法成功同步的问题(根因是 token 过期处理不当 + 同步并发竞争)。
优化了批量导入:从 1.1 秒/人降到几秒完成 100 人。
修复了文件访问 403(Nginx 反代 + 签名 URL 主机错误)。
遇到的难点
难点 1:中台 token 过期导致整轮同步报废
现象: 定时同步经常失败,拉了 1058/1099 页就差 41 页,功亏一篑。
根因: 中台 token 有效期 2 小时,一轮同步要 27 分钟。token 过期时中台返回 HTTP 400(不是 HTTP 200 + 业务错误码),原代码没处理这种形态,异常穿透所有重试,整轮报废。
解决方案:
executeWithRetry 新增 HTTP 400 形态的 token 失效检测。
请求时动态取 token,重试时自动换新 token。
修复后,token 过期只造成单页重试(几秒),不报废整轮。
难点 2:Nginx 反代导致签名 URL 主机错误
现象: 学生上传的图片显示不出来,URL 是 http://127.0.0.1/api/files/access?...(80 端口,没有 :8080)。
根因: 后端生成签名 URL 时,取 request.getServerName() 和 getServerPort()。Nginx 反代把 Host 头改成 127.0.0.1,端口是 80,后端误判为"本地开发",生成了错误的主机。
解决方案:
后端加判断:如果是反代请求(有 X-Forwarded-* 头),用配置的公网域名