双11狂欢大促

盲盒赢 定制羽绒服

开启惊喜盲盒,抽取你的专属好礼

— 惊喜奖品抢先看 —

历阶——LLM结合探索CodeArts团队实战总结

历阶 历阶 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
这个作业属于哪个课程202601福大-软件工程实践-W班
这个作业要求在哪里LLM结合探索CodeArts团队实战总结
本文对应LLM结合探索CodeArts团队实战总结、对 冲刺总结随笔 中老师、同学提问的重新回答与后续行动计划
其他参考文献《构建之法》

补充说明:本系统共 10 个种子账号, 统一密码均为123456 :

角色用户名姓名说明
大会主席(CONFERENCE_CHAIR)chair李建国大会级管理看板
秘书(SECRETARY)sec01王敏参会者名单查看/导出、发布大会级通知
分论坛主席(FORUM_CHAIR)chair01刘亚彬管辖 SP-025(id=4005)
分论坛主席(FORUM_CHAIR)chair02茹炳晟管辖 SP-026(id=4012)
分论坛主席(FORUM_CHAIR)chair03魏哲巍管辖 SP-080(id=4006)
参会者(ATTENDEE)zhang张明主测试账号,已有报名记录
参会者(ATTENDEE)li李晓雨—
参会者(ATTENDEE)zhou周航—
参会者(ATTENDEE)sun孙悦—
参会者(ATTENDEE)wu吴迪—

目录

  • 第一部分——项目内容
  • 1、项目CodeArts地址以及项目部署的在线地址
  • 2、组员职责分工
  • 3、提交日志次数与截图
  • 4、程序运行截图
  • 5、遇到的困难及解决方法
  • 6、组员贡献度
  • 7、PSP表
  • 第二部分——Alpha 冲刺答辩问题回应与后续行动
  • 1、重新回答:为什么选 qwen-flash + text-embedding-v3
  • 2、对冲刺总结博客三个提问的回应
  • 3、老师总结的四点启发 → 具体行动
  • 4、Beta 行动清单汇总
  • 项目的具体实现
  • 1、GUI界面
  • 2、基础功能实现
  • 3、LLM功能实现
  • 4、AI Coding过程
  • 5、数据库设计
  • 6、用户体验
  • 7、项目部署
  • 附件功能
  • 1、多语言支持
  • 2、个人参会日程与时间冲突检测

第一部分——项目内容

1、项目CodeArts地址以及项目部署的在线地址

项目CodeArts地址:项目地址
项目部署的在线地址:部署链接

2、组员职责分工

序号成员角色负责范围
1周蔚琳队长 / 架构仓库搭建、分支策略、接口契约(OpenAPI)、部署、最终联调
2柳钰舒后端 A认证(注册/登录/JWT/角色)、报名/修改/取消、推送
3郑聪凌后端 B论坛 CRUD、参会人数统计、通知发布、秘书查看参会者
4刘锐清前端 A参会者端:论坛列表、论坛详情+报名、布局与路由
5黄奕前端 B我的报名(改/取消/冲突)、智能推荐页、多语言
6汤文琪前端 C管理端:会议主席看板、分论坛主席看板+发通知、秘书列表
7刘嘉奕数据 & 算法ER 图、建表 SQL、种子数据、日程冲突检测算法
8林彩华文档 & QA前后端联调、AI Coding 记录、博客、测试

3、提交日志次数与截图

成员Commit 次数
周蔚琳5
柳钰舒21
郑聪凌27
刘锐清14
黄奕27
汤文琪15
刘嘉奕16
林彩华5
合计130

以下,我们将分成员提供各自的commit日志截图。
周蔚琳:

img

柳钰舒:

img


img

郑聪凌:

img


img

刘锐清:

img

黄奕:

img


img

汤文琪:

img

刘嘉奕 :

img

林彩华:

img

4、程序运行截图

以下截图均来自线上部署链接,展示系统核心功能的真实运行状态。

1. 用户登录:所有角色通过统一登录页认证;登录后系统按账号角色显示对应的功能入口,参会者无法进入管理端页面(路由守卫拦截)。
登录前页面:

img

登录后页面(以参会者视角):

img

2. 分论坛列表:展示全部 170 场分论坛的议题、主讲、时间、地点,支持分页浏览。

img

3. 论坛报名:参会者在论坛详情页一键报名,可随时取消报名。

img

4. 智能推荐(LLM):参会者用自然语言描述兴趣(如"我对大模型和软件工程交叉方向感兴趣"),系统调用大模型返回匹配的分论坛及推荐理由、匹配度。

img

5. 主席发布通知:分论坛主席登录后在其看板选择分管论坛,发布通知。

img

6. 参会者接收通知:报名该论坛的参会者在"我的通知"中实时收到上述通知。

通知内容与第 5 条主席发布的通知一致,形成发布—接收闭环

img

7. 秘书视角:秘书可查看全部参会者名单及大会整体报名统计。

img

8. 多语言支持:界面支持简/繁中文、英、德、日五种语言一键切换。

img

