# 模块 2、4、5 用户输入错误记录与评分设计 ## 目标 让发行货币(模块 2)、数字货币兑换(模块 4)和数字货币支付(模块 5)沿用模块一的评分口径:用户提交的业务输入不正确时,后端持久化一次错误并扣分;越级操作、重复点击、缺少前置数据和系统异常不计入错误。 ## 依据与现状 - 模块一通过错误记录器在事务外记录错误次数,并同步成绩明细的完成进度、错误数和得分。 - 模块 2、4、5 使用可恢复实验动作链。动作失败时动作事务会回滚,因此错误计分必须使用 `REQUIRES_NEW`,不能依赖动作主事务。 - 模块 2 的用户输入集中在发行申请金额、币种、机构标识、面额明细和签名密钥;模块 4 集中在钱包、银行卡和兑换金额;模块 5 集中在付款/收款钱包、支付金额和备注。 ## 设计 ### 评分服务 在后端为三个模块各提供独立的成绩服务,复用统一成绩明细表 `stu_module_score_details`: - 模块 2:模块名“发行数字货币”,序号 2,7 个步骤。 - 模块 4:模块名“数字货币兑换”,序号 5,5 个步骤。 - 模块 5:模块名“用户支付数字货币”,序号 6,6 个步骤。 每个服务提供 `recordError(userId)`、`markStepCompleted(userId, step)` 和 `detail(userId)`。错误扣分规则与模块一一致,默认每次错误扣 0.50 分,并以当前完成进度折算项目得分。 ### 错误分类 动作服务只在下列用户输入校验路径调用 `recordError`: - 模块 2:发行申请字段/面额明细非法、机构标识或银行代码不匹配、签名密钥不正确。 - 模块 4:兑换钱包或银行账户不属于当前用户、兑换金额非法、用户签名或摘要输入校验失败。 - 模块 5:付款钱包不属于当前用户、收款钱包无效、支付金额非法、备注超过限制。 顺序门禁(“请先完成动作”)、重复动作、动作状态冲突、找不到实验、业务前置数据缺失和内部异常不计分。 ### 事务边界 动作服务在识别为“用户输入错误”的 `BusinessException` 时调用对应成绩服务的 `recordError`。成绩服务使用新事务,确保即使动作主事务回滚,错误记录和成绩更新仍然保留。错误响应继续返回原有业务提示,并追加错误序号,便于用户确认本次错误已计分。 ### 前端行为 模块 2、4、5 不在前端本地重复计算分数。按钮请求沿用后端动作链,错误提示直接展示后端返回的业务消息;步骤回显继续读取动作历史和本地步骤记录。这样可避免前后端对“哪些错误计分”的判断不一致。 ## 测试策略 后端为三个评分服务补单元测试,覆盖: 1. 首次错误创建成绩明细、错误数为 1、得分按进度折算。 2. 重复错误累计错误数并继续扣分。 3. 完成步骤后再记录错误,完成进度保留且得分下降。 4. 空用户标识不写入成绩。 为三个动作服务补行为测试,分别验证一个用户输入错误会增加一次错误,而顺序门禁异常不会增加错误。已有动作成功流程和前端构建测试保持通过。 ## 不在本次范围 - 不修改模块一既有评分口径。 - 不把所有 HTTP 400 或所有 `VALIDATION_ERROR` 自动视为计分错误。 - 不新增前端独立成绩缓存或视觉评分组件。