BUG REPORT · 13 ENTRIES · ALL FIXED
云途智报 · Bug 缺陷报告
云途智报 · 多租户企业差旅报销 SaaS —— 集成测试 / 接口自动化 / 性能与日志分析过程中发现并跟踪的缺陷。共 13 条,全部已修复并通过回归关闭。
4 P0 严重
6 P1 中等
3 P2 轻微
13 / 13 已修复关闭
统计口径:P0 严重 4 条、P1 中等 6 条、P2 轻微 3 条,已全部修复并通过回归关闭。严重程度按「资金损失 > 数据/一致性破坏 > 规则/权限 > 性能 > UI 体验」评估;以下按严重程度从高到低排序,BUG 编号为稳定跟踪号,与测试用例文档中的回归用例相互对应。
P0 严重:资金与最终一致性 4
BUG-02并发重复付款偶发抖动超扣
P0 严重已关闭
模块银企付款 / FinanceSettle
来源接口自动化 PAY-05 并发
定位锁/扣款时序
两请求并发付同一单据时,若不先做状态前置校验再拿锁,会在极小窗口导致同一单被处理两次并触发两次 Lua 扣款,存在重复向银行付款 / 账户重复扣款的真实资金损失风险。
复现步骤
- 构造已审批、余额充足单据
- 并发提交同一单的两次付款请求
- 核对余额与流水
预期:仅一次生效,余额扣一次 实际(初次复现):偶发重复扣款 2 次导致余额偏负
修复建议 在 Redisson 锁内增加状态前置校验(状态须为 PROCESSING 且未处理),锁外幂等键唯一化。修复后并发用例回归通过。
BUG-11预算并发扣减超扣(先查后扣竞态)
P0 严重已关闭
模块预算扣减 / FinanceSettle
来源并发预算用例(多单同部门)
定位Lua 原子扣减范围/加锁粒度
对同一部门预算执行「余额/预算扣减」时,若仅在单据维度加锁而未在预算行维度加锁,两笔并发付款会在「查余额 → 扣预算」之间发生竞态,导致预算实际扣减超过剩余预算(超扣为负),产生超预算支出。
复现步骤
- 设置部门预算恰好等于两笔报销之和 - 1
- 同部门两笔报销并发发起付款
- 核对预算剩余
预期:预算不为负,饱和后拒绝 实际(初次复现):预算被扣为负数,两笔均走完
修复建议 预算扣减使用单条 Lua 脚本原子判断+扣减(KEYS=预算行,ARGV=扣减额,超限返回失败),并将锁粒度提升为「预算行」,双保险。已并入 PAY-08 并发原子性回归。
BUG-09本地事务与 MQ 消息双写不一致(付款成、扣减丢)
P0 严重已关闭
模块银企付款 / FinanceSettle
来源故障注入(关闭 Broker 重发)
定位事务消息/本地消息表
付款走「本地事务提交 + 投递 RabbitMQ 银行请求」两步。当本地事务已提交(余额扣、状态置 PROCESSING)但随后 rabbitmq 投递失败 时,银行从未收到请求,单据永久停留在 PROCESSING,且余额已被扣减——本地事务与消息投递缺乏原子性(典型的「本地事务 + 发消息」双写不一致,破坏最终一致性)。
复现步骤
- 构造已审批单据
- 在付款落库后、发 MQ 前注入投递失败
- 核对:余额、单据状态、银行侧流水
预期:余额/预算/消息三处要么都成要么都回滚 实际:余额已扣但银行未收单,状态悬挂 PROCESSING
修复建议 引入本地消息表 + 定时补偿(或 RocketMQ 事务消息):业务事务在库内写「待投递消息」,JOB 扫描补投,确保「扣减成功 ⇔ 消息必达」。已纳入付款幂等/补偿回归。
BUG-10银行回调消息丢失致单据悬挂(无超时补偿)
P0 严重已关闭
模块银行回调 / MQ 消费
来源注入回调重试超限
定位重试/死信/超时补偿
银行回调经 bank.callback.queue 投递;当回调消息多次消费失败进入死信队列,而系统缺少超时扫描与重新拉单对账时,付款单据停留在 PROCESSING 无法收敛到 SUCCESS/FAILED,用户侧与对账口径失真、资金结算状态无法闭环。
复现步骤
- 付款并让银行回调处理抛异常
- 消息重试直至进入死信队列
- 观察单据终态与对账
预期:超时后触发补偿拉单收敛终态 实际:单据永久悬挂 PROCESSING,死信无法自愈
修复建议 增加超时补偿任务(对超过 N 分钟无终态的单据主动向银行拉单/查询并落终态);死信队列接入告警 + 自动重拉,已通过注入死信场景验证超时补偿收敛,回归关闭。
P1 中等:规则 / 权限 / 部分一致性与性能 6
BUG-12银行付款失败后余额/预算回退不一致(对账不平)
P1 中等已关闭
模块付款终态回退
来源FAILED 路径联调
定位回退链路原子性
银行返回 FAILED 后系统需回退「余额 + 预算 + 单据状态」。实际回退链路中,平衡与预算回退分步执行且未以同一事务包裹,任一步失败会导致「余额已回退、预算未回退」或反之,月末对账不平。
复现步骤
- 付款并模拟银行 FAILED
- 在预算回退步骤注入失败
- 比对余额/预算/单据状态
预期:三者原子回退或在补偿后一致 实际:余额已回退、预算未回退,对账出现偏差
修复建议 将「余额回退 + 预算回退 + 状态 FAILED」收敛到同一本地事务 / 同一 Lua 回退脚本,回退操作本身实现幂等,重复补偿不二次回退。已收敛到统一回退事务并验证幂等,回归关闭。
BUG-13延期/死信重试消息重复消费导致重复补偿
P1 中等已关闭
模块MQ 消费幂等
来源故障注入(同一 message_id 重投)
定位消费幂等键
回调消费链路未对 message_id 做幂等记录,出现重试/重投时同一笔回退被执行多次,导致余额、预算二次回退,出现「资金凭空增多」的对账异常。
复现步骤
- 同一银行回调消息手动重投 3 次
- 观察余额/预算/单据状态变更
预期:仅生效一次,后续幂等跳过 实际:回退 3 次,余额、预算同时被多次变更
修复建议 消费侧写入 mq_consume_log(message_id, status),先查再处理,处理完成后写 SUCCESS。已并入 PAY-09 重投幂等回归。
BUG-03月结关账并发多端触发导致重复跑批
P1 中等已关闭
模块月结关账 / MonthClose
来源接口自动化 MC-03 并发关账
定位关账任务互斥
月结关账接口未做进程级互斥,多端同时触发会导致跑批任务被并发执行,产生重复入账与对账数据污染。
复现步骤
- 多端同时点击月结关账
- 观察任务执行次数与数据落表
预期:仅一次生效,其余请求立即拒绝 实际:并发执行,数据被多次写入
修复建议 增加分布式锁 + 关账状态机(CLOSING/CLOSED),并发请求快速失败。已通过 MC-03 回归。
BUG-05多租户隔离 - 跨租户读取审批单据
P1 中等已关闭
模块权限/多租户
来源接口自动化 MT-01 跨租户
定位租户过滤
审批查询接口未严格按 tenant_id 过滤,租户 A 用户可访问到租户 B 的报销审批单详情,造成数据越权读取。
复现步骤
- 使用租户 A 的 token 构造租户 B 单据 id
- 请求详情接口,观察返回数据
预期:返回 403 / 404 实际:返回完整审批流数据
修复建议 MyBatis 拦截器自动注入 tenant_id 过滤条件,Service 层做双重校验。已并入 MT-01~03 回归。
BUG-07JMeter 1000 并发 P95 飙高,网关限流抖动
P1 中等已关闭
模块网关 / Sentinel 限流
来源JMeter 网关压测
定位限流策略/线程池
1000 并发压测下单据提交接口 P95 飙升至 900ms+,错误率 0.8%;定位到网关 Sentinel 限流阈值偏低 + 业务线程池过小。
复现步骤
- JMeter 1000 并发,30s ramp-up
- 持续 5min 压测
- 观察 P95/P99/错误率
预期:P95 < 300ms,错误率 < 0.1% 实际:P95 920ms,错误率 0.8%
修复建议 调高网关 QPS 阈值 + 业务线程池扩容,SQL 慢查询优化(加联合索引)。回归后 P95 184ms / 错误率 0.02%。
BUG-08Allure 报告偶发丢截图,环境清理脚本误删
P1 中等已关闭
模块CI / 报告
来源流水线复跑
定位报告归档脚本
流水线复跑时环境清理脚本 rm -rf ./results 误删了已生成的 Allure 截图附件,导致失败用例无法定位现场。
复现步骤
- 运行测试,生成 results 与附件
- 复跑任务,清理脚本删除 results
- 查看 Allure 报告
预期:报告完整,失败截图可见 实际:截图全部丢失
修复建议 改用 --clean-alluredir 而非 rm,截图打包归档至 OSS。修复后多次复跑均正常。
P2 轻微:UI / 体验 / 文案 3
BUG-01报销金额输入 0 仍可提交(应为必填>0)
P2 轻微已关闭
模块报销提交
来源功能测试 BUD-01 边界值
定位前端校验
报销金额输入框未限制最小值,提交 0 元单据可成功,后端业务校验也未拦截。
复现步骤
- 新建报销单,金额填 0
- 提交并观察
预期:前端提示「金额必须大于 0」 实际:提交成功,后端也未拦截
修复建议 前端加 min=0.01,后端 JSR-303 注解 @DecimalMin("0.01")。已并入 BUD-01 边界回归。
BUG-04审批驳回后未通知提交人(站内信缺失)
P2 轻微已关闭
模块站内信 / 通知
来源功能测试 NOTI-02
定位通知事件订阅
审批驳回事件未触发站内信,提交人无法及时知晓结果,影响体验。
复现步骤
- 提交报销并被驳回
- 查看提交人站内信
预期:收到「您的报销被驳回」站内信 实际:无任何通知
修复建议 通知中心订阅 reimburse.rejected 事件,异步推送。已并入 NOTI-02 回归。
BUG-06金额大写转换偶发漏字(以「整」结尾)
P2 轻微已关闭
模块公共工具类
来源功能测试 UTIL-05
定位大写转换函数
金额大写转换函数对小数点为 0 的情况漏掉「整」字尾,不符合财务规范。
复现步骤
- 输入金额 100.00
- 查看大写输出
预期:壹佰元整 实际:壹佰元
修复建议 补充分支判断 if (decimal == 0) append("整")。已并入 UTIL-05 回归。