5、遇到的困难及解决方法

  • 周蔚琳

    困难 1:8 人并行开发导致的分支合并冲突

    困难:8 个人各自从 dev 拉 feat-* 分支后并行开发,但各分支的 base 都停留在早期提交,而 dev 已经向前推进了数十个提交。多个共同文件会真实冲突:README.md 签到互相覆盖、requirements.txt 两边都改、frontend/package.json 版本不一致、vite.config.js 代理端口一个写 8000、一个写 8080。

    解决:先做无副作用的合并预演,用 git merge-tree --write-tree --name-only 把每个分支与 dev 的真实冲突文件、冲突位置一次性摸清,再排定合并顺序:无依赖/冲突小的先进,被依赖的先进。并对每个冲突文件明确「保留哪个版本」,关键的契约更新由队长亲自串行合并并 push,未出现一次污染 dev 的事故。

    收获:多人并行开发时,冲突不可怕,失控的冲突才可怕——用工具预演代替手工撞车、用明确的取舍规则代替各自为战,是保证共享分支干净的关键。

    困难 2:组员原定技术栈与已定 schema 自相矛盾

    困难:组员发来的技术栈写着「HTTP 层用标准库 http.server、数据访问用 sqlite3」,但数据算法岗已经写好的 db/schema.sql 全是 MySQL 8.0 语法,sqlite3 根本跑不了这套;而 http.server 手写 17 个接口 + JWT + 参数校验,工作量过大。

    解决:及时拍板并同步全员:统一 MySQL + 升级 FastAPI,决策理由写进 docs/architecture.md 决策记录。事后验证这是正确的——后端 A/B 得以直接按契约写路由,没有在自研框架上浪费时间。

    收获:技术选型出现矛盾时要尽早拍板并把决策理由留痕,让全组基于同一份架构假设开发,避免在错误的路上各走各的。

  • 柳钰舒

    困难 1:数据同学交付后,10 个种子账号全部登不上

    困难:接上真实数据库,zhang/123456 登录返回 401,但密码确实是 123456。定位发现:种子数据的 password_hash 是 Werkzeug 格式,自己实现的是另一种格式,两种格式互不识别,校验函数一律返回 False。

    解决:哈希校验改成双格式分支,按前缀判断;迭代次数从哈希串里解析,不写死。同时加了一条测试:拿真实的 Werkzeug 哈希串验证能通过,避免以后有人"优化"掉这个分支。

    收获:模块间约定好的数据格式,实现时必须以对方的实际交付物为准,接口处要有真实样例的测试守住兼容性——"我实现的格式"不等于"对方给的格式"。

    困难 2:取消报名后再报,接口返回 201 但没报上

    困难:取消某论坛后重新报名,接口 201,响应里也有这个论坛,但刷新页面就没了。定位发现:取消报名的实现把 status 改成 cancelled 保留行,重报时撞唯一键,INSERT OR IGNORE 静默忽略,接口继续返回成功。

    解决:改成软删除 + 复活语义,ON CONFLICT DO UPDATE ... WHERE status='cancelled'。那个 WHERE 是关键:已报名时条件不成立,rowcount 保持 0,才能区分"新增"和"已存在"。

    收获:"静默失败"比报错更危险——接口返回成功不代表数据真的写进去了,写入逻辑的每个分支都要有对应的测试用例守着。

  • 郑聪凌

    困难 1:云端后端容器启动但登录接口 404

    困难:前端登录页访问 /api/auth/login 返回 404,论坛列表接口却能返回 200。原因是容器只运行了后端 B 的 app.main:app,没有复制或加载 backend/ 下的后端 A。

    解决:让 app.main 以现有后端 A 应用为基础,再挂载后端 B 的论坛、通知、管理和日程路由;Dockerfile 增加 COPY backend ./backend。

    收获:容器"启动成功"只说明进程活着,不说明功能完整——部署后要按接口清单逐个验证,而不是只看容器状态。

    困难 2:前端 8080 页面可访问但 API 曾返回 502

    困难:页面端口 8080 已打开,但部分请求无法转发。定位确认:8080:80 只是公网端口映射,nginx 容器内部仍监听 80;真正的 API 代理应为 backend:8000。

    解决:检查 nginx 配置的 location /api/ 反向代理,确认后端容器实际监听 0.0.0.0:8000,页面恢复正常访问。

    收获:排查部署问题要分清"端口映射"和"服务代理"两层——页面能开只证明静态资源链路通,API 链路要单独验证。

  • 刘锐清

    困难 1:Git 分支管理与合并冲突

    困难:①误在 dev 分支直接 commit,违反分支规则;②和汤文琪同时改了 frontendC.js 路由文件;③package.json vite 版本和架构定稿不一致(6.0 vs 5.2)。

    解决:①用 reflog 找回 commit,cherry-pick 到 feat 分支,再 reset dev;②明确路由文件归属:frontendA/B/C.js 各归一人,A 只在 index.js 统一注册;③vite 从 6.0 降到 5.2,对齐架构定稿。

    收获:分支规则的意义在于明确"谁在哪条分支上改什么文件",文件归属清楚了,冲突自然就少了。

    困难 2:cherry-pick 静默失败

    困难:cherry-pick 命令 exit code 是 0,看起来成功了,但 push 后核对远程发现 commit 根本没过去。

    解决:每次 cherry-pick 后立刻 git log --oneline 验证本地,再 push,最后 git ls-remote 确认远程状态。

    收获:命令执行成功不等于操作目的达成,git 的每一步都要用 log/ls-remote 这类"读操作"验证实际效果,形成本地—远程两头核对的习惯。

  • 黄奕

    困难 1:git 冲突标记被带进仓库,推荐页编译直接报错

    困难:队友提交把 git 冲突标记(<<<<<<< Updated upstream / ======= / >>>>>>> Stashed changes)带进了 Recommend.vue,/recommend 页面 vite 编译报 Unexpected token,页面打不开。

    解决:定位到 import 区域的冲突标记,按下游引用保留正确版本,删除冲突标记,编译通过并 commit + push + 合并。

    收获:多人并行开发时,合并前要检查冲突残留;遇到编译报错先看文件里有没有冲突标记这种"低级但致命"的问题。

    困难 2:统计口径矛盾:参会 30 人却报 1203 人次

    困难:会议主席看板上「参会人数 30」与「报名总人次 1203」同时出现,明显矛盾,答辩会被直接问住。

    解决:根因是 mock 里每场论坛的 attendeeCount 是硬编码的,与参会者注册表脱节。改为按真实报名关系统计,列表/详情/统计三处用同一个函数,报名后人数 +1 可演示。

    收获:用数据对账找 bug——单看页面渲染不出来,只有把 mock 数据、统计口径、展示数字放一起算才暴露;前端要关心「渲染出来的数字对不对」,而不只是「能不能渲染」。

  • 汤文琪

    困难 1:管理看板三看板开发

    困难:三个看板(会议主席/分论坛主席/秘书)组织方式不确定:单 /admin 入口按角色分发,还是拆三个独立路由。

    解决:拍板单入口:/admin 按 auth/me.role 内部分发三看板,路由守卫只守「是否管理角色」一层,后续加看板不用动路由表,导航也只需暴露一个管理入口。

    收获:路由设计先想扩展性——按"角色"这一维度收敛入口,比按"页面"平铺路由更能适应后续变化。

    困难 2:Vite 缓存脏

    困难:拉 dev / 切分支后 dev server 报 Failed to resolve import @/api/request.js,但文件实际都在。

    解决:重启 dev server 清缓存解决,不动代码(多人协作仓库常见)。

    收获:多人协作仓库里"报错说文件不存在但文件明明在"这类灵异问题,先重启工具清缓存再怀疑代码,能省大量排查时间。

  • 刘嘉奕

    困难 1:MySQL 实例中文路径导致启动失败

    困难:自建 MySQL 实例启动后立刻退出,错误日志只有一行,没有任何报错信息。逐次排查后发现:数据目录路径含中文时,mysqld 在 Windows 上初始化数据目录时用 ANSI 代码页处理路径,中文被转成乱码,后续文件读写全部失败,而错误被静默吞掉。

    解决:数据目录改到纯英文路径,实例正常启动。

    收获:开发环境尽量使用纯英文路径——不少基础软件对中文路径的处理存在隐性问题,且失败往往被静默吞掉,极难定位。

    困难 2:交付物本地能跑不等于团队能跑

    困难:组长反馈重灌数据库后,多语言接口不生效。定位发现:init_db.py 的执行链只跑了 schema + 种子数据三步,多语言建表和译文要手工补。本地是因为手工执行过,团队重灌走脚本就漏了。

    解决:执行链补到 7 步,全部默认执行;同时加了硬断言——译文行数、触发器存在性不对就当场报错,不再静默降级。

    收获:交付脚本要按"别人从零跑通"的标准写,而不是"我本地能跑"——手工步骤必须脚本化,脚本必须有结果断言。

  • 林彩华

    困难 1:前端请求入口唯一,接口却分散在两个后端

    困难:项目由两个独立的后端服务组成(后端 A 负责认证/报名/推荐,后端 B 负责论坛/统计/通知),而前端所有请求统一走 /api 一个入口转发到 8000 端口。联调时发现论坛列表、大会统计等页面全部报 404——这些接口实际在 8001 端口的后端 B 上,前端却把请求发给了后端 A。

    解决:在 vite.config.js 中按路径前缀配置代理分流:论坛、统计、日程、通知发布类请求转发至 8001,认证、报名、推荐类请求保持 8000,其余路径兜底回落。配置时特别注意规则的声明顺序——/api/notices/mine 与 /api/notices 前缀重叠,必须把更精确的规则写在前面,否则会被宽泛规则抢先匹配到错误的后端。

    收获:理解了生产环境中"单一入口 + 反向代理分流"的通用架构模式;nginx 的 location 分发与本方案原理一致,本地代理配置与线上部署得以保持同构。

    困难 2:双后端数据源不一致,报名写操作全部失败

    困难:这是本次联调暴露的最隐蔽问题。后端 A 此前以内存模式运行(数据为种子数据),后端 B 连接 MySQL(170 场真实论坛数据)。用户在论坛页报名时,报名请求走后端 A,而后端 A 的内存库中查无此论坛,导致报名、修改报名全部失败。该问题在接口逐个测试时未暴露,直至走通"浏览论坛 → 点击报名"完整业务流程才浮现。

    解决:将后端 A 切换为 MySQL 模式,使两个后端共享同一数据库,读写路径一致。切换后完整回归:报名、修改、取消、冲突检测、LLM 推荐全部通过。

    收获:接口级联调通过不等于系统可用——"数据一致性"必须在业务流程层面验证;多个服务共享状态的场景下,存储必须收敛到同一数据源。

6、组员贡献度

成员贡献度评估依据
柳钰舒14后端 A 全链路:认证/报名/推送 + 数据访问层 + 契约测试 + LLM 推荐多语言适配,测试覆盖完整,工程完整度最高
郑聪凌14后端 B 四大模块(论坛 CRUD、人数统计、通知发布、秘书查看)+ 双后端集成入口拼装与部署排查
黄奕13前端工作量最大:我的报名(改/取消/冲突)、智能推荐页、五语言国际化
周蔚琳12项目骨架级贡献:仓库搭建、分支策略、OpenAPI 接口契约、云端部署、八人分支合并治理、最终联调收口,是全组并行开发的前提
汤文琪12管理端三看板(会议主席/分论坛主席/秘书),角色逻辑与页面复杂度最重的前端模块
刘嘉奕12数据与算法:ER 图、建表 SQL、170 场种子数据、冲突检测算法 + 初始化脚本硬断言,交付质量高
林彩华12测试、联调与质量:双后端代理分流、数据源不一致等关键问题的定位修复、博客
刘锐清11参会者端核心链路:论坛列表、论坛详情+报名、布局与路由骨架

7、PSP表

以下按分工顺序列出每位组员的 PSP 表格。各成员岗位性质不同,表格列结构与时间单位(分钟/小时)以个人记录为准。

周蔚琳(队长 / 架构)

队长的产出以架构设计、接口契约、部署骨架文档与 YAML 为主,「编码」对应编写 YAML / 文档 / 脚本,「测试」对应语法校验与合并预演。

阶段计划时间(min)实际时间(min)
计划(需求理解、分工对齐)3040
设计(接口契约设计、架构选型、目录骨架)90120
编码(写 api.md / openapi.yaml / architecture.md / docker-compose / Dockerfile / CONTRIBUTING)120150
测试(YAML 语法校验、合并冲突预演、契约一致性检查)4060
后置处理(契约迭代更新、合并协调、文档同步)6080
合计340450

柳钰舒(后端 A)

阶段具体任务计划实际偏差原因
计划读题、拆解后端 A + LLM 工作量,梳理 8 个接口边界0.3 h0.5 h漏算博客材料收集成本;契约 v1.0 变更后重做一次
设计领域模型 + 端口/适配器分层0.3 h0.5 h多花了契约隔离层的设计,后期迁移省回来
设计LLM 提示词 + 输出 Schema + 降级链路0.3 h0.5 h提示词改三版才稳定
设计表结构与接口字段边界核对0.3 h0.4 h与数据同学对了三轮口径
编码认证(注册/登录/JWT/me)0.6 h0.8 h兼容 Werkzeug 哈希格式,多一轮
编码报名(追加/替换/取消/复活)0.4 h0.7 h软删除的三种情形要分开处理
编码通知三路并集0.2 h0.2 h—
编码LLM 推荐(提示词/校验/兜底/降级)0.6 h0.8 h括号配平提取器返工
编码契约映射与 FastAPI 路由0.6 h0.7 h422→400 转换与断连兜底
编码MySQL 适配器0.4 h0.5 hNOT IN () 空集合语法错
测试190 个用例 + 契约校验器0.5 h0.7 h校验器抓出两处真实偏差,很值
对接与数据同学对齐表结构、与前端对齐五语言字段0.3 h0.4 h字段口径对了两轮
文档契约对照表、验收手册、博客素材0.2 h0.3 h困难条目从 5 条扩到 7 条
合计5.0 h7.0 h超 2.0 h

郑聪凌(后端 B)

序号工作项计划时间(小时)实际时间(小时)偏差说明
1阅读接口契约、分工文档和部署架构0.50.6需要同时核对后端 B、后端 A 和前端请求路径
2论坛、场地、通知多语言查询1.01.5发现重复列名覆盖译文后进行了二次修正
3个人日程多语言及可选表回退0.50.8需要处理 forum_i18n 缺失时的兼容路径
4统计 SQL、数据映射和接口测试0.81.0增加了真实 MySQL 数据验证
5数据库导出、导入和多语言数据校验0.61.2处理重复主键、触发器导入和真实数据迁移
6前后端代理联调0.50.8处理 8080、nginx、Docker 和后端容器问题
7后端 A+B 统一部署入口0.50.8发现原入口未加载后端 A,需要改镜像和应用装配
8Git 分支提交、合并和文档整理0.50.6按功能提交,并保留合并记录
合计4.47.3实际投入增加主要来自部署和数据库联调

刘锐清(前端 A)

阶段计划时间(min)实际时间(min)注入缺陷移除缺陷剩余缺陷
计划(Plan)1015000
设计(Design)2025110
编码(Code)200180550
代码审查(Code Review)2035010
测试(Test)1530010
事后总结(Postmortem)510000
合计270295680

黄奕(前端 B)

阶段具体内容计划时间(h)实际时间(h)说明
计划阅读作业要求、拆分任务、前端统一约定(91 条契约)、确定多语言方案与换场交互0.50.5方案讨论多轮
设计五语言 key 结构、forumI18n.js 取值兼容层、译文存库方案、换场弹窗交互、分页/导出公共工具设计11.5内容译文方案从「加字段」改到「存库」反复论证
编码五语言接入、我的报名(筛选/修改/换场/取消/冲突提示)、推荐页(报名/取消闭环)、论坛内容多语言 8 页接入、mock 数据对齐 seed、分页与 CSV 工具34页面多、跨 A/C 页面,反复改文案与样式
编译调试编译修复、git 冲突标记清除、裸 key 溯源、CSS 变量修复、check:i18n 白名单、mock 错位排查11.5排错类工作集中在这部分
测试/验证五语言逐页验证、mock 数据口径对账、build 与 check:i18n 全绿、配合后端验证接口11口径对账占大头
总结博客素材整理、个人记录文档、与团队的方案说明0.51—
合计—79.5实际比计划多 2.5 小时,主要超在排错与跨页数据对齐

汤文琪(前端 C)

阶段计划时间(min)实际时间(min)注入缺陷移除缺陷剩余缺陷
计划(Plan)1520000
设计(Design)4050110
编码(Code)300360550
代码审查(Code Review)2030010
测试(Test)4060110
事后总结(Postmortem)1015000
合计425535780

刘嘉奕(数据 & 算法)

阶段具体任务计划实际偏差原因
计划读题、梳理字段口径与角色枚举0.2 h0.4 h角色枚举前后改了三版,多核了一轮
设计ER 图 + 表结构设计0.3 h0.4 h照接口文档倒推,联系比预想的少
编码schema.sql(建表 + 索引 + 外键)0.2 h0.3 hER 定完直接照着写,一遍过
编码种子数据(170 场官方真实论坛)0.2 h0.5 h数据包是另一套字段名,另写了个转换脚本
编码冲突检测算法 + 单元测试0.3 h0.7 h紧邻分档改两轮,补了 5 个边界用例
编码37 条业务查询0.3 h0.5 h% 占位符与 ONLY_FULL_GROUP_BY 各卡一次
编码多语言旁表 + 译文入库0.3 h0.8 h翻译接口全不通,改 LLM 逐批翻,繁简又查一轮
测试查询真跑 + 约束拦截验证0.2 h0.3 h脚本一次跑通,但抓出 2 个运行期 bug
对接与后端/前端对齐接口字段0.2 h0.2 h契约已定,只对了一遍字段表
文档ER 图、数据字典、博客素材0.2 h0.4 h—
合计2.4 h4.5 h超在要跟外部对齐的五步,省在照图施工的三步

林彩华(文档 & QA)

PSP 2.1Personal Software Process Stages计划时间(min)实际时间(min)偏差原因
Planning计划1520联调前需先摸清双后端架构与启动方式,多估了一轮
· Estimate· 估计这个任务需要多少时间1520同上
Development开发330390超支集中在联调排查与回归测试
· Analysis· 需求分析(分析作业评分表,明确文档与 QA 交付项及联调验收口径)2530评分点逐条核对,验收口径需与两位后端确认
· Design Spec· 生成设计文档(博客骨架、AI Coding 记录模板、PSP 表模板)3035模板字段需覆盖全部评分点,与组长对了两轮
· Design Review· 设计复审(核对模板字段是否覆盖全部评分点)1010—
· Coding Standard· 代码规范(截图命名规则、记录填写格式、文档目录结构)1010沿用团队既有约定,仅补截图命名
· Design· 具体设计(回归测试清单结构、联调环境方案:端口 / 代理 / 数据库配置规划)2535双后端端口与代理分流方案需先排查验证再定
· Coding· 具体编码(vite 代理分流配置、.env.local 环境修正、JWT 统一与数据源收敛修复、test-case.md、AI Coding 记录与博客正文)150175分流规则前缀重叠返工一次,数据源不一致问题定位耗时
· Code Review· 代码复审(博客与评分表逐项对应,材料齐全性核对commit 截图、运行截图)4540材料随做随收,集中核对一遍通过
· Test· 测试(按回归清单执行完整用户流程验证,记录 bug 与修复情况)3555全流程验证暴露数据源不一致与权限 403,回归多轮
Reporting报告9070测试结论已随测试记录成型,整理成本低于预估
· Test Report· 测试报告(整理测试结论写入博客)2015—
· Size Measurement· 计算工作量以及截图(统计各成员 commit 次数、贡献比例表)3045按 git author 脚本统计,一次完成
· Postmortem & Process Improvement Plan· 事后总结,并提出过程改进计划(随笔第二部分:新思考与具体行动)5540困难条目已在个人总结中沉淀,汇总即可
合计450495实际超 45 分钟,超在联调排查与全流程回归,省在文档复审与统计

第二部分——Alpha 冲刺答辩问题回应与后续行动

1、重新回答:为什么选 qwen-flash + text-embedding-v3

答辩时老师问我们「为什么选 qwen-flash 和 text-embedding-v3 这两个模型」,当时答得偏「顺手选的」。这里从项目功能需求、模型成本、模型性能三个维度,重新把选型决策说完整。

1.1 两个模型分别承担什么

模型在本项目的职责调用点
qwen-flash(对话/生成)自由对话、新建计划的意图解析/检索词/台阶拆解、通关出题、Mem0 记忆门控分类web/src/lib/ai/client.ts、draft.ts、analyze.ts、memory.ts
text-embedding-v3(向量)把用户偏好/习惯/约束转成向量,供 Mem0 检索 topK 拼进提示词memory.ts 的 embedder 配置

两个模型都走百炼 OpenAI 兼容接口(https://dashscope.aliyuncs.com/compatible-mode/v1),用同一把 Key、同一套 SDK 形态接入,不需要为对话和向量维护两套客户端。

1.2 从功能需求看:够用,且恰好规避了 flash 的短板

  • 我们给大模型划的边界是「模型只起草,不判分、不落日期」——意图、检索词、台阶草稿由模型出,日期排期、复习日、判分全部由程序(排期引擎 + py-fsrs)计算。这条边界意味着本项目对模型的要求是短平快的结构化生成,而不是深度推理或长文创作,qwen-flash 的指令跟随与 JSON 输出能力正好覆盖。
  • 模型需要 response_format=json_object、enable_thinking=false 这类可控输出,qwen-flash 原生支持,能保证 completeJson 的一次解析成功率和「关闭思维链省 token」的实现(见 client.ts)。
  • 向量侧的需求是中文语义检索,text-embedding-v3 中文语义表达好,且维度可配(本项目固定 1024),与已用 pgvector 持久化的现有 helix 库天然对齐,无需另买向量库。

1.3 从成本看:全组共用一把按量计费 Key,性价比优先

  • 冲刺阶段模型被高频调用:每次自由对话、每步七步分析、每次出题、每次记忆门控(shouldMemorize 一次短调用)都要打一次。qwen-flash 是百炼系列里偏快、单价低的一档,在预算敏感(全组共用一把 Key、按量计费)的前提下是理性选择。
  • 向量侧 text-embedding-v3 调用成本低,且维度定 1024 后省去了启动探测调用(见 memory.ts 注释「省去启动探测调用」),进一步压低成本与首帧延迟。
  • 门控与检索都做了降级保护:shouldMemorize 失败返回 false(宁可不记)、searchRelevant 失败返回空串(不编造偏好),保证即便模型/网络异常也不会为无效调用持续烧钱。

1.4 从性能看:低延迟 + 可切换

  • qwen-flash 响应快,契合交互式对话和七步分析多次往返的体验;超时统一设 MODEL_TIMEOUT_MS=60000,实际稳定返回。
  • text-embedding-v3 1024 维在「检索 topK=5、拼接约 500 字」的场景下召回与实时性平衡良好。
  • 可切换性是这份选型的保险:模型名走环境变量 AI_PROVIDER_MODEL,将来要上更强推理(如 qwen-max/qwen-plus)或换 embedding 维度,只改 .env.local,不改任何代码。

1.5 结论

qwen-flash + text-embedding-v3 是「任务边界设计 → 模型能力 → 成本 → 可替换性」四者对齐的结果,不是随机选择:功能上覆盖结构化生成与中文向量检索、成本上适配共 Key 按量计费、性能上满足交互延迟,且通过环境变量保留了升级路径。


2、对冲刺总结博客三个提问的回应

2.1 测试能否由 AI 自主完成?

结论:不能完全自主,采用人机协同。

测试层执行方式AI 的定位
单元测试AI 自动完成(生成用例 + 执行 + 归零断言)主执行者,人复核边界
功能测试人工执行为主AI 辅助精准定位缺陷、描述复现步骤与根因
接口测试AI 先生成用例清单,测试人员在 Apifox 实际执行初稿生成者,人执行 + 回填结果

原因:AI 生成的测试代码「存在 ≠ 通过」,业务前置条件(如「层级未点亮时测试入口不应存在」这类隐含规则)需要人来补;关键路径与真实链路回归必须由人验收。

Alpha 阶段的实际执行情况:单元测试基于 Vitest 3 完成 5 个测试文件、33 个用例,全部通过;接口测试按 5 组 26 条用例在 Apifox 逐条执行,全部通过,并发现 1 个健壮性问题(非法格式 UUID 触发 500,已登记《测试问题报告-2026-10-28》问题 5,低危);功能测试共沉淀 7 份问题报告,覆盖历阶天梯弹层冲突、今日看板回调缺失、甘特图拖拽限制、侧栏滚动截断等界面与交互缺陷。

2.2 测试报告格式是否预先定义?

  • 每日测试报告:使用固定模板(问题编号、优先级、现象、复现步骤、根因分析、修复建议、回归顺序),Alpha 期间七份问题报告均按此模板沉淀。
  • Alpha 对应的测试用例文档模板:目前尚未统一,功能 / 接口 / 单元三份用例文档各自由测试同学临场拟定。后续会统一规范制定一份用例文档模板,收敛「前置条件、测试步骤、预期结果、实测结果、结论」五要素与字段命名。
  • 已有底稿:接口测试已采用「用例与结果合并为一份文档」的形式,执行结果直接回填用例表,不再单独维护结果文档;单元测试用例文档已包含用例明细、过程记录与覆盖边界说明。这两份文档的现有结构将作为统一模板的基础。

2.3 关于「Beta 阶段增加数据量方面的测试」——已采纳

老师建议在 Beta 增加大数据量场景的稳定性与效率测试,我们采纳,具体行动见 3.4。


3、老师总结的四点启发 → 具体行动

3.1 规范、计划的重要性

Alpha 已证明「契约先行 + 每日站会 + 提交只 add 目标文件」避免了大量返工。Beta 继续强化:

  • 把前后端代码规范、领域红线(不编造链接、复习日服务端计算、Key 不进仓库)固化进仓库 AGENTS.md 与输入约束,任何 AI 产出先过规范再合入。
  • 冲刺计划按「依赖关系」排定并同步到工作项 backlog,每日站会对照计划线核对,偏差当天暴露、当天调拨。
  • 统一接口契约以 types.ts 为准,类型定义先于实现,变更走 PR 评审。

3.2 统一 AI coding 工具 + 上下文打包给协作组员

老师指出:不限制组员各自用不同 AI coding 工具 → 统一一个工具 → 结合上下文一起打包给协作组员,提高集成效率与代码质量。

  • 统一工具:Beta 全组收敛到同一 AI coding 工具与同一模型(延续 qwen-flash,按需升级),减少风格漂移与「各写各的」。
  • 上下文打包:沉淀一份团队共享的「项目上下文包」(技术栈、目录、接口契约、领域规则、代码规范、常用提示词模板、自检清单),作为每次任务的标准输入,新组员/协作组员拉同一份,避免凭印象生成。
  • 提交门禁:保持 husky + lint-staged(prettier/eslint)与 npx tsc --noEmit 两道门,AI 产出必须过门 + 人工评审才合入。

3.3 AI 生成测试用例 → AI 自主测试 → 按既定格式生成测试报告

把 Alpha「AI 只到用例初稿」推进为更完整的自动化闭环:

  • 先定统一用例文档模板(承接 2.2),让 AI 生成的用例与报告「生来就符合格式」。
  • 单元测试由 AI 自动生成 + 自动执行,并扩充至配额降级、排期冲突、检索降级等纯函数。既有 33 个用例已覆盖「合法输入、非法/损坏输入、往返一致性」三类场景,扩充时延续该划分与优先级标注。
  • 测试代码同样需要检验:Alpha 期间发现过 1 个用例自身缺陷(UT-04-02,篡改方式未实际改变 token,首跑失败源于用例而非被测代码),修正为模拟真实攻击后通过——「从未失败过的测试不可信」这一经验将写入用例模板的自检项。
  • 接口测试:AI 生成 Apifox 用例清单初稿 → 人工执行回填 → AI 按既定格式汇总成测试报告草稿,人逐条核对「没跑过的不写进报告」。
  • 引入 Playwright 冒烟链路,让「AI 自主测试」从纯函数延伸到关键页面路径,目标接入 CI,push 即回归。

3.4 考虑大数据量情况下的运行稳定性与效率

  • 造大数据量种子:批量灌入大量计划/子任务/复习记录/笔记,验证列表、甘特、今日面板、统计卡片的渲染与接口耗时。
  • 接口压测与索引检查:对 tasks、subtasks、task_traces、note_docs 等高频表做数据量放大后的查询耗时与索引覆盖核对,必要时补索引或分页。
  • 健壮性回归:Alpha 接口测试已发现「非法格式 UUID 直达数据库触发 500」问题(低危、已登记),大数据量测试时同步补齐路由入口的参数校验,并回归 405 方法不匹配、非法枚举值等边界场景。
  • 幂等与并发:延续 Day7 的 PostgreSQL 幂等键,在大数据量 + 并发重复提交下验证 409、缓存结果复用、失败重试。
  • 向量库扩容:Mem0 记忆量增大后,验证 pgvector 检索延迟与结果质量,必要时调整 topK、维度或加过滤索引。
  • 日志与监控:补异常日志、错误监控与性能指标,脱离演示种子后仍能定位慢查询与 5xx。

4、Beta 行动清单汇总

序号行动对应启发责任方状态
1统一用例文档模板并推广2.2 / 3.3测试待定
2固化规范与领域红线进仓库3.1全员待定
3统一 AI coding 工具 + 上下文打包3.2组长 + 全员待定
4AI 自主单元测试 + Playwright 冒烟入 CI3.3测试待定
5大数据量种子 + 接口压测 + 索引核对3.4后端 + 测试待定
6幂等并发与 pgvector 扩容验证3.4后端 + 记忆待定
7日志、监控与性能指标补齐3.4后端待定

以上为 Alpha 答辩后我们对选型与老师/同学反馈的完整回应,Beta 冲刺将按此清单逐项落地。

项目的具体实现

1、GUI界面

前端基于 Vue 3 组合式 API 构建,视觉上遵循「Corporate Clean」风格,整套界面由一份统一的设计令牌(Design Tokens)驱动:主色、语义色、灰阶、三档阴影、五级字号、八档间距、圆角与动效时长全部收敛为 CSS 变量,页面中禁止写死颜色和圆角。这保证了八个功能页面虽然是三位前端分工开发,视觉与交互风格仍完全一致。

全局布局为「吸顶导航 + 居中内容区」:顶部 64px 吸顶栏放置站点标识、主导航、语言切换与登录入口,当前页在导航项上以主色下划线标示;内容区统一约束在 1152px 容器内,窄屏(≤768px)下导航自动转为横向滚动,不换行不折断。界面文案支持简/繁中文、英、德、日五种语言,由顶栏的语言切换器一键切换;导航菜单按登录角色动态渲染——管理角色(会议主席/分论坛主席/秘书)只显示「管理看板」入口,参会者显示分论坛、我的报名、智能推荐、我的通知四项,未登录仅保留公开页面。

所有列表类页面共享同一组公共组件:加载骨架屏、空态提示、确认对话框与页头,保证「请求中—无数据—出错了」三种状态在任何页面都有统一、可理解的呈现。

各界面截图如下(按参会者操作流排列)。

1. 登录 / 注册页:单页双模式切换,表单带输入校验,登录成功后按角色跳转对应视图。

img

注册页:

img

2. 分论坛列表页:卡片式论坛列表,支持关键词搜索与日期筛选联动,分页浏览 170 场论坛;加载中显示骨架屏,无结果显示空态。

img

img

3. 论坛详情页:完整展示论坛议题、主讲、时间地点与当前报名人数,一键报名 / 取消报名,操作结果以提示反馈。

img

4. 我的报名页:集中管理已报名论坛,支持换场(一换一弹窗:选定替代场后保存即完成替换)、取消,并在页内标出时间冲突与转场时间不足的提醒。

img

5. 智能推荐页:自然语言输入兴趣方向,推荐结果以卡片呈现,附推荐理由与匹配度。

img

6. 管理看板:单入口按角色内部分发三个视图——会议主席看板(参会人数统计 + 各论坛报名条形图)、分论坛主席看板(选择分管论坛发布通知 + 查看参会者)、秘书看板(全部参会者名单、搜索与导出、发布大会级通知)。

会议主席看板:

img

分论坛主席看板:

img

秘书看板:

img

7. 多语言界面:同一页面切换语言前后的对比,论坛标题与简介等业务内容随界面文案同步切换。

img

img

2、基础功能实现

基础功能围绕「注册—登录—浏览—报名—修改—取消—通知」的完整业务闭环实现,覆盖参会者、会议主席、分论坛主席、秘书四类角色。前端为 Vue 3 单页应用,后端按 OpenAPI 接口契约提供 17 个 RESTful 接口,全部功能已完成双后端联调并在部署环境上通过完整用户流程验证。

各功能点与作业要求逐条对照如下:

作业要求实现说明
参会者注册(可同时选择报名多个分论坛)注册表单支持勾选多个分论坛,注册请求一次性携带 forumIds 完成初始报名(上限 20 场);用户名、邮箱唯一性校验,密码以 PBKDF2 哈希存储
用户登录,按角色区分功能统一登录页签发 JWT,令牌内含角色;登录后按角色渲染导航:参会者显示报名/推荐/我的通知,管理角色仅显示管理看板入口;路由守卫拦截越权访问
浏览分论坛信息列表页支持关键词搜索、日期筛选与分页;详情页展示论坛时间、地点、主席、简介及实时报名人数
报名 / 修改 / 取消报名详情页一键报名(接口幂等,重复报名自动跳过);「我的报名」页支持取消报名与「一换一」换场弹窗;换场与取消均有确认反馈
报名时间冲突提示后端按半开区间实时计算个人日程冲突,完全重叠标记「冲突」,间隔 15 分钟内标记「紧邻」并建议预留转场时间
主席发布通知、参会者接收推送分论坛主席在看板选择分管论坛发布通知;参会者在「我的通知」中收到「已报名论坛 + 本人主持论坛 + 大会级」三路并集的通知列表
会议主席 / 分论坛主席了解参会人数会议主席看板展示大会参与人数(按报名去重口径)与各论坛报名条形图;分论坛主席看板展示所管论坛的参会者人数与名单
秘书获取全部参会者信息秘书看板提供全部参会者名单,支持关键词搜索与 CSV 导出(RFC 4180 转义,Excel 可直接打开)

除需求逐条覆盖外,针对易被忽略的边界场景做了专门处理:重复报名由数据库唯一约束兜底、接口层幂等返回不报错;取消报名采用状态位软删除,取消后重新报名会复活原记录而非产生重复数据,首次报名时间保持不变;报名修改与换场前实时校验时间冲突,从源头阻止日程撞场;并发写入场景下幂等性由唯一约束仲裁而非「先查后写」,避免竞态导致的数据错乱。上述边界行为均有对应的自动化测试用例覆盖。

3、LLM功能实现

LLM 智能推荐面向参会者:输入自然语言描述的兴趣方向(如「我对大模型和软件工程交叉方向感兴趣」),系统结合库内 170 场分论坛的真实信息调用大模型,返回最多 5 场匹配的分论坛,每场附带自然语言推荐理由与匹配度,与作业「利用 LLM 推荐相关分论坛,并说明推荐理由」的要求逐点对应。

调用链路:模型选用阿里云百炼 qwen(OpenAI 兼容端点,密钥经环境变量注入,不进代码仓库)。后端构造提示词时只提供论坛目录的 id、标题、领域标签与简介,要求模型按 id 选择而非自行生成论坛名——模型倾向于「优化」标题措辞,若由模型输出论坛名,前端将无法与数据库记录对应。模型返回后,标题、时间等字段一律由后端按 id 从数据库回填,不信任模型生成的业务字段。

输出校验:模型输出被视作不可信输入,依次通过四道闸门过滤——forumId 必须在本次目录白名单内(拦截模型编造不存在的论坛);相关性分数低于 0.50 的条目剔除(模型习惯凑满 5 条,边缘条目拉低质量);同一论坛去重只留最高分;结果截断至最多 5 条。此外推荐理由少于 8 个字符同样判为不合法,避免出现「相关」这类无信息量的理由。

可靠性设计:推荐链路实现四级降级,不允许「模型不可用导致接口 500」——模型输出非合法 JSON 时携带纠错提示重试一次;重试仍失败、超时或鉴权失败时切换为关键词兜底算法(按 2-gram 重叠度对论坛标签与简介排序,标签优先于简介),响应中标记 fallback=true 告知前端当前为降级结果;兜底也无命中时返回明确的 503 错误码而非笼统的服务器错误。

留痕与多语言:每次推荐调用记录查询语句、返回结果与耗时到 llm_recommendations 表,便于离线分析推荐质量;推荐接口支持可选 lang 参数,推荐理由可按界面语言生成,与全站五语言切换保持一致。推荐相关的离线评测与契约测试覆盖了模型返回非 JSON、JSON 被截断、编造论坛 id、分数低于阈值、重复 id、全部超时、兜底无命中等异常输入,均为固定脚本、不依赖网络、可稳定复现。

img

4、AI Coding过程

项目全程采用 AI 辅助开发,但没有把 AI 输出直接当作成品。整体工作方式遵循三条原则:给 AI 的指令先写清约束(接口契约、字段名、不许改动的范围),让 AI 在约束内生成;AI 的输出一律经过实际运行验证——接口实测、解析器校验、单元测试,不因「AI 说没问题」而免检;架构与方案类决策由 AI 列举选项和利弊,人负责拍板并把决策理由留痕。以下选取七个有代表性的开发任务,还原关键 Prompt、AI 输出与迭代取舍过程。

案例一:技术选型决策——AI 列选项,人拍板(周蔚琳)

关键 Prompt:

组员定的是 http.server + sqlite3 本地,但 schema.sql 是 MySQL 语法 sqlite3 跑不了,怎么办?HTTP 层用哪个?

AI 输出摘要:AI 先指出矛盾点——数据算法岗已交付的建表脚本全部是 MySQL 8.0 语法(CHECK 约束、utf8mb4、InnoDB),sqlite3 根本无法执行;随后给出数据库三个选项(统一 MySQL / sqlite+MySQL 双份维护 / 全 sqlite)与 HTTP 层三个选项(FastAPI / http.server / Flask),逐项列出利弊。

迭代与取舍:AI 只给选项不做强推,队长拍板数据库选「统一 MySQL」、HTTP 层选「升级 FastAPI」,决策理由写进 docs/architecture.md 决策记录:一套 schema 减少维护、FastAPI 自动生成 OpenAPI 与已定契约兼容、JWT 生态成熟。事后验证这一决策正确——后端 A/B 直接按契约写路由,后端 A 原先基于标准库的实现也因业务与框架分层隔离,迁移 FastAPI 时 189 条测试零改动全部通过。此案例体现「AI 负责分析、人负责决策」的分工方式,而非盲目采纳 AI 的第一个答案。

案例二:多语言译文存储方案——连续否掉两版(刘嘉奕)

关键 Prompt(需求描述):切语言后 170 场论坛的标题、简介、场地、通知都要跟着变,170 场 × 4 种语言的译文放在哪里。

AI 输出摘要:AI 依次给出三个方案——第 1 版主表加列(title_en、title_de……),最省事;第 2 版一张通用翻译表(entity_type + entity_id + 字段名 + 语言 + 译文),一张表全包;第 3 版每类内容一张旁表,联合主键加外键级联。

迭代与取舍:第 1 版拒绝——字段数随语言线性膨胀,每加一门语言就要改一次表,且 CHECK 约束管不了「英文有、德文空」的缺译;第 2 版拒绝——entity_id 挂不上外键,写入不存在的 id 也照收,标题和正文挤同一列只能按最长的预留;第 3 版采纳,但改了两处:场地表直接拿场地名做主键(仅 5 个场地,不值得再建维表),写入从 REPLACE INTO 换成 ON DUPLICATE KEY UPDATE——前者先删后插会触发级联、主键跳号,而这份 SQL 必须能反复重跑。最终落地为 forum_i18n / location_i18n / notice_i18n 三张旁表,查询用 LEFT JOIN + COALESCE 回退中文,五种语言走同一条 SQL,应用层无需分支。

img

img

案例三:LLM 返回的 JSON 提取——从正则到状态机的四轮迭代(柳钰舒)

关键 Prompt(第 1 轮):

大模型返回的内容里可能带 ```json 代码块,也可能前后有别的话。帮我写个函数,把里面的 JSON 对象取出来。

AI 输出摘要与迭代:第 1 轮 AI 给出正则 re.search(r"```json\s*(\{.*?\})\s*```", text, re.S),看起来可用,但拿真实模型返回一跑即失败——推荐理由里含大括号(如「涵盖 {数据库, 存储} 两个方向」)时,非贪婪匹配在第一个 } 处提前截断。第 2 轮改为「取第一个 { 到最后一个 }」,结果更糟:模型有时会在 JSON 后补一句「以上是推荐结果」,末尾反而多取。第 3 轮放弃正则,要求改用字符扫描,并明确给出三个需要跟踪的状态——是否在字符串内、是否转义、括号深度;AI 写出的版本正确,再补两处:跳过 ```json 围栏、允许前后有说明文字。第 4 轮自行补充边界:模型偶发输出两个 JSON 对象时取第一个,并补了对应测试用例。

判断依据:正则无法区分「结构上的右括号」和「字符串内容里的右括号」,只有字符扫描能分清。采纳的标准不是「代码看起来对」,而是「真实模型输出跑得过」。

案例四:注册登录——一句话到七个文件的分层收敛(柳钰舒)

关键 Prompt(第 1 轮要求):按 docs/api.md 契约实现注册/登录——注册只返回 201 与用户信息、不返回 token、重复注册返回 400;登录返回 { token, user }、JWT 带角色、无效凭证返回 401。

AI 输出摘要与迭代:第 1 轮 AI 单文件一把梭,验收三处不通过——201 响应带出了 password 字段、重复注册返回 409 而非契约要求的 400、token 漏掉 role。第 2 轮要求按分层拆文件,拆是拆了但职责重叠:app.py 重复判重、token 校验在 auth 与 security 两头都做。第 3 轮改用分工表逐文件钉死唯一职责:auth.py 只管业务规则、security.py 只管 PBKDF2 与 HS256、facade.py 只管 201/200 响应形状、contract.py 只管字段裁剪、app.py 只管路由与 Bearer 提取、domain.py 只管错误码工厂、ports.py 只管三个 Protocol;在此基础上补两处——重复用户名复用 DomainError 统一走 400(不新建 409),Bearer 缺失返回 401 契约体。第 4 轮自行补充 3 个契约断言:注册响应不含 token、登录响应必含 role、任何响应体不出现 password,防止「能跑但违背契约」的假绿。

轮次AI 给的处理理由
1单文件一把梭拒绝字段裁剪、状态码、payload 三处违约
2拆七个文件但职责重叠部分采纳判重、token 校验两头做
3分工表逐文件钉职责采纳,补 2 处口径统一:400 而非 409、401 契约体
4—补 3 个契约断言防假绿

判断依据:契约对齐(状态码、字段裁剪、payload 形状)是 AI 最容易漏的部分,接口「能跑通」发现不了这类违约,必须靠验收脚本逐条断言钉死;职责重叠则靠逐文件唯一化职责表收敛。

img

案例五:多语言接口的运行验证与错误排查 (郑聪凌)

关键 Prompt:

按照多语言接口改造清单修改后端 B。数据库已备好 forum_i18n、location_i18n、notice_i18n,前端不用改,只改 app/ 下负责查询的文件。接口路径和返回字段名保持不变,只增加可选 lang 参数,查不到译文回退中文。

AI 输出摘要:AI 在论坛列表、详情、日程、通知查询中增加可选 lang 参数,用 COALESCE 返回译文或中文原文,不新增前端字段、不改动原路径。

检查与验证过程:生成结果经接口实测暴露三个问题,逐一回喂 AI 修复。其一,数据库已有英文译文但接口仍返回中文——对比 SQL 原始结果与 JSON 响应,定位为 PyMySQL DictCursor 对重复列名的处理导致 SELECT f.*, COALESCE(i.title, f.title) AS title 里译文别名被 f.* 覆盖,要求去掉 f.*、改为显式字段列表后修复;其二,重灌后的基础库缺 forum_i18n 表时日程接口报 1146/500——第一版 AI 只保护了论坛查询,日程路由仍无条件 JOIN,用重灌后的库复测发现后,将表存在性检查接入 schedule.py,缺表时回退原文;其三,主查询带两个 lang 参数而 COUNT 查询只需一个,参数列表需分开维护——用关键词、日期、分页、lang 同时存在的请求实测返回 200 后确认修复。整个任务按「提出约束—生成初稿—运行接口—反馈错误—定位原因—修改—重新联调」的循环推进,验证始终以真实接口响应为准。

img

img

案例六:「换场」交互设计——两轮收敛到贴合直觉的方案(黄奕)

关键 Prompt:

修改报名这个 UI 按键应该怎么设计比较合理?换场点开就是请选择你要换的 B,点取消就是不换,点保存就是更换,不要去什么勾不勾选,不是一换一吗?

AI 输出摘要:第 1 版在「我的报名」页行内按钮点开后弹出大抽屉,列出全部可选论坛,通过「取消勾选旧场 + 勾选新场」完成换场,并配套自动取消勾选、引导条、重叠筛选等功能;第 2 版改为独立的一换一弹窗——点行内按钮后弹窗只选一个替代场 B,「保存」即移除 A 并加入 B,「取消」什么都不做。

迭代与取舍:第 1 版拒绝——它把「换场」做成了「重新编辑报名」,功能堆叠但违背用户对「换」这个动作的直觉,学习成本高;第 2 版采纳——严格贴合「一换一」语义,交互路径最短。后续用户反馈「点报名参加后无法取消报名」,又从只改文案迭代为补上 toggle 行为,顺带修复了刷新后按钮状态不准确的隐藏问题。此案例说明交互设计要优先贴合用户的心智模型,而不是把功能做全。

img

img

案例七:双后端 404 的定位与代理分流方案(林彩华)

关键 Prompt:

前端 mock 关掉之后,论坛列表页报"接口不存在:GET /api/forums",但这个接口后端明明实现了,帮我定位问题。

AI 输出摘要:AI 排查后指出症结——项目是双后端架构,后端 A(认证/报名/推荐,8000 端口)与后端 B(论坛/统计/通知,8001 端口)独立运行,而前端所有请求统一代理到 8000,论坛类接口实际在 8001 上,因此 404。给出方案:在 vite.config.js 按路径前缀分流,论坛/统计/日程/通知发布类转发 8001,认证/报名/推荐类保持 8000;并特别提醒 /api/notices/mine 与 /api/notices 前缀重叠,精确规则必须声明在前,否则会被宽泛规则抢先匹配到错误的后端。

引导与采纳依据:引导方式是「只给现象不给结论」,让 AI 从两后端路由表与前端的比对中自己找出接口归属。采纳前先独立核对了两后端路由表与前端 9 类请求路径的映射,确认分流划分与实际接口归属一致才采纳;采纳时自行补充一条兜底规则(未列出的路径回落 8000),保证日后新增接口漏配代理时行为可预期。修改配置后重启 dev server,论坛列表、统计、通知页面全部恢复正常。

img

除上述案例外,团队对 AI 生成内容的检查与验证已形成固定动作:AI 产出的 YAML 契约必须先用解析器实测而非肉眼审阅(曾定位到第 148 行冒号引发的语法错误);AI 参与设计的分支合并方案先用 git merge-tree 预演真实冲突再执行;冲突检测算法的 38 个单元用例坚持「先把旧代码跑红再还原」,确认测试本身有效;接口级测试通过后仍以完整业务流程复验——双后端数据源不一致的问题正是在「浏览论坛→点击报名」的全流程验证中才暴露。是否采纳、修改或拒绝 AI 建议的依据始终是实测结果与既定约束,而非 AI 输出的表面完整性。

5、数据库设计

数据库采用 MySQL 8.0,共 11 张表——8 张业务表加 3 张多语言旁表。设计从概念模型 ER 图(Chen 记号)出发:4 个实体(用户、论坛、通知、标签)与 6 个联系,其中「报名」「接收」「兴趣」「标注」「推荐」五个 M:N 联系各自落为独立的联系表,「发布」为 1:N 联系,由 notices.user_id 一个外键表达即可,不单独建表。「标签」实体没有单独成表——标签只有一个名字,直接作为 forum_tags.tag / user_interests.tag 存在联系表里,省一次 JOIN,也不会出现标签表里无人引用的孤儿行。

img

图:概念模型 ER 图(矩形为实体,椭圆为属性,菱形为联系,连线上的 1 / M / N 为基数)

表结构总览:

表作用设计要点
users四种角色共用role 加 CHECK 限定 ATTENDEE / CONFERENCE_CHAIR / FORUM_CHAIR / SECRETARY 四种枚举值
forums大会论坛与专题论坛共用forum_type 区分 plenary / special,避免两套结构
registrations报名关系UNIQUE(user_id, forum_id) 防重复报名,取消用 status 状态位标记
notices通知forum_id 为 NULL 表示会议级通知
notice_reads通知已读联合唯一,幂等写入
forum_tags / user_interests领域标签供 LLM 推荐做语义匹配
llm_recommendations推荐调用留痕记录查询语句、返回结果、耗时
forum_i18n论坛标题与简介译文主键 (forum_id, lang)
location_i18n场地名译文主键 (location, lang)
notice_i18n通知标题与正文译文主键 (notice_id, lang)

关键建模决策一:报名用状态位软删除,不物理删除。 registrations.status 取 active / cancelled,所有统计一律加 WHERE status='active',保证历史口径不失真;配合 UNIQUE(user_id, forum_id) 唯一约束,取消后重新报名是「复活」原记录而非新增行,首次报名时间保持不变。并发场景下幂等性由唯一约束仲裁而非「先查后写」,避免竞态导致重复报名。

关键建模决策二:多语言译文存数据库旁表,界面文案存前端 JSON。 多语言方案讨论中明确了一条边界——界面文案跟着代码走(放前端语言包),业务内容跟着数据走(存数据库),两者不能混。最初设想的「给 forums 表加 8 个译文列」被放弃:列数随语言线性膨胀,且 CHECK 约束无法管住「英文有、德文空」的缺译。落地形态是每类内容一张旁表、联合主键加外键级联删除,查询时 LEFT JOIN + COALESCE 兜底中文原文:

SELECT f.id, COALESCE(i.title, f.title) AS title
FROM forums f
LEFT JOIN forum_i18n i ON i.forum_id = f.id AND i.lang = %s

简体中文不单独存表,主表本身就是 zh-CN 的权威来源,避免两份数据不一致。这条设计对前端的直接收益是接口返回结构不变——多语言只体现为可选的 lang 查询参数,缺译自动回退中文,前端 8 个页面接入多语言时零改动,后续维护中也只需在数据库补译文行,不用动任何代码。

索引与约束。 索引只覆盖两条高频路径:分会人数统计用 idx_reg_forum (forum_id, status)(分论坛主席看板),个人报名与日程用 idx_reg_user (user_id, status)(我的日程)。约束逐条用真实脏数据验证过拦截效果:唯一约束(错误码 1062)、CHECK 枚举(3819)、外键(1452),五类脏数据全部被数据库拒绝,应用层无需重复校验。

6、用户体验

用户体验围绕「减少操作步骤、防止误操作、状态及时反馈」三个目标设计,以下为具体体现。

按角色直达,入口最小化。 四种角色共用统一登录页,登录后导航自动按角色切换——参会者看到「分论坛 / 我的报名 / 智能推荐 / 我的通知」,管理角色只看到「管理看板」;管理端单入口 /admin 内部按角色分发会议主席、分论坛主席、秘书三个看板,无需记忆多个地址。路由守卫同时拦截越权访问,误入时回到正确页面而非展示无权限报错。

报名一步到位,误操作有拦截。 论坛详情页一键报名,重复报名幂等处理不报错,取消后重报自动恢复原记录。修改报名采用「一换一」弹窗——只选一个替代场次、点保存即完成替换,交互路径最短。报名与换场前实时校验时间冲突:完全重叠直接阻止,间隔不足 15 分钟给出转场提醒,把错误拦在发生之前而不是事后报错。

状态反馈完整。 列表加载中有骨架屏、无结果有空态说明、请求失败有错误提示;报名成功与失败均有即时 toast 反馈;分论坛主席发布通知后,已报名的参会者在「我的通知」中立即可见,形成「发布—接收」的即时闭环。

自然语言降低使用门槛。 面对库内 170 场论坛,参会者无需逐场翻找——在智能推荐页输入一句兴趣描述(如「我对大模型和软件工程交叉方向感兴趣」),即可获得最多 5 场带推荐理由与匹配度的结果,并可在结果页直接报名或取消,无需跳转详情页。

多语言与导出细节。 五种语言一键切换,业务内容(论坛标题、简介、通知、推荐理由)同步切换,个别缺译自动回退中文、不打断浏览;秘书导出参会者名单为带 BOM 的 CSV 文件,Excel 直接打开不乱码,且导出内容为当前筛选条件下的全量数据而非当前页。

7、项目部署

项目部署在华为云服务器上,线上访问地址:http://123.249.85.102:8080/。整体采用 Docker Compose 容器化编排:前端构建为静态资源由 nginx 容器托管,后端 A/B 以统一入口运行在同一个 FastAPI 容器内,MySQL 独立容器存储正式数据。

统一部署入口。 项目由两个后端服务组成,云端最初只启动了后端 B 的 app.main:app,登录接口 /api/auth/login 返回 404。修复方式是让 app.main 以现有后端 A 的应用为基础,再挂载后端 B 的论坛、通知、管理、日程路由,同时 Dockerfile 增加 COPY backend ./backend 把后端 A 的代码复制进镜像——两个后端共用一个容器、一个端口,前端只需面对一个 API 入口。

反向代理分层。 公网通过 8080:80 端口映射访问 nginx 容器,nginx 托管前端静态资源,并通过 location /api/ { proxy_pass http://backend:8000; } 将接口请求转发到后端容器。部署初期页面可访问但接口 502,排查确认问题是 API 代理目标写错——8080:80 只是端口映射,真正的接口链路要单独指向 backend:8000,修正后页面与接口均恢复正常。

数据初始化。 正式数据库由建表脚本与种子数据脚本初始化(170 场分论坛、四角色测试账号)。迁移本地数据上云时遇到两类问题:重复导入触发主键冲突(1062),以及完整导出文件在 MySQL 8.0 导入时触发器 DEFINER 语法报错。处理方式是先备份服务器库、重建目标库结构,再用 mysqldump --no-create-info --skip-triggers 只导数据、复用服务器已有 schema 导入触发器,避免本地与云端定义混用。

镜像加速与安全配置。 服务器直连 Docker Hub 超时,配置华为云 SWR 镜像加速地址并重启 Docker 后恢复拉取。JWT 密钥按「至少 16 字符」的校验要求生成 64 位随机十六进制串写入服务器 .env,密钥不进代码仓库、不进提交记录;数据库连接等环境差异全部通过环境变量注入,与本地开发配置互不干扰。

部署后逐接口验证。 部署完成的标志不是容器运行正常,而是功能可用:按接口清单逐个实测(登录、注册、论坛列表、报名、通知、推荐),确认 OpenAPI 中同时出现两个后端的全部路由后,再以完整用户流程(登录→浏览→报名→收通知)在线上环境回归一遍,博客第一部分的运行截图均来自该线上地址。

附件功能

作业要求的附加功能实现了两项:多语言支持(五语言)与个人参会日程生成及时间冲突检测。

1、多语言支持

界面支持简体中文、繁体中文、英语、德语、日语五种语言一键切换,顶栏语言切换器为全站唯一入口。

资源包与逻辑分离。 针对作业提示的「不要用 if-else 堆语言」问题,项目采用资源包方案:全部界面文案按 key 存放在五个语言包文件(locales 目录,各 181 个 key),组件不写死任何语言的文字,统一通过 t(key) 接口取当前语言的文案——程序员负责逻辑与 key 的维护,翻译只需更新语言包,与作业倡导的 LoadMenuItem(id, language) 思想一致。项目还配了 check-i18n 校验脚本,强制五个语言包 key 结构一致、并禁止在组件里出现中文字面量硬编码,防止有人绕过资源包直接写文字。

业务内容跟随语言切换。 界面文案之外,论坛标题、简介、场地、通知、推荐理由等业务内容也随语言切换:译文存数据库多语言旁表,接口带可选 lang 参数返回对应语言,缺译时回退中文原文;推荐理由可按界面语言生成。切换语言后页面数据自动重拉,无需刷新。

2、个人参会日程与时间冲突检测

日程生成。 参会者报名的分论坛自动汇总为个人日程页,按时间排列,无需手动整理。

冲突判定规则。 每场论坛用半开区间 [start, end) 表示,两场冲突当且仅当 a.start < b.end AND a.end > b.start。按此规则,前一场 18:00 结束、后一场 18:00 开始不算冲突——参会者可以在该时刻到场,边界语义明确。

三档提示。 体验上不能只判「冲不冲突」,紧邻(转场时间不足)同样影响参会安排,因此分为三档:有时间重叠判为冲突,无法同时参加;间隔 0~15 分钟判为紧邻,不算冲突但提示建议预留 15 分钟转场;间隔大于 15 分钟正常无提示。同一天的论坛按开始时间排序后采用剪枝比较(内层循环只看「还没结束且转场时间不足」的后续场次),几十场同日论坛下接近线性复杂度。

对作业三个思考问题的回答,即本项目的实现方式:

  • 如何判断重叠、首尾相接算不算冲突:半开区间判定(见上),结束时刻与开始时刻重合不构成冲突。
  • 新增、取消、调整分论坛时如何及时更新:冲突是派生数据,不落库,每次进入日程页基于当前报名记录实时计算——报名、换场、取消操作后重新进入页面即是最新结果,不存在「改了报名但冲突标记还是旧的」的窗口;报名与换场操作前也会即时校验,重叠直接阻止、紧邻给出提醒,把问题拦在操作发生时。
  • 主办方临时改期是否需要重新检查:因为冲突每次实时计算、不落任何缓存,论坛时间在数据库中更新后,用户下次查看日程得到的就是基于新时间的判定结果,天然无需额外的「失效重算」机制——这也是当初选择实时计算而非落库的原因:落库方案必须再写一套改期后的冲突失效逻辑,实时计算的代价(每次进页面查几十条报名)可以忽略。

测试覆盖。 冲突检测有 38 个单元用例,覆盖完全相同、部分重叠、包含、开始时间相同的包含、首尾相接、间隔 5/15/16 分钟、链式紧邻、跨天、空日程、单场等全部时间边界,其中紧邻分档的剪枝条件与判定口径保持同源也有专门用例守护。

...全文

相关推荐

科技中介服务机构在评估技术成果价值时,如何避免主观判断带来的信息偏差?.docx

科技中介服务机构在评估技术成果价值时,如何避免主观判断带来的信息偏差?

BIZKEEN

高校技术转移办公室人员如何利用知识图谱实现技术成果价值挖掘?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

BIZKEEN

课程课qdqwdwdqwdqw程课程课程课程课程课程课程课程课程课程课程课程课程

课程课qdqwdwdqwdqw程课程课程课程课程课程课程课程课程课程课程课程课程

胡橙汁

国央企在推动自主创新与技术转移时,如何提升技术供需对接的效率与成功率?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

BIZKEEN

阻尼器磁流变阻尼器MR Damper非线性(阻尼、滞回)特性研究(Matlab代码实现)

内容概要:本文系统研究了磁流变阻尼器(MR Damper)的非线性力学特性,重点聚焦其阻尼力响应与典型滞回行为,并基于Matlab提供了完整的仿真建模与实现代码。通过构建MR阻尼器的动力学模型,深入分析其在外加磁场调控下的非线性、强滞回的力-位移与力-速度关系,利用数值仿真手段复现了其复杂的动态响应特征。研究涵盖了从模型建立、关键参数设定、外部激励信号设计到仿真结果可视化分析的全过程,旨在揭示该智能材料器件在振动控制应用中的内在机理与性能边界。该仿真平台对于理解半主动悬架、结构隔震等领域的核心元件行为具有重要参考价值。; 适合人群:具备一定Matlab编程基础和动力学系统基础知识,从事机械工程、车辆工程、土木工程结构振动控制、智能材料与结构或机电一体化等方向的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握磁流变阻尼器非线性滞回特性的数学建模与计算机仿真方法;②深入理解其力-位移/力-速度曲线的形成机制及磁场对阻尼力的调控规律;③为后续设计半主动控制系统、进行控制器开发或开展相关实验验证提供可靠的仿真基础与理论支撑; 阅读建议:建议读者结合Matlab代码进行逐行调试与参数扫描,通过改变输入激励(如正弦、复合频率位移)和模型参数(如磁场强度、粘滞系数),直观观察其对滞回环形状、峰值阻尼力和能量耗散的影响,以深化对非线性动态行为的理解,同时推荐查阅相关实验文献以对比验证仿真结果的准确性。

创新优化代码学习
评论
收藏 已收藏
分享
返回顶部