|
641
|
22
|
79
|
1
|
|
0
|
🔍 代码审查报告:app-260616 - Merge branch 'app-260616 🔍 代码审查报告:app-260616 - Merge branch 'app-260616' of https://gitea.g-hi.co...
|
## 自动代码审查报告
**分支**: app-260616
**提交**: `c7aa286e2 ## 自动代码审查报告
**分支**: app-260616
**提交**: `c7aa286e291b5ee2230354e0e05df24e5d5a433d`
**提交人**: LITTLEMAIDI (11833999+littlemaidi@user.noreply.gitee.com)
**时间**: 2026-06-09 16:14:18
---
## 1. 审查摘要
- **代码质量评分**:4.5 / 10 分
- **总体评价**:代码实现了较为复杂的商户端业务逻辑,但存在明显的架构反模式(胖控制器、模型内重复加载组件)、严重的安全隐患(硬编码敏感密钥、SQL拼接注入风险)及事务一致性缺陷。代码风格与 PSR-12 规范差距较大,可维护性与扩展性较低。
- **风险等级**:🔴 高
> 📌 **框架说明**:提交代码的结构、加载方式(`$this->load->`、`$this->db->`、`Simple_model`)高度符合 **CodeIgniter 3.x** 规范。若 `phpci` 为贵司内部定制框架,请结合其官方生命周期文档微调以下建议。
---
## 2. 问题详情
| 严重程度 | 文件/行号 | 问题描述 | 建议修改方案 | 代码示例 (可选) |
| :--- | :--- | :--- | :--- | :--- |
| 🔴 严重 | `MerchantAppServer.php`<br>~L295 | **硬编码第三方敏感密钥**:`xfyun_tts_config` 直接明文写入控制器,极易随代码库泄露,违反安全基线。 | 将密钥迁移至 `config/` 配置文件或 `.env` 环境变量中,通过 `config_item()` 或 `getenv()` 读取。 | ```php<br>// config/xfyun.php<br>return [<br> 'appid' => getenv('XFYUN_APPID'),<br> 'secret' => getenv('XFYUN_SECRET'),<br> 'key' => getenv('XFYUN_KEY')<br>];<br>// 控制器中<br>$this->config->load('xfyun');<br>$config = $this->config->item('xfyun');<br>``` |
| 🔴 严重 | `Ahead_deposit_model.php`<br>~L385 | **SQL 注入风险**:`$where['where'][] = '(deposit._admin_id = '.$uid.' or deposit._admin_id = 0)';` 未对 `$uid` 进行类型强转或参数绑定,若传入恶意字符串将导致注入。 | 强制类型转换或使用 CI 查询构建器安全拼接。 | ```php<br>// 推荐写法<br>$uid = (int)$uid;<br>$this->db->group_start();<br>$this->db->where('deposit._admin_id', $uid);<br>$this->db->or_where('deposit._admin_id', 0);<br>$this->db->group_end();<br>``` |
| 🔴 严重 | `Ahead_book_order_model.php`<br>~L115-180 | **事务与外部 API 调用耦合**:`invalid_book` 开启数据库事务后,在 `refund_by_notify` 中直接调用微信/银联退款 API。若外部退款成功但后续 DB 操作失败触发 `trans_rollback()`,将导致**资金已退但订单状态未更新**的资损问题。 | 将外部支付退款剥离出数据库事务。采用“先更新本地状态为退款中 -> 调用外部API -> 回调更新最终状态”的异步/补偿机制,或使用消息队列保证最终一致性。 | ```php<br>// 架构建议<br>$this->db->trans_start();<br>$this->update(['_status' => 3], ['_id' => $id]); // 3:退款处理中<br>$this->db->trans_complete();<br><br>// 事务外调用退款<br$refundRes = $this->refund_by_notify($order_data, ...);<br>if ($refundRes['status']) {<br> $this->update(['_status' => 4], ['_id' => $id]);<br>}<br>``` |
| 🟠 警告 | `MerchantAppServer.php`<br>~L100-450 | **控制器严重违反单一职责原则 (SRP)**:`index()` 方法通过 `switch` 处理登录、个人中心、打印机、支付配置等数十个接口,代码超 500 行,难以测试与维护。 | 按业务域拆分控制器(如 `LoginController`, `ProfileController`, `PrinterController`),或使用路由分发+Service 层处理业务逻辑。 | 拆分示例:<br>`class MerchantLoginController extends AplicationController { public function login() { ... } }` |
| 🟠 警告 | 所有 Model 文件<br>顶部 L2-L3 | **文件顶部全局实例化 CI 对象**:`$CI = &get_instance(); $CI->load->model('Simple_model');` 在文件加载时即执行,增加不必要的内存开销,且不符合框架懒加载机制。 | 移除文件顶部的实例化代码。模型继承 `Simple_model` 即可,CI 会自动处理基类加载。 | ```php<br>// 删除这两行<br>$CI = &get_instance();<br>$CI->load->model('Simple_model');<br>``` |
| 🟠 警告 | 所有文件<br>多处 | **模型内重复加载组件**:大量使用 `$this->load->model()` 在方法内部动态加载。CI 虽会缓存,但频繁调用仍影响性能且破坏依赖注入原则。 | 将高频使用的 Model 移至 `__construct()` 中加载,或配置 `autoload.php`。 | ```php<br>public function __construct() {<br> parent::__construct();<br> $this->load->model('ahead_yc_merchant_user_model');<br> $this->load->model('ahead_shop_config_model');<br>}<br>``` |
| 🟡 建议 | `MerchantAppServer.php`<br>~L10 | **拼写错误与命名不规范**:`AplicationController` 拼写错误;属性 `$createOutTradeNo` 使用驼峰,其余多用下划线,违反一致性。 | 修正拼写为 `ApplicationController`;统一属性命名风格(推荐 `snake_case` 或 `camelCase` 全量统一)。 | `class MerchantAppServer extends ApplicationController` |
| 🟡 建议 | `MerchantAppServer.php`<br>~L35 | **输入流处理不规范**:混用 `$_POST['post_content_data']` 与 `file_get_contents('php://input')`,未校验 Content-Type 与数据长度,易受畸形请求攻击。 | 统一使用 CI 提供的 `$this->input->raw_input_stream`,并增加 JSON 解析异常捕获与大小限制。 | ```php<br>$raw = $this->input->raw_input_stream;<br>if (strlen($raw) > 1024 * 100) exit('Payload too large');<br>$this->stream = json_decode($raw, true);<br>if (json_last_error() !== JSON_ERROR_NONE) {<br> $this->error_response('JSON格式错误');<br>}<br>``` |
---
## 3. 总结与行动建议
### 🔑 优先修复的关键问题
1. **移除硬编码密钥**:立即将 `xfyun_tts_config` 等敏感信息迁移至环境变量或加密配置文件中,避免代码仓库泄露导致资损。
2. **修复 SQL 注入漏洞**:对 `Ahead_deposit_model.php` 中的 `$uid` 拼接进行强制类型转换 `(int)`,或全面改用 CI Query Builder 的 `where()` 链式调用。
3. **解耦事务与外部支付**:重构 `invalid_book` 与 `refund_by_notify` 的调用链路,确保数据库事务仅包裹本地数据操作,外部 API 调用移至事务外或采用异步补偿机制。
### 🛠 后续重构与优化方向
1. **架构分层**:当前控制器承担了路由分发、参数校验、业务逻辑、数据组装等多重职责。建议引入 **Service 层** 处理核心业务,控制器仅负责请求接收、参数校验与响应格式化。
2. **依赖管理优化**:清理文件顶部的 `$CI = &get_instance()` 滥用,统一在构造函数中声明依赖。对于高频调用的 Model,建议配置自动加载。
3. **规范与可维护性**:
- 遵循 PSR-12 规范统一命名风格(属性、方法、常量)。
- 为长方法(如 `index()`、`search_deposit_list()`)添加类型声明(PHP 7.4+ 支持 `array`, `int`, `string` 等)与 PHPDoc 注释。
- 引入静态分析工具(如 `PHPStan` 或 `Psalm`)与代码规范检查(`PHP_CodeSniffer`)纳入 CI/CD 流程。
> ⚠️ **局限性说明**:本次审查基于您提供的代码片段。由于 `MerchantAppServer.php` 末尾被截断,部分业务闭环逻辑(如 `case "1001"` 后续处理)未能完整评估。建议补充完整代码或提供对应单元测试用例,以便进行更精准的边界条件与异常流审查。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1780992858
|
1780992858
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
642
|
22
|
80
|
1
|
|
0
|
🔍 代码审查报告:app-260616 - 预订列表
|
## 自动代码审查报告
**分支**: app-260616
**提交**: `6c2219403 ## 自动代码审查报告
**分支**: app-260616
**提交**: `6c2219403bf4db53b66686f356e77bd5c4e06939`
**提交人**: LITTLEMAIDI (11833999+littlemaidi@user.noreply.gitee.com)
**时间**: 2026-06-09 16:49:37
---
## 1. 审查摘要
- **代码质量评分**:6.5 / 10 分
- **总体评价**:业务功能覆盖较完整,状态流转与权限校验逻辑较为清晰。但存在**高危 SQL 注入漏洞**、**事务处理机制不规范**、**严重的 N+1 查询性能瓶颈**,且代码风格偏向传统 PHP 写法,缺乏现代类型声明与 PSR-12 规范。部分方法逻辑冗长,职责划分不够清晰。
- **风险等级**:🔴 高
## 2. 问题详情
| 严重程度 | 文件/行号 | 问题描述 | 建议修改方案 | 代码示例 (可选) |
| :--- | :--- | :--- | :--- | :--- |
| 🔴 严重 | `Ahead_book_model.php`<br>`add_book()` 方法 | **事务处理逻辑错误**。在 `try` 块中手动调用 `$this->db->trans_rollback()` 后直接 `return`,但方法末尾仍执行 `$this->db->trans_complete()`。在 CI 类框架中,`trans_complete()` 会自动根据状态提交或回滚,手动回滚会导致事务状态机混乱,可能引发“事务已提交/回滚”异常或数据不一致。 | 移除 `try-catch` 中的手动回滚,采用框架标准事务流:`trans_start()` → 业务逻辑 → `trans_complete()` → 通过 `trans_status()` 判断结果。异常捕获应仅用于记录日志或转换错误格式。 | ```php<br>$this->db->trans_start();<br>// ... 业务逻辑 ...<br>$this->db->trans_complete();<br>if ($this->db->trans_status() === FALSE) {<br> return ['success'=>false, 'msg'=>'预订失败'];<br>}<br>``` |
| 🔴 严重 | `Ahead_book_model.php`<br>`get_book_list()` ~L285 | **SQL 注入漏洞**。`$where_str[] = "(book._book_no LIKE '%" . $params['book_no'] . "%' ..."` 直接拼接用户输入,未做任何转义或参数绑定。攻击者可构造恶意输入破坏查询结构或拖库。 | 使用框架查询构建器的 `like()` 方法,或强制类型转换/使用 `escape()`。复杂条件建议拆分为多个 `or_group_start()`。 | ```php<br>$this->db->group_start();<br>$this->db->like('book._book_no', $params['book_no']);<br>$this->db->or_like('book._customer_contact', $params['book_no'], 'after');<br>// ... 其他条件 ...<br>$this->db->group_end();<br>``` |
| 🔴 严重 | `Ahead_book_model.php`<br>`update_book()` ~L195 | **SQL 注入漏洞**。`$where = "_merchant_id=" . $merchantId . " and _id in (" . implode(",", $ids) . ")";` 直接拼接字符串作为 WHERE 条件。 | 使用数组条件或 `where_in()`,避免手写 SQL 片段。 | ```php<br>$where = ['_merchant_id' => $merchantId];<br>$this->db->where_in('_id', $ids);<br>``` |
| 🟠 警告 | `Ahead_book_model.php`<br>`get_book_list()` ~L330-380 | **N+1 查询性能瓶颈**。在 `foreach ($list['rows'] as &$row)` 循环中频繁调用 `get_one()`、`get_vip_info_by_recharge()` 等模型方法。数据量稍大时将导致数据库连接耗尽、响应超时。 | 提取循环中所需的所有 ID,使用 `where_in` 批量查询,或在 SQL 层通过 `LEFT JOIN` 一次性获取。循环内仅做数组映射与格式化。 | ```php<br>$userIds = array_unique(array_filter(array_column($list['rows'], 'ahead_user_id')));<br>$users = $this->ahead_user_model->get_list(['_id' => $userIds]);<br>$userMap = array_column($users, '_mobile', '_id');<br>// 循环内直接 $row['customer_contact'] = $userMap[$row['ahead_user_id']] ?? '';<br>``` |
| 🟠 警告 | `Ahead_book_model.php`<br>`add_book()` ~L45 | **日期格式化逻辑错误且冗余**。`strtolower(date("Ymd H:30"))` 中 `H:30` 非标准格式(应为 `H:i`),且 `strtolower` 对日期字符串无意义。业务意图疑似“取整到半小时”。 | 使用数学取整或标准时间函数。若需取当前时间最近的半小时节点:`date('Y-m-d H:i', floor(time()/1800)*1800)`。 | `$thirtyTime = date('Y-m-d H:i', floor($nowTime / 1800) * 1800);` |
| 🟠 警告 | `Ahead_book_model.php`<br>全文多处 | **模型重复加载**。在多个方法内部反复调用 `$this->load->model()`,增加框架解析开销,且不利于依赖管理。 | 将高频使用的模型移至 `__construct()` 中统一加载,或采用服务容器/依赖注入。 | ```php<br>public function __construct() {<br> parent::__construct();<br> $this->load->model('ahead_shop_config_model');<br> $this->load->model('Ahead_yc_shop_model');<br>}<br>``` |
| 🟡 建议 | `Ahead_book_model.php`<br>`Ahead_book_order_operation_log_model.php` | **不符合 PSR-12 规范**。方法名使用下划线(如 `add_book`),缺少参数与返回类型声明,文件顶部 `$CI = &get_instance();` 暴露在全局作用域。 | 方法名改为驼峰式(`addBook`),补充类型提示(`int $merchantId, array $params`),移除全局 `$CI` 赋值,按需使用 `$this->ci` 或 `$CI =& get_instance()` 局部获取。 | `public function addBook(int $merchantId, int $uid, array $params): array` |
| 🟡 建议 | `Ahead_book_order_operation_log_model.php`<br>`get_log_list()` ~L45 | **循环内分支查询冗余**。根据 `source` 在循环中调用不同模型的 `get_one()`,可优化为分组批量查询。 | 按 `source` 分组收集 `user_id`,分别批量查询后合并映射,减少 DB 交互次数。 | *(逻辑同 N+1 优化,按 source 分组后批量 `where_in` 查询)* |
| 🟡 建议 | `Ahead_book_model.php`<br>`update_book()` 末尾 | **代码截断**。方法在 `if (isset($params['welcome_minutes']) && $params['welcome_minutes']) {` 处中断,无法评估完整逻辑与事务闭合情况。 | 请补充完整代码。审查当前仅基于已提供片段。 | N/A |
> 💡 **框架适配说明**:代码结构高度类似 CodeIgniter 3/4。若 `phpci` 为定制框架,其事务状态机(`trans_start/complete/status`)与查询构建器(`where_in/like`)的实现可能与原生 CI 存在差异。建议对照 `phpci` 官方文档确认事务自动回滚机制与参数绑定语法。
## 3. 总结与行动建议
### 🔑 优先修复的关键问题
1. **立即修复 SQL 注入**:替换所有字符串拼接的 WHERE/LIKE 条件,全面改用框架查询构建器或参数绑定。这是最高优先级的安全红线。
2. **重构事务控制流**:移除 `try-catch` 中的手动 `trans_rollback()`,统一使用 `trans_start() → trans_complete() → trans_status()` 标准模式,确保数据一致性。
3. **消除 N+1 查询**:将 `get_book_list()` 循环内的单条查询改为批量查询(`where_in`)或 SQL `JOIN`,预计可将列表接口响应时间降低 60%~80%。
### 🛠 后续重构与优化方向
- **分层架构优化**:当前 Model 承担了过多业务逻辑(如权限校验、短信发送、欢迎词编码、日志记录)。建议引入 `Service` 层处理业务流程,Model 仅负责数据存取,符合单一职责原则。
- **现代化 PHP 特性**:全面启用 PHP 7.4+/8.x 类型声明(`declare(strict_types=1);`、参数/返回类型、属性类型),提升代码健壮性与 IDE 提示体验。
- **配置与常量管理**:硬编码的魔法数字(如 `1, 2, -1, 7, 11, 34`)应提取为类常量或配置文件,提升可维护性。
- **异常处理规范化**:`throwError()` 疑似全局函数,建议替换为抛出标准 `InvalidArgumentException` 或自定义业务异常类,配合全局异常处理器统一返回 JSON 格式。
- **补充完整代码**:请提供 `update_book()` 方法的完整实现,以便审查其事务边界、数据校验与状态流转逻辑。
如需针对特定模块(如短信发送逻辑、权限校验链路)进行深度剖析或提供完整重构代码模板,可随时提供补充片段。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1780994977
|
1780994977
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
643
|
22
|
81
|
1
|
|
0
|
🔍 代码审查报告:app-260616 - 预订列表
|
## 自动代码审查报告
**分支**: app-260616
**提交**: `422c54fb5 ## 自动代码审查报告
**分支**: app-260616
**提交**: `422c54fb5bc9fc67619ac2b5c777d7be5b60df9e`
**提交人**: LITTLEMAIDI (11833999+littlemaidi@user.noreply.gitee.com)
**时间**: 2026-06-09 16:52:26
---
## 1. 审查摘要
- **代码质量评分**:4.5 / 10 分
- **总体评价**:代码实现了较为复杂的商户端业务逻辑,但存在典型的“巨型控制器/模型”反模式。安全层面存在硬编码密钥与 SQL 注入风险;性能层面存在明显的 N+1 查询与重复资源加载;架构层面严重违反单一职责原则,且混用了 CodeIgniter 3 的底层特性(注:项目结构及语法特征高度吻合 CI3,非 `phpci` 框架,以下审查基于 CI3 最佳实践)。整体需进行系统性重构。
- **风险等级**:🔴 高
## 2. 问题详情
| 严重程度 | 文件/行号 | 问题描述 | 建议修改方案 | 代码示例 (可选) |
| :--- | :--- | :--- | :--- | :--- |
| 🔴 严重 | `MerchantAppServer.php` (约第350行) | **硬编码敏感凭证**:`xfyun_tts_config` 直接暴露了第三方 API 的 `APPID`、`APISecret` 和 `APIKey`,极易导致服务被盗刷或数据泄露。 | 将敏感配置移至 `application/config/` 下的独立配置文件或环境变量中,通过 `$this->config->item()` 读取。 | `// config/xfyun.php<br>return ['appid' => 'xxx', 'secret' => 'xxx'];<br><br>// Controller<br>$config = $this->config->item('xfyun');` |
| 🔴 严重 | `Ahead_book_model.php` (第5行) | **框架生命周期违规**:在类外部直接调用 `$CI = &get_instance();`。CI 框架在文件加载阶段尚未完成初始化,会导致致命错误或不可预期的行为。 | 移除文件顶部的全局调用。在类方法内部按需使用 `$this->load->` 或 `$CI = &get_instance()`。 | `// 删除文件顶部的 $CI = &get_instance();<br>// 在方法内部使用:<br>$CI =& get_instance();` |
| 🔴 严重 | `Ahead_book_model.php` (`get_book_list` 方法内) | **SQL 注入漏洞**:`$where_str[] = "(book._book_no LIKE '%" . $params['book_no'] . "%' ..."` 直接拼接用户输入,未进行转义或参数绑定。 | 使用 CI Query Builder 的 `like()` 方法或 `$this->db->escape_like_str()` 进行安全过滤。 | `$search = $this->db->escape_like_str($params['book_no']);<br>$this->db->group_start()<br> ->like('book._book_no', $search, 'both')<br> ->or_like('book._customer_contact', $search, 'after')<br>->group_end();` |
| 🔴 严重 | `MerchantAppServer.php` (`__construct`) | **初始化逻辑断裂**:通过 `if ($this->router->fetch_method() !== "uploadPic")` 跳过核心初始化。若其他未白名单方法被调用,将因 `$this->request`、`$this->stream` 等属性未定义而抛出 `Undefined property` 或空指针异常。 | 移除方法级白名单拦截。改为在 `__construct` 中安全初始化基础属性,或在具体方法开头按需校验。 | `// 移除 if 判断<br>$this->stream = json_decode(file_get_contents('php://input'), true) ?? [];` |
| 🟠 警告 | `Ahead_book_model.php` (`get_book_list` 循环内) | **N+1 查询性能瓶颈**:`foreach` 循环中逐行调用 `$this->ahead_vip_model->get_vip_info_by_recharge()`,数据量大时将导致数据库连接耗尽与响应延迟。 | 改为批量查询:先收集所有 `customer_contact`,使用 `WHERE IN` 一次性查出 VIP 信息,再在 PHP 中映射到对应行。 | `$contacts = array_column($list['rows'], 'customer_contact');<br>$vip_data = $this->ahead_vip_model->get_batch_by_mobiles($contacts);<br>// 循环中通过 $vip_data[$row['customer_contact']] 赋值` |
| 🟠 警告 | `MerchantAppServer.php` (`index` 方法) | **重复加载模型与配置**:多个 `case` 分支中重复执行 `$this->load->model()` 和 `$this->config->load()`,增加 I/O 开销与内存占用。 | 将公共依赖的模型/配置提取至 `__construct` 或类属性中按需懒加载。 | `// __construct 中统一加载<br>$this->load->model(['ahead_merchant_role_priv_model', 'ahead_yc_shop_model']);` |
| 🟠 警告 | `MerchantAppServer.php` (约第15行) | **CORS 策略过于宽松**:`header("Access-Control-Allow-Origin:*");` 允许任意域名跨域请求,易被恶意站点利用发起 CSRF 或数据窃取。 | 根据实际业务配置可信域名白名单,或限制为 App 端特定 `User-Agent`/`Origin`。 | `$allowed = ['https://app.yourdomain.com'];<br>if (in_array($_SERVER['HTTP_ORIGIN'] ?? '', $allowed)) {<br> header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");<br>}` |
| 🟡 建议 | `MerchantAppServer.php` (`index` 方法) | **魔法数字与硬编码泛滥**:`case '0005'`、`$permission_id = 534`、`$unsetMenuIds = [694, 849...]` 等缺乏语义化定义,维护成本极高。 | 提取为类常量或独立配置文件(如 `config/permissions.php`),使用枚举或常量映射。 | `const FUNC_LOGIN = '0005';<br>const PERM_VIP_RECHARGE_INVALID = 534;` |
| 🟡 建议 | `MerchantAppServer.php` (约第200行) | **数组过滤逻辑低效**:使用 `foreach` + `unset` + `array_values()` 过滤菜单,可读性差且性能不佳。 | 改用 `array_filter()` 结合闭包函数,代码更简洁且符合函数式编程规范。 | `$menus = array_values(array_filter($menus, function($v) use ($unsetMenuIds) {<br> return !in_array($v['id'], $unsetMenuIds) && !in_array($v['parentid'], $unsetMenuIds);<br>}));` |
| 🟡 建议 | `MerchantAppServer.php` / `Ahead_book_model.php` | **命名规范与拼写错误**:`AplicationController` 拼写错误;变量命名混用驼峰与下划线;注释含大量历史标记(如 `add by nan 17.10.25`)。 | 遵循 PSR-12 规范:类名 PascalCase,方法/属性 camelCase,常量 UPPER_SNAKE_CASE。清理过期注释。 | `class MerchantAppServer extends ApplicationController` |
## 3. 总结与行动建议
### 🔑 优先修复的关键问题
1. **立即移除硬编码密钥**:将 `xfyun_tts_config` 等敏感配置迁移至环境变量或加密配置文件中,避免凭证泄露。
2. **修复 SQL 注入风险**:全面审查 `Ahead_book_model.php` 中的 `$where_str` 拼接逻辑,统一替换为 CI Query Builder 的安全绑定方法。
3. **纠正框架生命周期调用**:删除 `Ahead_book_model.php` 文件顶部的 `$CI = &get_instance();`,防止框架初始化冲突。
### 🛠 后续重构与优化方向
1. **架构拆分(Controller -> Service/Repository)**:
- 当前 `MerchantAppServer` 承担了路由分发、鉴权、权限校验、数据组装、业务逻辑等所有职责,违反单一职责原则。
- **建议**:按业务域拆分为独立控制器(如 `AuthController`, `OrderController`, `PrinterController`),并将复杂业务逻辑下沉至 `Service` 层,模型仅负责数据持久化。
2. **性能优化策略**:
- 解决 `get_book_list` 中的 N+1 查询问题,采用批量加载或 `JOIN` 预加载。
- 将重复的 `$this->load->model()` 移至构造函数或使用 CI 的自动加载配置。
- 对高频调用的权限校验(如 `check_priv`)引入 Redis 缓存,降低数据库压力。
3. **规范化与可维护性提升**:
- 建立全局常量/配置中心管理魔法数字(接口号、权限ID、菜单ID等)。
- 统一输入校验层:在 `__construct` 或中间件中统一解析 JSON、校验 Token 格式、过滤非法字符,避免在每个 `case` 中重复处理。
- 补充异常处理与日志记录:当前 `try-catch` 仅返回失败提示,建议接入统一日志组件(如 Monolog)记录堆栈,便于线上排查。
> 📌 **注**:项目代码结构、加载方式(`$this->load->`、`get_instance()`、`BASEPATH`)与 **CodeIgniter 3** 高度一致。若实际使用的是内部封装的 `phpci` 框架,请核对上述 CI3 特性是否被框架兼容或重写。建议查阅框架官方文档确认路由分发、模型加载及安全过滤的最佳实践。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1780995146
|
1780995146
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
644
|
21
|
291
|
1
|
|
0
|
🔍 代码审查报告:pay-260616 - 预订退款
|
## 自动代码审查报告
**分支**: pay-260616
**提交**: `afdf33599 ## 自动代码审查报告
**分支**: pay-260616
**提交**: `afdf33599c575f0ec80959371c38eb026bf8e536`
**提交人**: LITTLEMAIDI (11833999+littlemaidi@user.noreply.gitee.com)
**时间**: 2026-06-09 17:06:02
---
## 1. 审查摘要
- **代码质量评分**:5.5 / 10 分
- **总体评价**:业务逻辑覆盖较全面,具备支付回调、退款、消息推送等核心流程。但存在**严重的事务管理缺陷**与**SQL注入隐患**,代码结构冗长、硬编码较多,且频繁动态加载模型影响性能。整体可维护性与安全性亟待提升。
- **风险等级**:🔴 高
> 📌 **框架说明**:根据目录结构(`system/`, `application/models/`)、`$CI =& get_instance()` 及 `$this->load->model()` 等特征,判定该代码基于 **CodeIgniter 3.x** 架构。若 `phpci` 为贵司内部定制框架,请结合其官方文档对事务状态机与模型加载机制进行适配调整。
> ⚠️ **局限性说明**:提供的代码在 `create_community_shop_book_order` 方法末尾截断(`if ($this->tuangou->verify_token) {`),导致该部分逻辑无法完整评估。以下审查基于已提供内容。
## 2. 问题详情
| 严重程度 | 文件/行号 | 问题描述 | 建议修改方案 | 代码示例 (可选) |
| :--- | :--- | :--- | :--- | :--- |
| 🔴 严重 | `check_notify()` 方法内 | **事务提交后执行关键业务**:`$this->db->trans_complete()` 在方法中段调用,数据库事务已提交。随后执行 `send_success_msg()`、会员回调等逻辑,若此处抛出异常或失败,**数据已落库但业务未闭环**,导致状态不一致。且 `catch` 中尝试 `trans_rollback()` 已无效。 | 将非数据库操作(消息推送、外部API调用)移至事务提交后,并增加补偿/重试机制;或改用显式事务控制,确保 `trans_complete()` 仅在方法末尾执行。 | 见下方重构示例 |
| 🔴 严重 | `refund_by_notify()` 约第 240 行 | **SQL 注入风险**:`$log_where = '_relation_id="' . $order_data['_id'] . '" ...';` 直接拼接字符串传入自定义 `up()` 方法。若 `_id` 含双引号或恶意字符,将破坏 SQL 结构或导致注入。 | 严禁字符串拼接构造 SQL 条件。统一使用 CI 查询构造器或参数绑定。 | `$this->db->where('_relation_id', $order_data['_id'])<br>->where('_status', 1)<br>->where_in('_type', [5, 13])<br>->update('pay_log', ['_status'=>4, ...]);` |
| 🟠 警告 | 文件顶部 | **全局 `$CI` 实例滥用**:`$CI = &get_instance();` 定义在类外部。每次文件被 `include` 时都会执行,浪费内存且违反 CI 规范。模型继承自 `CI_Model`,内部可直接使用 `$this->load`。 | 删除顶部 `$CI` 赋值。在需要加载配置的方法内按需获取,或改用 `$this->load->config('wx', TRUE);`。 | `// 删除顶部 $CI = &get_instance();<br>// 方法内改为:<br>$this->load->config('wx', TRUE);<br>$wx_template = $this->config->item('wx');` |
| 🟠 警告 | 多处方法 | **频繁动态加载模型**:`$this->load->model()` 在业务流中重复调用数十次。虽 CI 有缓存,但增加解析开销、降低可读性,且易引发循环依赖。 | 将高频依赖模型移至 `__construct()` 初始化,或抽离为独立 Service 层。 | `public function __construct() {<br> parent::__construct();<br> $this->load->model(['ahead_book_model', 'ahead_vip_model', 'ahead_pay_log_model']);<br>}` |
| 🟠 警告 | `check_notify()` catch 块 | **异常日志记录不规范**:`json_encode($e->getTrace(), 256)` 中 `256` 非标准 JSON 选项,且完整堆栈序列化可能包含敏感信息(如密码、Token)。 | 记录精简的异常信息(消息、文件、行号),避免在生产环境输出完整 Trace。 | `doLog('支付失败: ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine(), 'book_order');` |
| 🟡 建议 | 全局 | **魔法数字与硬编码泛滥**:大量使用 `-1, 1, 4, 5, 14, 56, 58` 等状态码/模板ID,缺乏语义化定义,后期维护成本极高。 | 提取为类常量或独立配置数组,提升代码自解释能力。 | `const STATUS_PENDING = -1; const STATUS_PAID = 1; const SMS_TPL_BOOKING = 56;` |
| 🟡 建议 | 全局 | **违反 PSR-12 规范**:混用 `array()` 与 `[]`;方法过长(`refund_by_notify` 超 150 行);注释风格不统一;函数命名 `doLog`/`do_log` 不一致;存在过时注释(如 `//add by nan 18.1.22`)。 | 统一使用短数组语法;拆分超长方法;使用 PHP-CS-Fixer 自动格式化;清理历史注释。 | 建议配置 `.php-cs-fixer.php` 并执行 `php-cs-fixer fix` |
## 3. 总结与行动建议
### 🔑 优先修复的关键问题
1. **重构事务控制逻辑**:`check_notify` 与 `refund_by_notify` 中的事务管理是最高风险点。建议采用 **显式事务控制** 或 **延迟提交策略**,确保数据库操作与外部服务调用解耦。
2. **消除 SQL 拼接隐患**:全面排查 `$log_where` 及类似字符串拼接 SQL 的地方,替换为 CI Query Builder 或 PDO 参数绑定。
3. **清理全局 `$CI` 与模型加载**:移除文件顶部的 `$CI =& get_instance()`,将模型加载收敛至构造函数或依赖注入容器,降低运行时开销。
### 🛠 后续重构与优化方向
- **架构分层**:当前 Model 承担了过多职责(支付、退款、消息推送、库存扣减、会员逻辑)。建议引入 **Service 层**,将 `check_notify`、`refund_by_notify` 拆分为独立的 `PaymentService` 与 `RefundService`,Model 仅负责数据持久化。
- **状态机管理**:订单状态流转(`-1 → 1 → 4` 等)建议使用状态机模式或枚举类管理,避免硬编码判断,提升业务扩展性。
- **统一日志与异常处理**:建立全局异常拦截器,规范 `doLog`/`do_log` 调用,敏感数据脱敏后再落盘。
- **补充单元测试**:针对支付回调、退款分支、库存扣减等核心链路编写 PHPUnit 测试用例,覆盖正常流、并发冲突、第三方 API 超时等边界场景。
> 💡 **提示**:若 `phpci` 框架对事务或模型加载有特殊封装,请以官方文档为准。建议在修复上述高危问题后,使用静态分析工具(如 `PHPStan` 或 `Psalm`)进行全量扫描,进一步收敛潜在缺陷。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1780995962
|
1780995962
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
645
|
21
|
292
|
1
|
|
0
|
🔍 代码审查报告:pay-260616 - refund_method
|
## 自动代码审查报告
**分支**: pay-260616
**提交**: `8a99434b2 ## 自动代码审查报告
**分支**: pay-260616
**提交**: `8a99434b2373fa9a9942af59296889b958ee96d1`
**提交人**: linyangrui (yangruilin888@gmail.com)
**时间**: 2026-06-09 17:12:13
---
## 📋 审查摘要
- **变更文件数**: 1
- **严重问题**: 1
- **高危问题**: 3
- **中危问题**: 2
- **建议优化**: 4
## 🐛 发现的问题
### <font color="red">[语法错误] 未安全处理空值导致潜在运行时崩溃</font>
- **严重程度**: <font color="red">严重</font>
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js`
- **行号**: 约 68 行
- **问题描述**: `const uid = wx.getStorageSync('userInfo').uid || ''` 中,若本地缓存中不存在 `userInfo` 或其值为 `null`/`undefined`,直接访问 `.uid` 会抛出 `TypeError: Cannot read properties of null (reading 'uid')`,导致页面白屏崩溃。
- **修复建议**: 使用可选链操作符或安全取值:
```javascript
const userInfo = wx.getStorageSync('userInfo') || {};
const uid = userInfo.uid || '';
```
### <font color="red">[跨文件调用] 模型方法调用参数类型不一致/疑似传参错误</font>
- **严重程度**: <font color="red">高危</font>
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js`
- **行号**: 约 115、188、285 行
- **问题描述**: `reserveModel.openMachine` 方法在多处被调用,但第 5 个参数类型不一致。首次调用传空字符串 `''`,后续调用传数字 `1`。若底层模型未做类型兼容,将导致参数解析错误或静默失败。
- **修复建议**: 统一参数类型,或查阅 `reserve.js` 确认该参数语义(如是否为 `skip_clean_check` 标识)。建议统一使用布尔值或明确定义的枚举值,例如:
```javascript
// 统一传参示例
reserveModel.openMachine(url, this.data.order_id, forward_open, successCallback, false, completeCallback)
```
### [安全隐患] 路由跳转参数未进行 URL 编码,存在路由断裂或注入风险
- **严重程度**: 高危
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js`
- **行号**: 约 108 行
- **问题描述**: `onApplyClick` 方法中拼接跳转 URL 时,`voucher_name` 未使用 `encodeURIComponent` 编码。若该字段包含 `&`、`=`、`#` 或特殊字符,将破坏 URL 结构,导致目标页面接收参数错乱,甚至引发 XSS 或路由劫持。
- **修复建议**: 对所有动态拼接的 URL 参数进行编码:
```javascript
url: '/pages/community-reserve/apply-refund/apply-refund?order_id=' + this.data.order_id +
'&actual_pay=' + this.data.order_detail.actual_pay +
'&voucher_name=' + encodeURIComponent(this.data.order_detail.voucher_name) +
'&voucher_can_refund=' + this.data.order_detail.voucher_can_refund
```
### [逻辑 BUG] 弹窗状态初始值设置错误,导致页面加载即显示阻断弹窗
- **严重程度**: 高危
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js`
- **行号**: 约 48 行
- **问题描述**: `data` 中 `showCantConvertPop: true` 的注释为“当前时间不允许自助转房弹窗是否显示”。默认值为 `true` 会导致页面一进入就强制弹出该提示,不符合常规交互逻辑,且会阻断用户操作。
- **修复建议**: 将初始值改为 `false`,仅在满足特定业务条件时通过 `setData` 动态开启:
```javascript
showCantConvertPop: false, // 默认隐藏
```
### [逻辑 BUG] wx.showToast 的 success 回调误用,导致导航时机不可控
- **严重程度**: 高危
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js`
- **行号**: 约 298 行
- **问题描述**: `wx.showToast` 的 `success` 回调是在 Toast **显示时**立即触发,而非消失后触发。在 `success` 中直接调用 `wx.navigateTo` 会导致页面跳转与 Toast 动画冲突,Toast 可能被瞬间销毁或跳转失败。
- **修复建议**: 移除 `success` 回调,直接执行跳转,或使用 `setTimeout` 延迟跳转以保证用户体验:
```javascript
wx.showToast({ title: '变更成功!', icon: 'success' });
setTimeout(() => {
wx.navigateTo({ url: '/pages/...' });
}, 1500);
```
### [中危] 页面卸载后执行定时器回调可能引发内存泄漏或报错
- **严重程度**: 中危
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js`
- **行号**: 约 175 行
- **问题描述**: `onChangeOrderClick` 中使用了 `setTimeout(() => { this.getOrderDetail() }, 5000)`。若用户在 5 秒内返回上一页或关闭小程序,`this` 指向的页面实例可能已被销毁,此时调用 `this.getOrderDetail()` 会报错或造成内存泄漏。
- **修复建议**: 在 `onUnload` 生命周期中清理定时器,或使用 `wx.navigateBack` 配合页面栈刷新替代定时器:
```javascript
// 在 data 中记录 timerId
this.timerId = setTimeout(() => { this.getOrderDetail() }, 5000);
// 在 onUnload 中清除
onUnload() { clearTimeout(this.timerId); }
```
### [代码质量] 变量命名拼写错误及冗余赋值
- **严重程度**: 建议优化
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js`
- **行号**: 约 38、41、198 行
- **问题描述**:
1. `avilable_room_list` 拼写错误,应为 `available_room_list`(多处使用)。
2. `operfrom` 拼写错误,应为 `operateFrom` 或 `operFrom`。
3. `handleOpenMachineResult` 中 `showCancelBtn: false,` 被连续赋值两次(约 198、200 行),属冗余代码。
- **修复建议**: 全局替换拼写错误,删除重复的 `showCancelBtn: false` 赋值。保持命名符合驼峰规范。
## ✅ 代码亮点
1. **状态管理清晰**:使用 `data` 集中管理弹窗显示状态(`showScanPop`, `showConfirm` 等),配合 `setData` 更新,符合微信小程序 MVVM 规范。
2. **业务边界处理完善**:在 `onApplyClick` 和 `onChangeOrderClick` 中充分考虑了退款/变更的时间限制、次数限制及商家操作状态,用户体验闭环较好。
3. **模块化调用**:合理拆分了 `ReserveModel`、`OrderModel`、`CabinetModel`,职责分离清晰,便于后期维护。
## 📝 总体建议
1. **强化防御性编程**:小程序环境网络与缓存状态多变,所有 `wx.getStorageSync`、API 返回的 `res.result` 都应进行空值/类型校验后再访问属性。
2. **统一路由参数处理**:建议封装一个 `buildUrl(path, params)` 工具函数,自动处理 `encodeURIComponent`,避免手动拼接遗漏。
3. **规范模型接口契约**:跨文件调用 `reserveModel.openMachine` 时参数类型混乱,建议在 `reserve.js` 中明确定义 JSDoc 注释,或使用 TypeScript 约束参数类型,防止后续维护出现隐式 Bug。
4. **清理冗余与拼写**:尽快修正 `avilable`、`operfrom` 等拼写错误,避免后续开发者产生误解或引发连锁引用问题。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1780996333
|
1780996333
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
646
|
21
|
293
|
1
|
|
0
|
🔍 代码审查报告:pay-260616 - 关房文案
|
## 自动代码审查报告
**分支**: pay-260616
**提交**: `52b3c6985 ## 自动代码审查报告
**分支**: pay-260616
**提交**: `52b3c69852cbf94ac325eaf9428d5306d9dc0245`
**提交人**: linyangrui (yangruilin888@gmail.com)
**时间**: 2026-06-09 17:27:27
---
## 📋 审查摘要
- **变更文件数**: 1
- **严重问题**: 0
- **高危问题**: 3
- **中危问题**: 2
- **建议优化**: 4
## 🐛 发现的问题
### <font color="red">[跨文件调用] 模型文件缺失且方法调用签名不一致</font>
- **严重程度**: <font color="red">高危</font>
- **文件**: web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js
- **行号**: 约 10-12, 115, 235, 335
- **问题描述**:
1. 代码引入了 `ReserveModel`, `OrderModel`, `CabinetModel`,但提供的项目结构为 PHP CodeIgniter 框架,**未提供对应的 JS 模型文件**,无法验证这些类及 `getBookOrderDetail`, `openMachine`, `reOpenCabinetDoor` 等方法是否真实存在。
2. `reserveModel.openMachine` 在多处调用时参数数量和语义不一致:
- 第115行:`openMachine(url, order_id, forward_open, success, '', fail)`
- 第235行:`openMachine(family_server_id, order_id, 1, success, '', fail)`
- 第335行:`openMachine(family_server_id, order_id, 1, success, 1, fail)`
参数位置混用极易导致模型层解析错位或抛出 `TypeError`。
- **修复建议**:
1. 补充 `../../../models/reserve.js` 等文件以完成跨文件验证。
2. 统一方法签名,强烈建议改为对象传参:`reserveModel.openMachine({ url, orderId, forwardOpen, success, fail })`,避免位置参数歧义。
### <font color="red">[语法错误] 未安全访问 Storage 对象导致潜在 TypeError</font>
- **严重程度**: <font color="red">高危</font>
- **文件**: web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js
- **行号**: 约 48
- **问题描述**: `const uid = wx.getStorageSync('userInfo').uid || ''`。若本地未缓存 `userInfo` 或缓存值非对象类型,直接访问 `.uid` 会触发 `TypeError: Cannot read properties of undefined`,导致小程序页面直接白屏崩溃。
- **修复建议**: 使用可选链操作符或前置判空:
```javascript
const userInfo = wx.getStorageSync('userInfo');
const uid = userInfo?.uid || '';
```
### [安全隐患] 动态拼接 HTML 字符串存在 XSS 风险
- **严重程度**: 高危
- **文件**: web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js
- **行号**: 约 198-208
- **问题描述**: `confirmContent` 直接拼接了 `res.result.book_time` 和 `res.result.reset_book_time` 等后端返回数据到 HTML 字符串中。若后端接口未做严格过滤,攻击者可通过篡改这些字段注入恶意 `<script>` 或事件属性,在支持富文本渲染的自定义组件中触发 XSS。
- **修复建议**: 对后端返回的字符串进行 HTML 实体转义,或使用小程序官方 `<rich-text>` 组件配合严格的节点白名单过滤,禁止直接拼接不可信数据。
### [逻辑 BUG] `setData` 对象中存在重复键名
- **严重程度**: 中危
- **文件**: web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js
- **行号**: 约 218
- **问题描述**: 在 `handleOpenMachineResult` 的 `type == 2` 分支中,`showCancelBtn: false` 被连续定义了两次。虽然 JS 引擎会以后者覆盖前者,但属于冗余代码,易引发维护困惑或后续合并冲突。
- **修复建议**: 删除重复的 `showCancelBtn: false` 键值对,保持对象字面量整洁。
### [逻辑 BUG] 数组访问未做边界保护
- **严重程度**: 中危
- **文件**: web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js
- **行号**: 约 418
- **问题描述**: `this.data.timeSliceList[this.data.recommendIndex].fragment_period_key`。虽然前置判断了 `recommendIndex != -1`,但未校验 `timeSliceList` 实际长度是否大于该索引。若后端返回空数组或数据异常,仍会引发 `Cannot read properties of undefined` 崩溃。
- **修复建议**: 增加安全访问逻辑:
```javascript
const selectedItem = this.data.timeSliceList[this.data.recommendIndex];
if (!selectedItem) {
wx.showToast({ title: '时段数据异常', icon: 'none' });
return;
}
```
### [代码质量] 魔法数字硬编码
- **严重程度**: 建议优化
- **文件**: web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js
- **行号**: 多处(如 `status == 5`, `operational_scene == 1/2/3/4`, `type == 1/2/4/5/6`)
- **问题描述**: 订单状态、业务场景、弹窗类型等大量使用数字硬编码,可读性差,后续新增场景时极易遗漏或写错。
- **修复建议**: 提取为常量枚举文件(如 `constants/order.js`):
```javascript
export const ORDER_STATUS = { IN_PROGRESS: 5 };
export const SCENE_TYPE = { ROOM: 1, TABLE: 2, CARD: 4 };
export const OPEN_RESULT_TYPE = { SUCCESS: 1, CONFIRM: 2, ROOM_MISMATCH: 4, ERROR: 5, UNCLEAN: 6 };
```
### [代码质量] `wx.showLoading` 缺少全局异常兜底
- **严重程度**: 建议优化
- **文件**: web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js
- **行号**: 约 65, 85, 113, 148 等
- **问题描述**: 多处直接调用 `wx.showLoading()`,但完全依赖模型回调中的 `wx.hideLoading()`。若网络请求超时、DNS解析失败或模型层未正确触发 fail 回调,Loading 遮罩将永久显示,阻塞用户操作。
- **修复建议**: 在请求发起前设置超时自动隐藏,或在模型层封装统一的 Request 拦截器处理 Loading 状态的生命周期。
## ✅ 代码亮点
1. **状态管理清晰**:使用 `data` 集中控制各类弹窗(`showScanPop`, `showConfirm`, `showChangeRoomPop` 等)的显隐,符合微信小程序组件化开发的最佳实践。
2. **业务分支明确**:针对 `bigType`(预订单/现场单)做了清晰的路由分离,逻辑隔离良好,降低了耦合度。
3. **交互细节完善**:充分考虑了提前开机确认、未清扫换房提示、碎片时段推荐、商家变更拦截等边缘场景,用户体验设计较为成熟。
## 📝 总体建议
1. **⚠️ 上下文严重不匹配**:提供的项目结构为 `PHP CodeIgniter` 框架,但审查代码为 `微信小程序 JS`。跨文件引用验证因缺少 `models/` 目录源码无法彻底完成。**请务必补充对应的 JS 模型文件**,否则 `ReserveModel` 等方法调用存在极高风险。
2. **健壮性优先**:立即修复 `wx.getStorageSync` 的空指针问题,统一 `openMachine` 等核心方法的调用签名,增加数组/对象的安全访问逻辑,避免线上白屏。
3. **安全与规范**:对富文本内容进行转义处理,提取魔法数字为常量枚举,统一 Loading 状态管理。建议接入 `ESLint` + `Prettier` 进行静态检查,自动拦截重复键名等低级语法问题。
4. **架构优化**:当前页面承担了过多的业务逻辑(近 400 行)。建议将弹窗控制、状态计算、API 请求封装为独立的 `Behavior` 或 `Mixin`,保持 Page 实例的轻量与可测试性。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1780997247
|
1780997247
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
647
|
21
|
294
|
1
|
|
0
|
🔍 代码审查报告:pay-260616 - applyBookRefund
|
## 自动代码审查报告
**分支**: pay-260616
**提交**: `98f24d0d2 ## 自动代码审查报告
**分支**: pay-260616
**提交**: `98f24d0d2e8840d59952c676882a04847b1378b0`
**提交人**: LITTLEMAIDI (11833999+littlemaidi@user.noreply.gitee.com)
**时间**: 2026-06-09 17:29:32
---
## 1. 审查摘要
- **代码质量评分**:6.5 / 10 分
- **总体评价**:该控制器承载了小程序预订核心链路(选店、选包厢、下单、开房、退款、变更、AI交互等),业务覆盖完整。但存在**构造函数职责过重、框架超对象滥用、事务处理不规范、死代码残留及 PSR-12 规范缺失**等问题。部分逻辑依赖隐式约定,可维护性与安全性存在隐患。
- **风险等级**:中(存在事务状态覆盖风险、订单路由误判风险及框架非标准用法)
> 📌 **框架说明**:代码实际基于 **CodeIgniter 3** 架构(`BASEPATH`、`get_instance()`、`$this->load->model()` 等特征)。若 `phpci` 为内部定制框架,请对照其官方文档核对生命周期与组件加载差异。以下建议以 CI3/现代 PHP 规范为准。
## 2. 问题详情
| 严重程度 | 文件/行号 | 问题描述 | 建议修改方案 | 代码示例 (可选) |
| :--- | :--- | :--- | :--- | :--- |
| 🔴 严重 | `Book.php` / 第 450~480 行 (`communityNotCleanChangeBook`) | 数据库事务处理存在状态覆盖风险。手动调用 `$this->db->trans_rollback()` 后未终止执行,后续 `$this->db->trans_complete()` 仍会执行,可能导致事务状态混乱或重复提交。 | 使用 `try-catch` 统一管控事务,或确保回滚后直接 `return`。推荐将事务逻辑收敛至 Model 层。 | ```php<br>$this->db->trans_start();<br>try {<br> // 业务逻辑...<br> $this->db->trans_complete();<br>} catch (\Exception $e) {<br> $this->db->trans_rollback();<br> $this->error_response($e->getMessage());<br>}<br>``` |
| 🔴 严重 | `Book.php` / 第 3 行 | 父类引入使用 `include` 且路径拼接冗长,未使用框架常量,易导致重复加载或路径解析失败。 | 改用 `require_once` 配合 `APPPATH` 常量,符合 CI 规范。 | `require_once APPPATH . 'controllers/mini/hz/Index.php';` |
| 🟠 警告 | `Book.php` / 第 330 行 (`checkBookReceipt`) | `if (false && $order_id)` 为硬编码死代码。逻辑被强制跳过,后续维护者易产生困惑,且可能遗漏业务开关。 | 移除死代码,或改为配置项/数据库开关控制。 | `if ($order_id) { /* 恢复原逻辑 */ }` |
| 🟠 警告 | `Book.php` / 第 380 行 (`communityOpenDoor`) | 使用 `strpos($order_id, 'CYD') !== false` 判断订单类型。若订单号包含 `CYD` 但非预订单(如备注字段污染),将导致路由错乱。 | 使用严格前缀匹配或基于订单表 `type` 字段校验。 | `if (str_starts_with($order_id, 'CYD')) { ... }`<br>*(PHP 8+ 可用 `str_starts_with`,低版本用 `substr($order_id, 0, 3) === 'CYD'`)* |
| 🟠 警告 | `Book.php` / 构造函数 (~L20, L60) | 频繁使用 `$CI = &get_instance()` 动态修改超全局对象属性(如 `error_status`, `operational_scene`)。破坏框架封装性,且 `$this` 在控制器中已是实例,无需重复获取。 | 使用 `$this->config->set_item()` 或父类属性传递状态,避免污染 CI 超对象。 | `$this->config->set_item('error_status', 2333);`<br>`$this->operational_scene = $this->param['operational_scene'] ?? 1;` |
| 🟡 建议 | `Book.php` / 第 130 行 (`getCommunityShopBookInfo`) | `is_valid_json()` 为自定义函数,未处理 `json_decode` 失败场景。若传入非法字符串,可能触发 Warning 或返回 `null` 导致后续数组访问报错。 | 使用原生 `json_decode` 配合 `json_last_error()` 或 `JSON_THROW_ON_ERROR` (PHP 7.3+)。 | ```php<br>$decoded = json_decode($shop_guide_info, true);<br>if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {<br> $data['shop_guide_info'] = $decoded;<br>}<br>``` |
| 🟡 建议 | `Book.php` / 第 50 行 | `strpos($this->function_name, 'ChangeBook') !== false \|\| strpos(..., 'changeBook')` 冗余。且 `$unnecessary_shop_id_function` 暴露为 `public`,易被外部篡改。 | 使用 `stripos` 简化判断;属性改为 `protected`;使用 `array_flip` 或 `isset` 提升查找性能。 | `protected $unnecessary_shop_id_function = [...];`<br>`if (stripos($this->function_name, 'changebook') === false) { ... }` |
| 🟡 建议 | 全局方法命名 | 方法命名风格不统一(如 `tuanGouVerify`、`communityOpenRoom` 混用大小写),不符合 PSR-12 `camelCase` 规范。 | 统一重构为小驼峰命名,提升可读性与 IDE 提示体验。 | `tuanGouVerify` → `tuangouVerify`<br>`getRoomPackgeTimePriceInfo` → `getRoomPackageTimePriceInfo` (修正拼写) |
## 3. 总结与行动建议
### 🚨 优先修复项(P0/P1)
1. **事务安全加固**:`communityNotCleanChangeBook` 中的事务回滚逻辑必须收敛。建议将 `trans_start()` / `trans_complete()` 移至 Model 层,或在 Controller 中使用 `try-catch` 确保异常时安全回滚并终止响应。
2. **清理死代码与硬编码**:移除 `checkBookReceipt` 中的 `if (false && ...)`,改为可配置开关;修正父类引入路径为 `require_once APPPATH . '...'`。
3. **订单类型路由安全**:将 `strpos($order_id, 'CYD')` 替换为严格前缀匹配,避免字符串包含误判导致越权或逻辑错乱。
### 🛠 后续重构方向
1. **构造函数瘦身**:当前构造函数承担了参数校验、模型加载、状态注入、业务预处理等职责,违反单一职责原则。建议:
- 将 `shop_id` 校验、`merchant_id` 绑定等前置逻辑移至父类 `Index` 的中间件或钩子中。
- 按需延迟加载模型(`$this->load->model()` 移至具体方法内),减少内存占用。
2. **统一响应与状态管理**:废弃 `$CI = &get_instance()` 动态赋值模式。建议封装统一的 `ApiResponse` 类或使用 CI 的 `Output` 类处理状态码与业务数据,避免全局变量污染。
3. **安全与规范对齐**:
- 所有外部输入(`$this->param`)应在 Model 层使用 Query Builder 参数绑定,严禁拼接 SQL。
- 遵循 PSR-12 规范:统一方法命名、补充空格、修正拼写错误(如 `Pakcage` → `Package`)。
- 敏感操作(退款、开房、门锁控制)建议增加操作日志记录与幂等性校验(如基于 `request_frequency` 的 Token 防重放)。
> 💡 **提示**:若 `phpci` 为内部框架且对控制器生命周期、模型加载有特定约束,请优先遵循其官方文档。本审查基于 CodeIgniter 3 最佳实践与 PHP 8 现代语法提供,可直接落地参考。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1780997372
|
1780997372
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
648
|
21
|
295
|
1
|
|
0
|
🔍 代码审查报告:pay-260616 - 卡券续费查询用户卡券需要shop_id
|
## 自动代码审查报告
**分支**: pay-260616
**提交**: `51041ff98 ## 自动代码审查报告
**分支**: pay-260616
**提交**: `51041ff98a6f987d6f01b3910b6092dc6231d4bb`
**提交人**: linyangrui (yangruilin888@gmail.com)
**时间**: 2026-06-09 17:35:58
---
## 📋 审查摘要
- **变更文件数**: 1
- **严重问题**: 2
- **高危问题**: 3
- **中危问题**: 2
- **建议优化**: 4
## 🐛 发现的问题
### <font color="red">[语法错误] 潜在的空指针/运行时崩溃(未处理 find 返回 undefined)</font>
- **严重程度**: <font color="red">严重</font>
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-list/order-list.js`
- **行号**: 约 118 行
- **问题描述**: `this.data.status_list.find(item => item.value == this.data.status).name` 在 `this.data.status` 的值不在 `status_list` 中时,`find()` 会返回 `undefined`,直接调用 `.name` 将触发 `TypeError: Cannot read properties of undefined (reading 'name')`,导致页面白屏崩溃。
- **修复建议**: 使用可选链操作符或提供默认值:
```javascript
const matchedStatus = this.data.status_list.find(item => item.value == this.data.status);
this.setData({
status_name: matchedStatus ? matchedStatus.name : '全部状态',
});
```
### <font color="red">[跨文件调用] 方法调用参数数量不一致/签名不匹配</font>
- **严重程度**: <font color="red">高危</font>
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-list/order-list.js`
- **行号**: 约 330、440、465 行
- **问题描述**: `reserveModel.openMachine` 在多处被调用,但传入的参数数量和顺序不一致:
1. `openMachine(url, this.data.oper_order.id, forward_open, callback)` (4个参数)
2. `openMachine(this.data.family_server_id, this.data.oper_order.id, 1, callback, 1)` (5个参数,多了一个末尾的 `1`)
3. `openMachine(this.data.family_server_id, this.data.oper_order.id, 1, callback)` (4个参数)
这种不一致极易导致底层模型方法解析错位、回调丢失或静默失败,属于典型的跨文件调用契约破坏。
- **修复建议**: 统一 `reserveModel.openMachine` 的函数签名。建议改为接收配置对象或固定参数顺序,例如:
```javascript
// 模型层定义建议:openMachine(params, callback)
// 调用层统一为:
reserveModel.openMachine({
url: url,
orderId: this.data.oper_order.id,
forwardOpen: forward_open,
extraFlag: 1 // 如有需要
}, (res) => { ... })
```
### [逻辑 BUG] 数组删除逻辑存在越界/误删风险
- **严重程度**: 高危
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-list/order-list.js`
- **行号**: 约 535 行
- **问题描述**: `deleteOrder` 方法中使用 `findIndex` 查找订单索引,若因网络延迟或数据不同步导致 `findIndex` 返回 `-1`,执行 `slice(0, -1)` 会错误地删除数组最后一个元素,`slice(0)` 则返回完整数组,导致列表状态错乱。
- **修复建议**: 增加索引校验,或改用 `filter` 安全删除:
```javascript
const index = this.data.goods_order_list.findIndex(item => item.order_id == this.data.del_order_id);
if (index > -1) {
const newList = [...this.data.goods_order_list];
newList.splice(index, 1);
this.setData({ goods_order_list: newList });
}
// 或直接使用 filter:
// this.setData({ goods_order_list: this.data.goods_order_list.filter(item => item.order_id !== this.data.del_order_id) });
```
### [安全隐患] 动态拼接 HTML 字符串存在 XSS 风险
- **严重程度**: 高危
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-list/order-list.js`
- **行号**: 约 360~375 行
- **问题描述**: `confirmContent` 使用模板字符串拼接了 `<span style="...">` 等 HTML 标签,并配合 `contentIsNodes: true` 渲染。若 `res.result.reset_book_time` 或 `this.data.oper_order.book_time` 包含恶意脚本(如 `<img src=x onerror=alert(1)>`),将直接触发 XSS 攻击。
- **修复建议**: 避免在 JS 中拼接 HTML。应在 WXML 中使用数据绑定,或使用微信小程序提供的安全渲染机制。若必须使用富文本,需对后端返回的数据进行严格的 HTML 实体转义或白名单过滤。
### [代码质量] 魔法数字与硬编码过多,缺乏常量管理
- **严重程度**: 中危
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-list/order-list.js`
- **行号**: 全文多处(如 `tabIndex == 0/1/2`,`status` 值 `'1'/'2'/'5'`,`operational_scene` 值 `1/2/3/4`)
- **问题描述**: 业务状态码、Tab 索引、场景类型等大量使用硬编码数字。可读性差,后期维护或新增状态时极易遗漏判断分支,引发逻辑漏洞。
- **修复建议**: 提取为枚举常量或配置文件:
```javascript
const TAB_TYPE = { BOOK: 0, ROOM: 1, GOODS: 2 };
const ORDER_STATUS = { ALL: '', UNUSED: '1', USED: '2', EXPIRED: '3', REFUNDED: '4', IN_PROGRESS: '5', CANCELLED: '6' };
// 后续判断改为:if (this.data.tabIndex === TAB_TYPE.BOOK)
```
### [代码质量] handleConfirm 方法职责不单一
- **严重程度**: 中危
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-list/order-list.js`
- **行号**: 约 505 行
- **问题描述**: `handleConfirm` 同时处理了“确认提前开机”和“确认删除订单”两种完全无关的业务逻辑,通过 `tabIndex` 进行分支判断。违反单一职责原则,增加耦合度,后续若新增确认弹窗类型,该方法将无限膨胀。
- **修复建议**: 拆分为独立方法,如 `handleConfirmEarlyOpen()` 和 `handleConfirmDelete()`,在弹窗组件的 `bindconfirm` 事件中通过 `data-action` 或独立回调绑定对应方法。
## ✅ 代码亮点
1. **结构清晰**:页面生命周期、数据初始化、业务方法分类明确,注释规范,符合微信小程序开发规范。
2. **状态管理合理**:合理使用 `setData` 控制 UI 状态(如弹窗显隐、加载状态、分页标志),用户体验流畅。
3. **防重复提交意识**:在关键操作(如开门、删除)前调用 `wx.showLoading()`,并在回调中 `wx.hideLoading()`,有效防止用户重复点击。
4. **分页加载逻辑完整**:`hasMore` 与 `page` 递增逻辑闭环完整,下拉/上滑加载更多体验良好。
## 📝 总体建议
1. **统一底层 API 契约**:当前 `reserveModel`、`orderModel`、`roomModel` 的回调参数数量、成功/失败回调结构不一致(如有的传 `(success, error)`,有的只传 `success`)。建议在 Model 层统一封装为 `Promise` 或标准 `(res, err)` 格式,降低调用方心智负担。
2. **强化边界防御**:前端直接依赖后端返回的数据结构(如 `res.result.xxx`),缺乏空值/类型校验。建议在关键数据赋值前增加 `if (res && res.result)` 等防御性编程,或使用可选链 `res?.result?.xxx`。
3. **抽离公共逻辑**:`getBookOrderList`、`getMyRoomOrderList`、`getGoodsOrderList` 的分页与列表合并逻辑高度重复。可封装为通用方法 `fetchList(apiFn, listKey, params)`,减少冗余代码。
4. **安全加固**:所有跳转 URL 拼接的参数建议统一使用 `encodeURIComponent` 包裹;涉及金额、状态变更的操作,务必在后端进行二次权限与状态校验,不可仅依赖前端状态。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1780997758
|
1780997758
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
649
|
21
|
296
|
1
|
|
0
|
🔍 代码审查报告:pay-260616 - Merge branch 'pay-260616 🔍 代码审查报告:pay-260616 - Merge branch 'pay-260616' of https://gitea.g-hi.co...
|
## 自动代码审查报告
**分支**: pay-260616
**提交**: `6280ae8dc ## 自动代码审查报告
**分支**: pay-260616
**提交**: `6280ae8dcba40d7f0e7ed8d6e14cea5efb25ed32`
**提交人**: LITTLEMAIDI (11833999+littlemaidi@user.noreply.gitee.com)
**时间**: 2026-06-09 17:41:23
---
## 📋 审查摘要
- **变更文件数**: 2
- **严重问题**: 3
- **高危问题**: 4
- **中危问题**: 3
- **建议优化**: 4
## 🐛 发现的问题
### <font color="red">[语法错误] PHP文件顶部直接调用 get_instance() 导致框架初始化失败</font>
- **严重程度**: <font color="red">严重</font>
- **文件**: `application/models/Ahead_shop_config_second_model.php`
- **行号**: 第 3 行
- **问题描述**: 在类定义外部直接执行 `$CI = &get_instance();`。CodeIgniter 框架的超级对象(Super Object)仅在控制器实例化后才会通过 `get_instance()` 返回。在模型文件加载阶段(通常早于控制器实例化)调用此函数会返回 `null` 或直接抛出 `Fatal error: Call to undefined function get_instance()`,导致整个应用崩溃。
- **修复建议**: 删除文件顶部的 `$CI = &get_instance();` 和 `$CI->load->model('Simple_model');`。在 CI 模型中,应直接使用 `$this->load->model()` 加载依赖,或在具体方法内部按需加载。
### <font color="red">[跨文件调用] 调用了未定义的自定义辅助函数</font>
- **严重程度**: <font color="red">高危</font>
- **文件**: `application/models/Ahead_shop_config_second_model.php`
- **行号**: 第 338, 352, 353, 355, 446 行等
- **问题描述**: 代码中多处直接调用了 `throwError()`, `hourToTime()`, `timeToHour()`, `minToStr()`, `get_business_date()` 等函数。这些并非 PHP 内置函数或 CI 标准辅助函数。若未在 `autoload.php` 中全局加载或未在当前文件 `require/include`,将触发 `Fatal error: Uncaught Error: Call to undefined function`。
- **修复建议**:
1. 确认这些函数是否定义在自定义 Helper 中,并在控制器或 `autoload.php` 中通过 `$this->load->helper('your_helper')` 加载。
2. 若为全局函数,建议在文件顶部显式引入或改用类方法封装,避免隐式依赖。
### <font color="red">[跨文件调用] JS 模型文件引用路径及类名未经验证</font>
- **严重程度**: <font color="red">高危</font>
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-list/order-list.js`
- **行号**: 第 2-5 行
- **问题描述**: 引入了 `ReserveModel`, `PublicModel`, `OrderModel`, `RoomModel`。根据微信小程序规范,需确保 `../../../models/reserve.js` 等文件真实存在,且内部正确 `export` 了对应类。若文件缺失或导出名称不匹配,页面加载时将直接白屏报错。
- **修复建议**: 核对项目目录结构,确保 `models/` 目录下存在对应 `.js` 文件,且导出语法为 `export class ReserveModel { ... }`。建议在开发环境开启严格模式验证模块依赖。
### [逻辑BUG] Array.find() 未处理未匹配情况导致运行时 TypeError
- **严重程度**: 高危
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-list/order-list.js`
- **行号**: 第 118 行
- **问题描述**: `this.data.status_list.find(item => item.value == this.data.status).name`。当 `this.data.status` 传入的值不在 `status_list` 中时(例如脏数据或新增状态未同步),`find()` 返回 `undefined`,紧接着访问 `.name` 会抛出 `TypeError: Cannot read properties of undefined (reading 'name')`,导致页面崩溃。
- **修复建议**: 增加安全判断或使用可选链:
```javascript
const matchedStatus = this.data.status_list.find(item => item.value == this.data.status);
this.setData({
status_name: matchedStatus ? matchedStatus.name : '全部状态'
});
```
### [安全隐患] URL 参数拼接未全面使用 encodeURIComponent
- **严重程度**: 高危
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-list/order-list.js`
- **行号**: 第 245, 263, 270, 277 行等
- **问题描述**: 多处使用字符串拼接构造跳转 URL,如 `'?order_id=' + this.data.oper_order.id + '&type=1...'`。虽然当前业务字段多为数字,但若未来 `shop_id`、`room_id` 或 `shelf_name` 包含特殊字符(如 `&`, `=`, `?`, 中文),将破坏 URL 结构,导致参数解析错误或路由跳转失败。
- **修复建议**: 对所有动态参数统一使用 `encodeURIComponent()` 包裹,或使用微信官方推荐的 `wx.navigateTo` 参数对象化写法(若框架支持)。
### [逻辑BUG] PHP 静态缓存未处理空值且缺乏清理机制
- **严重程度**: 中危
- **文件**: `application/models/Ahead_shop_config_second_model.php`
- **行号**: 第 108, 468, 508 行
- **问题描述**: 使用 `self::$shop_config[$shop_id]` 进行请求级缓存。若 `$this->get_one()` 查询不到数据返回 `false` 或 `null`,该空值会被缓存。后续同一请求中再次调用将直接返回缓存的空值,可能导致业务逻辑误判(如认为配置已存在但实际为空)。此外,静态变量在 CLI 脚本或长连接服务中不会自动释放,可能引发内存泄漏或脏数据。
- **修复建议**: 缓存前判断结果有效性,或提供 `clearCache($shop_id = null)` 方法。建议改用 CI 的 `Cache` 库或 Redis 进行分布式缓存。
### [代码质量] PHP 模型中 switch 语句过长,违反单一职责原则
- **严重程度**: 中危
- **文件**: `application/models/Ahead_shop_config_second_model.php`
- **行号**: 第 110-320 行
- **问题描述**: `get_shop_setting()` 方法包含超过 50 个 `case` 分支,代码行数超 200 行。该函数承担了数据查询、类型转换、默认值处理、业务规则计算(如时间取整、状态映射)等多重职责,可读性差且极难维护。
- **修复建议**: 采用配置映射表(Config Map)或策略模式重构。例如将默认值和转换逻辑抽离为独立数组或配置文件,通过 `array_key_exists` 和闭包函数动态处理,将函数长度控制在 50 行以内。
### [代码质量] PHP 模型加载命名大小写不一致,存在跨平台兼容性风险
- **严重程度**: 中危
- **文件**: `application/models/Ahead_shop_config_second_model.php`
- **行号**: 第 440, 485 行
- **问题描述**: 混用了 `$this->load->model('Ahead_ai_audio_player_content_model')`(首字母大写)和 `$this->load->model('ahead_shop_model')`(全小写)。CodeIgniter 在 Windows 下不区分文件名大小写,但在 Linux/生产环境中严格区分。若实际文件名与加载字符串大小写不一致,将导致 `Unable to locate the model you have specified` 错误。
- **修复建议**: 统一遵循 CI 规范:模型文件名全小写(如 `ahead_ai_audio_player_content_model.php`),加载时统一使用小写字符串。
## ✅ 代码亮点
1. **JS 状态管理清晰**:小程序页面数据(`data`)结构划分明确(预订单、门店、酒水订单分区),配合 `tabIndex` 和 `loading` 状态控制,交互逻辑完整。
2. **PHP 缓存优化意识**:在 `get_shop_setting` 和 `check_is_cleaned_for_open_room` 中使用了静态变量 `self::$shop_config` 避免重复查询数据库,提升了单次请求性能。
3. **防御性编程**:JS 中多处使用 `e.currentTarget.dataset.item` 安全获取事件参数,PHP 中大量使用 `??` 空值合并运算符设置默认值,降低了空指针风险。
## 📝 总体建议
1. **修复致命依赖问题**:优先处理 PHP 文件顶部的 `get_instance()` 调用和未声明的辅助函数。这是导致应用无法启动或运行时报错的核心原因。
2. **统一跨文件引用规范**:建立项目级的模型/Helper 命名与加载规范。PHP 端严格遵循 `小写文件名 + 小写加载`;JS 端确保 `import` 路径与导出类名一致,可考虑引入 ESLint 进行静态检查。
3. **重构超长 Switch**:建议将 `get_shop_setting` 拆分为 `基础配置获取` + `业务规则处理器`。可引入配置中心或 JSON 映射表,使新增业务场景时无需修改核心模型代码。
4. **增强异常边界处理**:JS 端对网络请求返回值增加 `Array.isArray()` 和 `res.code === 200` 校验;PHP 端对 `throwError` 等自定义异常捕获机制进行统一封装,避免错误堆栈直接暴露给前端。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1780998083
|
1780998083
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
650
|
21
|
297
|
1
|
|
0
|
🔍 代码审查报告:pay-260616 - 预订退款判断
|
## 自动代码审查报告
**分支**: pay-260616
**提交**: `7e2cd1572 ## 自动代码审查报告
**分支**: pay-260616
**提交**: `7e2cd1572cdc8a693aadf5d382c6ea720a3b5aaa`
**提交人**: LITTLEMAIDI (11833999+littlemaidi@user.noreply.gitee.com)
**时间**: 2026-06-09 17:44:22
---
## 1. 审查摘要
- **代码质量评分**:6.5 / 10 分
- **总体评价**:该 Model 承载了大量门店配置读取与业务规则处理逻辑,功能覆盖完整。但存在明显的**性能瓶颈**(循环内重复加载模型与查询)、**框架生命周期误用**(文件顶部全局获取实例)、以及**可维护性隐患**(巨型 `switch`、硬编码长字段串、变量未初始化)。整体代码偏向“过程式”堆砌,缺乏面向对象设计与批量处理思维。
- **风险等级**:🔴 高(主要源于高并发下的数据库连接耗尽风险、静态缓存潜在串扰、以及异常处理缺失)
> 📌 **框架说明**:根据目录结构(`system/`, `application/models/`)及 `$CI = &get_instance()` 用法,推断项目基于 **CodeIgniter 3** 或其衍生框架。若 `phpci` 为内部定制框架,请对照其官方文档调整生命周期与 Query Builder 用法。
---
## 2. 问题详情
| 严重程度 | 文件/行号 | 问题描述 | 建议修改方案 | 代码示例 (可选) |
| :--- | :--- | :--- | :--- | :--- |
| 🔴 严重 | `renewal_audio_broadcast` 方法内 | **N+1 查询与循环内加载模型**:在 `foreach` 中反复调用 `$this->load->model()` 和 `get_end_time_room()`,数据量稍大即会导致数据库连接池耗尽、脚本超时。 | 1. 将模型加载移至循环外;<br>2. 收集所有 `shop_id`/`room_id` 后使用 `WHERE IN` 批量查询;<br>3. 合并业务逻辑,减少嵌套循环。 | 见下方 `renewal_audio_broadcast` 优化示例 |
| 🔴 严重 | 文件顶部 (第 3-4 行) | **违反框架生命周期**:在类外部执行 `$CI = &get_instance(); $CI->load->model(...)`。每次文件被 `include` 时都会执行,造成性能损耗,且在 CLI/定时任务中可能引发 `get_instance()` 未初始化错误。 | 移除文件顶部代码。在方法内部直接使用 `$this->load->model()` 或 `$this->db`。CI 框架会自动处理实例注入。 | `// 删除顶部两行<br>class Ahead_shop_config_second_model extends Simple_model { ... }` |
| 🟠 警告 | `deal_audio_content_params` 方法 | **未定义变量警告**:`$total_time` 仅在 `if (!empty($room_data['_open_id']))` 分支内赋值,若条件不满足将触发 `Undefined variable` 警告。且循环内重复加载模型。 | 1. 提前初始化 `$total_time = '';`;<br>2. 将 `$this->load->model()` 移至 `foreach` 外部。 | `$total_time = ''; // 提前声明<br>$this->load->model('ahead_open_room_log_model');<br>foreach ($params_map as &$param) { ... }` |
| 🟠 警告 | `get_shop_setting` 方法 | **巨型 Switch 与隐式变量**:超 150 行的 `switch` 难以维护;部分分支未赋值 `$result`,依赖末尾 `?? ''` 兜底,易引发逻辑遗漏。静态缓存 `self::$shop_config` 在长驻进程(如 Swoole/RoadRunner)中会导致多请求数据串扰。 | 1. 在 `switch` 前初始化 `$result = '';`;<br>2. 若运行环境为 PHP-FPM 可保留静态缓存,否则建议改用 CI Cache 驱动或请求级缓存;<br>3. 考虑将转换逻辑抽离为私有方法。 | `public function get_shop_setting(...) {<br> $result = ''; // 显式初始化<br> switch ($field) { ... }<br> return $result;<br>}` |
| 🟠 警告 | `get_wechat_group_config` 方法 | **全局状态污染风险**:使用 `$this->set_table_name()` 临时修改表名,若后续查询抛出异常,表名无法恢复,将影响同一进程内的后续请求。 | 使用 `try...finally` 确保状态恢复,或优先使用 CI Query Builder 的 `from()` 与 `join()` 避免修改模型内部状态。 | `try {<br> $this->set_table_name($table_name . ' a');<br> $res = $this->select($where, $fields);<br>} finally {<br> $this->set_table_name($table_name);<br>}` |
| 🟡 建议 | `get_one` 方法参数 | **拼写错误**:参数名 `$fileds` 拼写错误,应为 `$fields`。 | 修正拼写,保持代码规范与 IDE 提示准确性。 | `public function get_one($where, $fields = '*', $order = '')` |
| 🟡 建议 | 多处使用 `throwError()` | **非标准异常处理**:依赖全局函数 `throwError()` 不符合现代 PHP 规范,且可能直接暴露堆栈信息或中断正常流程。 | 改用标准 PHP 异常或返回统一错误结构体,交由框架错误处理器统一拦截。 | `throw new \InvalidArgumentException('门店ID不能为空');` |
| 🟡 建议 | 全局代码规范 | **命名与缩进**:方法名使用 `snake_case`(CI3 历史习惯),不符合 PSR-12 推荐的 `camelCase`;缩进混用 Tab 与空格;缺少类型声明。 | 若团队强制沿用 CI3 规范可保留,但建议统一为 4 空格缩进。新增方法建议采用 `camelCase`,并补充 PHP 7+ 类型提示。 | `public function getShopSetting(int $merchantId, int $shopId, string $field): string` |
---
## 3. 总结与行动建议
### 🔑 优先修复的关键问题
1. **重构 `renewal_audio_broadcast` 方法**:当前实现是典型的“循环查库”反模式。必须将模型加载外置,并采用批量查询(如收集所有 `shop_id` 后一次性 `get_community_bill_shop`,或使用 `JOIN` 关联查询账单与房间)。
2. **清理文件顶部全局代码**:立即删除 `$CI = &get_instance();` 及外部 `load->model()`,避免框架生命周期冲突与内存泄漏。
3. **修复未初始化变量**:`deal_audio_content_params` 中的 `$total_time` 必须提前声明,否则在严格错误级别下会导致脚本中断。
### 🛠 后续重构与优化方向
1. **拆分巨型 `switch`**:`get_shop_setting` 承担了过多职责。建议:
- 将纯映射类字段(如直接返回 `$data['xxx'] ?? default`)提取为配置数组或动态属性访问。
- 将需要复杂计算/关联查询的字段(如 `currency_symbol`, `book_hour_options`)拆分为独立的私有方法 `private function resolveCurrencySymbol($data)`,在 `switch` 中仅做路由。
2. **引入请求级缓存**:若项目未来可能迁移至 PHP-FPM 以外的运行环境(如 Swoole、Workerman),`self::$shop_config` 静态缓存将引发严重的数据安全问题。建议改用 CI 的 `$this->cache->save()` 或注入 `Request` 对象进行单次请求缓存。
3. **统一异常与错误处理**:逐步废弃 `throwError()` 全局函数,建立统一的 `AppException` 或返回 `['code' => -1, 'msg' => '...']` 结构,提升 API 健壮性。
4. **数据库查询优化**:`$this->set_table_name()` 属于非标准 CI 用法。建议全面迁移至 `$this->db->from()->join()->get()` 链式调用,避免隐式状态修改。
### ⚠️ 审查局限性说明
- 本次审查仅基于提供的单个 Model 文件。`Simple_model` 父类实现、`hourToTime()`/`timeToHour()` 等全局助手函数、以及 `throwError()` 的具体行为未提供,部分逻辑(如跨天时间判断、缓存机制)的准确性依赖于这些外部组件的实现。
- 若 `phpci` 为高度定制的内部框架,部分 Query Builder 或生命周期建议需以官方文档为准。
> 💡 **附:`renewal_audio_broadcast` 核心优化思路示例**
> ```php
> public function renewal_audio_broadcast()
> {
> // 1. 模型外置
> $this->load->model(['ahead_bill_model', 'ahead_family_servers_model', 'Ahead_ai_audio_player_content_model']);
>
> $time = strtotime(date('Y-m-d H:i:00'));
> $business_date = get_business_date($time)['business_day'];
>
> // 2. 批量获取门店(避免逐店查询)
> $shops = $this->ahead_bill_model->get_community_bill_shop($time);
> if (empty($shops)) return true;
>
> $shop_ids = array_column($shops, 'shop_id');
> $merchant_ids = array_column($shops, 'merchant_id');
>
> // 3. 批量获取账单/房间数据(示例:使用 WHERE IN 或 JOIN)
> // 实际需根据 ahead_bill_model 的 API 调整,此处展示批量处理思想
> $all_bills = $this->ahead_bill_model->get_end_time_rooms_batch($merchant_ids, $shop_ids, $business_date, $time);
>
> foreach ($all_bills as $bill) {
> // 4. 统一处理播报逻辑,消除嵌套循环
> $this->ahead_family_servers_model->operational_scene_audio_broadcast(
> $bill['merchant_id'], $bill['shop_id'], $bill['room_id'], 'renewal',
> ['remaining_time' => $bill['renewal_time'], 'ai_audio' => $bill['is_ai']]
> );
> }
> return true;
> }
> ```
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1780998262
|
1780998262
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
651
|
21
|
298
|
1
|
|
0
|
🔍 代码审查报告:pay-260616 - bug
|
## 自动代码审查报告
**分支**: pay-260616
**提交**: `24f12a6f6 ## 自动代码审查报告
**分支**: pay-260616
**提交**: `24f12a6f67e6ea31f2764884f8f8c8de8987eb40`
**提交人**: linyangrui (yangruilin888@gmail.com)
**时间**: 2026-06-09 18:16:51
---
## 📋 审查摘要
- **变更文件数**: 2
- **严重问题**: 1
- **高危问题**: 4
- **中危问题**: 2
- **建议优化**: 3
## 🐛 发现的问题
### <font color="red">[语法错误] 未定义的变量 `qrcode` 导致运行时报错</font>
- **严重程度**: <font color="red">严重</font>
- **文件**: `web/Hi-Zan/Hi-Zan/pages/table-tennis/scan-order/scan-order.js`
- **行号**: 约 188 行
- **问题描述**: 在 `openRoomCheckPackageTime` 方法的回调中,调用了 `this.exchange('qr_code', qrcode)`。变量 `qrcode` 在当前作用域中并未定义,根据上下文逻辑,此处应为传入的参数 `qr_code`。该错误将直接触发 `ReferenceError`,阻断扫码兑换流程。
- **修复建议**: 将 `qrcode` 修正为 `qr_code`。
```javascript
// 错误
this.exchange('qr_code', qrcode)
// 正确
this.exchange('qr_code', qr_code)
```
### <font color="red">[跨文件调用] 引用的模型/行为文件未在提供的项目结构中定义</font>
- **严重程度**: <font color="red">高危</font>
- **文件**: `package.js`, `scan-order.js`
- **行号**: 约 3-6 行, 3-8 行
- **问题描述**: 代码中通过 `import` 引用了 `../../../models/billiards`、`../../../models/room`、`../../../models/reward`、`../../../models/reserve`、`../../../models/user` 及 `../../../behaviors/themeBehavior`。但提供的「项目结构」仅包含 PHP 系统文件,**未包含任何 JS 模型或配置文件**。无法验证这些模块是否存在,也无法验证其导出的方法(如 `getRoomPackageList`, `tuanGouExchange`, `openRoomCheckPackageTime` 等)签名是否匹配。若文件缺失或导出方式不符,将导致模块加载失败。
- **修复建议**: 请确保对应相对路径下的 `.js` 文件已正确创建,且使用 `export class` 或 `export default` 正确导出。建议补充前端模型文件清单以便进行完整交叉验证。
### [逻辑 BUG] `setData` 异步特性导致 `onHourTap` 读取到旧数据引发崩溃
- **严重程度**: 高危
- **文件**: `web/Hi-Zan/Hi-Zan/pages/table-tennis/package/package.js`
- **行号**: 约 108 行
- **问题描述**: 在 `getRoomPackageList` 回调中,调用 `this.setData` 更新 `hour_list` 后,立即同步调用了 `this.onHourTap(...)`。微信小程序的 `setData` 是异步的,此时 `this.data.hour_list` 尚未更新(仍为空数组)。`onHourTap` 内部执行 `const hour = this.data.hour_list[index].hour` 时,会尝试读取 `undefined` 的属性,抛出 `TypeError`。
- **修复建议**: 使用 `setData` 的回调函数确保数据更新后再执行依赖逻辑,或直接使用局部变量计算。
```javascript
this.setData({
hour_list: res.result.hour_list,
// ...其他字段
}, () => {
// 确保 setData 完成后再调用
this.onHourTap({ currentTarget: { dataset: { index: 0, item: hourList[0] } } })
})
```
### [逻辑 BUG] 直接修改 `data` 对象属性违反小程序规范
- **严重程度**: 高危
- **文件**: `web/Hi-Zan/Hi-Zan/pages/table-tennis/scan-order/scan-order.js`
- **行号**: 约 158 行
- **问题描述**: `toggleRuleInfo` 方法中直接执行了 `this.data.package_coupon_list[index].openRules = !...`。微信小程序官方明确禁止直接修改 `data` 对象,这会导致视图层与逻辑层状态不同步,且在某些基础库版本中会触发警告或渲染异常。
- **修复建议**: 使用 `setData` 配合动态路径更新,或深拷贝后整体替换。
```javascript
const key = `package_coupon_list[${index}].openRules`
this.setData({ [key]: !this.data.package_coupon_list[index].openRules })
```
### [安全隐患] URL 参数拼接未进行编码,存在路由解析异常风险
- **严重程度**: 高危
- **文件**: `package.js`, `scan-order.js`
- **行号**: 多处(如 `package.js` 约 135 行, `scan-order.js` 约 125 行)
- **问题描述**: 多个 `wx.navigateTo` 使用字符串拼接 `+ this.data.room_id +` 等方式传递参数。若业务数据中包含 `&`, `?`, `=`, `#` 或空格等特殊字符,将破坏 URL 结构,导致目标页面 `options` 解析错乱或路由拦截失败。
- **修复建议**: 统一使用模板字符串配合 `encodeURIComponent()` 进行安全编码。
```javascript
url: `/pages/community-reserve/pay/pay?room_id=${encodeURIComponent(this.data.room_id)}&package_id=${encodeURIComponent(packageItem.id)}&...`
```
### <font color="red">[未定义变量] 状态字段 `agreement` 未在 `data` 中初始化</font>
- **严重程度**: <font color="red">高危</font>
- **文件**: `web/Hi-Zan/Hi-Zan/pages/table-tennis/scan-order/scan-order.js`
- **行号**: 约 244 行
- **问题描述**: `onGetPhoneNumber` 中调用了 `this.setData({ agreement: true, ... })`,但页面初始 `data` 中并未声明 `agreement` 字段。虽然小程序允许动态添加,但会导致状态管理混乱,且极易与已有的 `agreeMobileAuth` 字段产生语义冲突。
- **修复建议**: 在 `data` 初始化中显式声明 `agreement: false`,或确认业务意图是否应为更新 `agreeMobileAuth`。
### [代码质量] 多处使用 `==` 而非 `===` 进行类型比较
- **严重程度**: 中危
- **文件**: `package.js`, `scan-order.js`
- **行号**: 多处(如 `item.status == '-1'`, `res.result.enough_time == -1`, `type == 'agreement'`)
- **问题描述**: JavaScript 中 `==` 会进行隐式类型转换,在复杂业务逻辑中可能引发难以排查的边界条件错误。
- **修复建议**: 全局替换为严格相等运算符 `===`,提升代码健壮性。
## ✅ 代码亮点
1. **结构清晰**:页面逻辑与数据模型分离良好,通过 `import` 引入独立 Model 类,符合模块化开发规范。
2. **交互体验完善**:合理使用了微信小程序的 `wx.navigateTo`、`wx.scanCode`、`wx.getPhoneNumber` 等 API,并配合弹窗(`showCrossTimePop`, `showAuthPop`)处理边界状态。
3. **动态 Tab 控制**:`package.js` 中根据接口返回的 `package_list` 和 `hour_list` 动态渲染 Tab 列表,提升了页面的灵活性。
## 📝 总体建议
1. **框架上下文说明**:提供的「项目结构」为 PHP CodeIgniter 框架目录,但变更文件为微信小程序前端 JS 代码。本次审查已针对小程序特性进行深度分析。若需进行 PHP/CI 后端审查,请补充对应的 Controller/Model 文件。
2. **异步编程规范**:小程序中 `setData` 为异步操作,后续依赖该数据的逻辑务必放入 `setData` 的回调函数中,或使用 `async/await` 封装 Promise 化请求。
3. **统一错误处理**:当前所有 Model 回调均未处理网络异常或业务失败状态(如 `res.result.status !== '1'` 或 `res.code !== 200`)。建议封装统一的请求拦截器,或在每个回调中补充 `else` 分支的 `wx.showToast` 提示。
4. **常量管理**:`operational_scene` 的枚举值(`1ktv 2台球 3棋牌 4酒馆`)硬编码在注释中,建议提取至 `config.js` 或独立常量文件,避免魔法字符串散落。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1781000211
|
1781000211
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
652
|
21
|
299
|
1
|
|
0
|
🔍 代码审查报告:pay-260616 - Merge remote-tracking branch 🔍 代码审查报告:pay-260616 - Merge remote-tracking branch 'pay/pay-260616' into...
|
## 自动代码审查报告
**分支**: pay-260616
**提交**: `e3eea539a ## 自动代码审查报告
**分支**: pay-260616
**提交**: `e3eea539ab8ef712c7d9fcb5b23ccc1418107d13`
**提交人**: zhangjunnan (121158035@qq.com)
**时间**: 2026-06-09 18:42:10
---
## 📋 审查摘要
- **变更文件数**: 5
- **严重问题**: 1
- **高危问题**: 3
- **中危问题**: 2
- **建议优化**: 4
## 🐛 发现的问题
### <font color="red">[语法错误] 文件内容被意外截断导致语法解析失败</font>
- **严重程度**: <font color="red">严重</font>
- **文件**: `application/models/Ahead_shop_group_buying_coupon_model.php`
- **行号**: 文件末尾(约第 100 行)
- **问题描述**: 提供的代码在 `if (!empty($same` 处突然中断,缺少闭合括号、分号及后续逻辑。若直接部署将导致 PHP 解析致命错误(Parse Error)。
- **修复建议**: 补全缺失的代码逻辑,确保语法完整。例如:
```php
if (!empty($same_package_room_type)) {
// 补充完整逻辑
}
// 确保类和方法正确闭合
}
```
### <font color="red">[跨文件调用] 模型加载命名大小写不一致可能导致Linux环境致命错误</font>
- **严重程度**: <font color="red">高危</font>
- **文件**: `application/controllers/mini/hz/Book.php`, `application/models/Ahead_book_order_model.php`, `application/models/Ahead_shop_config_second_model.php`
- **行号**: 多处(如 `Book.php` 第 338, 345 行;`Ahead_book_order_model.php` 第 188, 225 行等)
- **问题描述**: CodeIgniter 的 `$this->load->model()` 在 Linux 等大小写敏感的文件系统中,会严格匹配文件名。代码中混用了 `Ahead_xxx_model`(首字母大写)和 `ahead_xxx_model`(全小写)。若实际文件名为小写,加载大写名称将直接抛出 `Unable to locate the model you have specified` 致命错误。
- **修复建议**: 统一模型加载命名规范。建议全部使用小写或遵循 CI 官方推荐的首字母大写+下划线格式,并确保与磁盘文件名完全一致。
```php
// 推荐统一为小写加载(CI会自动处理首字母大写映射)
$this->load->model('ahead_book_invite_model');
$this->load->model('ahead_sms_config_model');
$this->load->model('ahead_ai_audio_player_content_model');
```
### <font color="red">[跨文件调用] 调用了未在当前上下文中验证的方法</font>
- **严重程度**: <font color="red">高危</font>
- **文件**: `application/models/Ahead_book_order_operation_log_model.php`
- **行号**: 约第 85 行
- **问题描述**: 调用了 `$this->ahead_book_order_model->get_order_by_bill($bill_data);`。在提供的 `Ahead_book_order_model.php` 代码片段中未找到 `get_order_by_bill` 方法定义。若该方法不存在或签名不匹配,将触发 `Call to undefined method` 错误。
- **修复建议**: 确认 `Ahead_book_order_model` 中是否已定义 `get_order_by_bill` 方法。若未定义,需补充实现;若已定义,请确保方法签名与调用处参数一致。
### [安全隐患] SQL注入风险(Where条件字符串直接拼接)
- **严重程度**: 高危
- **文件**: `application/models/Ahead_book_order_model.php`
- **行号**: 约第 330 行
- **问题描述**: `$log_where = '_relation_id="' . $order_data['_id'] . '" and _status=1 and _type in (5,13)';` 使用字符串拼接构造 SQL 条件。虽然 `$order_data['_id']` 当前来自数据库查询,但若未来数据来源变更或包含特殊字符,极易引发 SQL 注入或语法错误。
- **修复建议**: 使用 CI 查询构造器(Query Builder)安全绑定参数:
```php
$this->db->where('_relation_id', $order_data['_id']);
$this->db->where('_status', 1);
$this->db->where_in('_type', [5, 13]);
$this->db->update('pay_log', $log_up);
```
### [逻辑 BUG] 死代码/无效条件判断导致功能未生效
- **严重程度**: 高危
- **文件**: `application/controllers/mini/hz/Book.php`
- **行号**: 约第 233 行
- **问题描述**: `if (false && $order_id) { ... }` 条件永远为 `false`,导致内部的邀请函跳转逻辑完全失效。这属于典型的调试遗留代码或逻辑错误。
- **修复建议**: 移除硬编码的 `false`,恢复正确的业务判断条件:
```php
// 修复前
if (false && $order_id) {
// 修复后
if ($order_id) {
```
### [代码质量] 违反单一职责原则的超长 Switch 语句
- **严重程度**: 中危
- **文件**: `application/models/Ahead_shop_config_second_model.php`
- **行号**: 约第 130 ~ 330 行
- **问题描述**: `get_shop_setting` 方法中的 `switch` 语句超过 200 行,包含大量重复的默认值赋值和场景判断逻辑。代码可读性差,维护成本高,且容易引发合并冲突。
- **修复建议**: 将配置映射提取为类属性数组,或使用策略模式/配置数组映射简化逻辑:
```php
protected $config_defaults = [
'book_trial_time' => 0,
'turn_on_the_ac_early' => 10,
// ... 其他默认值
];
// 在方法中直接返回 $this->config_defaults[$field] ?? $data[$field] ?? '';
```
### [代码质量] 重复加载同一模型
- **严重程度**: 低危
- **文件**: `application/models/Ahead_book_order_model.php`
- **行号**: 约第 208, 210 行
- **问题描述**: 在 `_check_param` 方法中,`$this->load->model('ahead_room_type_book_log_model');` 被连续加载了两次。CI 的 Loader 具有单例缓存机制,重复加载虽不报错,但浪费性能且影响代码整洁度。
- **修复建议**: 删除重复的加载语句,保留一次即可。
### [代码质量] 控制器基类引入方式不规范
- **严重程度**: 低危
- **文件**: `application/controllers/mini/hz/Book.php`
- **行号**: 第 3 行
- **问题描述**: 使用 `include FCPATH . 'application' . DIRECTORY_SEPARATOR ... 'Index.php';` 手动引入父控制器。这破坏了 CI 的自动加载机制,且在 Windows/Linux 路径分隔符处理上存在隐患。
- **修复建议**: 将 `Index` 控制器移至 `application/core/MY_Controller.php` 或 `application/controllers/BaseController.php`,并通过 CI 的自动加载或 `require_once APPPATH.'controllers/mini/hz/Index.php';` 规范引入。
## ✅ 代码亮点
1. **事务管理完善**:在 `Ahead_book_order_model.php` 的支付回调和退款逻辑中,正确使用了 `$this->db->trans_start()`、`trans_complete()` 和 `trans_rollback()`,并配合 `try-catch` 保证了数据一致性。
2. **防刷机制**:在 `Book.php` 的关键下单接口(如 `createCommunityShopBookOrder`、`aiBookChangeRecommend`)中调用了 `request_frequency()`,有效防止恶意并发请求。
3. **配置缓存优化**:`Ahead_shop_config_second_model.php` 使用 `public static $shop_config` 进行门店配置缓存,减少了重复的数据库查询,提升了接口响应性能。
## 📝 总体建议
1. **统一命名规范**:严格遵循 CodeIgniter 的模型/库命名规范(文件 PascalCase,加载小写),避免跨平台部署时的致命错误。
2. **清理调试代码**:全面排查代码中的 `if (false && ...)`、注释掉的旧逻辑及未使用的变量,保持代码库整洁。
3. **安全加固**:所有涉及数据库查询的 `WHERE` 条件必须使用 CI 的 Query Builder 或预处理语句,杜绝字符串拼接。对 `$_POST`/`$this->param` 传入的数据进行严格的类型转换和过滤。
4. **重构臃肿方法**:建议将 `Ahead_shop_config_second_model::get_shop_setting` 拆分为独立的配置读取类或使用配置数组映射,降低圈复杂度(Cyclomatic Complexity)。
5. **补全截断文件**:务必确认 `Ahead_shop_group_buying_coupon_model.php` 的完整代码,当前状态无法通过语法检查,存在上线阻断风险。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1781001731
|
1781001731
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
653
|
21
|
300
|
1
|
|
0
|
🔍 代码审查报告:pay-260616 - 现场扫码退款
|
## 自动代码审查报告
**分支**: pay-260616
**提交**: `1de21f249 ## 自动代码审查报告
**分支**: pay-260616
**提交**: `1de21f24942458f96482e04d4bf8b4502dfe44e4`
**提交人**: LITTLEMAIDI (11833999+littlemaidi@user.noreply.gitee.com)
**时间**: 2026-06-09 19:12:04
---
## 1. 审查摘要
- **代码质量评分**:6.5 / 10 分
- **总体评价**:代码实现了较为复杂的预订、支付回调、退款及账单聚合业务,整体业务闭环完整。但存在明显的架构反模式、事务与外部API耦合、SQL注入风险、N+1查询性能瓶颈以及硬编码敏感信息等问题。部分方法逻辑冗长,缺乏常量抽象与错误边界控制。
- **风险等级**:🔴 高(存在致命运行时错误、SQL注入隐患及事务锁表风险)
> 📌 **框架说明**:从 `$CI = &get_instance()`、`$this->load->model()`、`$this->db->trans_start()` 等特征判断,当前代码基于 **CodeIgniter 3** 架构开发。若 `phpci` 为内部定制框架,以下建议仍完全适用,请结合官方文档微调生命周期调用。
---
## 2. 问题详情
| 严重程度 | 文件/行号 | 问题描述 | 建议修改方案 | 代码示例 (可选) |
| :--- | :--- | :--- | :--- | :--- |
| 🔴 严重 | `Ahead_yc_notice_model.php`<br>`insert_after` 方法 | 将布尔属性 `$this->push_notice` 当作方法调用:`return $this->push_notice($arr);`,将直接触发 `Fatal Error: Function name must be a string` 导致服务崩溃。 | 明确区分属性与方法名,或改为条件判断后调用同名方法。 | `if ($this->push_notice === true) { return $this->push_notice($arr); }` |
| 🔴 严重 | `Ahead_yc_order_model.php`<br>`get_bill_goods_info` | 直接字符串拼接 SQL 条件:`$sql = '_unique_key="' . $unique_key . '" ...'`,未做任何过滤或参数绑定,存在高危 SQL 注入漏洞。 | 全面改用 CI 查询构造器或参数绑定,杜绝手动拼接。 | `$this->db->where('_unique_key', $unique_key)->where('_status IN (1,4)')->get($this->table_name)->result_array();` |
| 🔴 严重 | `Ahead_book_order_model.php`<br>`check_notify` & `refund_by_notify` | 数据库事务中包裹了外部支付退款 API 调用(如 `WxPayApi::refund`)。网络请求耗时不可控,极易导致数据库连接池耗尽、长事务锁表或超时回滚失败。 | **事务与外部调用必须解耦**。先更新本地状态并提交事务,再通过异步队列、定时任务或独立流程调用退款接口,最后通过回调对账。 | 移除 `refund_by_notify` 中的 `WxPayApi` 调用,改为记录退款任务表,由 Cron 或消息队列异步执行。 |
| 🟠 警告 | `Ahead_book_order_model.php`<br>`check_notify` | 事务回滚逻辑不完整。当 `refund_by_notify` 返回 `['status'=>false]` 时,方法直接 `return`,未显式执行 `$this->db->trans_rollback()`,依赖框架隐式行为存在脏数据风险。 | 统一使用 `$this->db->trans_begin()`、`trans_commit()`、`trans_rollback()` 显式控制,或在所有异常/失败分支前显式回滚。 | `if (!$res['status']) { $this->db->trans_rollback(); return $res; }` |
| 🟠 警告 | `Ahead_book_order_model.php`<br>`get_list` | 循环内执行数据库查询:`foreach ($order_info as &$v) { $merchant_data = $this->ahead_merchant_model->get_one(...); }`,典型 N+1 查询问题,数据量增长时性能呈指数级下降。 | 提取所有 `merchant_id` 使用 `where_in` 批量查询,或在主查询中使用 `JOIN` 一次性获取。 | `$ids = array_column($order_info, 'merchant_id'); $merchants = $this->ahead_merchant_model->where_in('_id', $ids)->get()->result_array();` |
| 🟠 警告 | `Ahead_yc_order_model.php`<br>类属性定义 | 硬编码加密密钥:`public $encrypt = "Vs!Fs7VT";`。密钥随代码库分发,违反安全规范,一旦仓库泄露将导致历史数据可被解密。 | 移至 `config/config.php` 或 `.env` 环境变量中,通过配置项读取。 | `protected $encrypt_key; public function __construct() { $this->encrypt_key = config_item('encrypt_key'); }` |
| 🟡 建议 | 全局多处 | 大量使用魔法数字(如状态 `-1, 1, 2, 3, 4, 5`,支付平台 `1, 3, 14, 22` 等),业务含义不透明,维护成本高。 | 定义类常量或独立枚举类,提升可读性与可维护性。 | `const STATUS_PENDING = -1; const PAY_PLATFORM_WECHAT = 1;` |
| 🟡 建议 | `Ahead_book_order_model.php`<br>文件顶部 | 顶部直接使用 `$CI = &get_instance();` 加载模型。在 CI 架构中,模型文件被 `include` 时即执行,此时 CI 核心可能未完全初始化,易引发未定义变量或加载失败。 | 移除顶部代码,在类构造函数或具体方法内按需 `$this->load->model()`。 | 删除顶部两行,在 `__construct()` 中调用 `$this->load->model('Simple_model');` |
| 🟡 建议 | `send_success_msg` 等方法 | 存在大量注释掉的废弃代码(如旧版短信发送逻辑、时间判断分支),且变量拼写错误 `$rooom_data`。 | 清理无用注释代码,依赖 Git 管理历史版本;修正拼写错误。 | 删除 `/* ... */` 块,将 `$rooom_data` 改为 `$room_data`。 |
| 🟡 建议 | `Ahead_book_order_model.php`<br>`create_community_shop_book_order` | 代码在 `if ($this->tuangou->verify_token) {` 处被截断,无法评估后续逻辑完整性与事务闭合情况。 | 补充完整代码后重新提交审查,确保 `trans_complete()` 或 `trans_rollback()` 成对出现。 | *(需补充完整代码)* |
---
## 3. 总结与行动建议
### 🚨 优先修复项(P0)
1. **修复致命调用错误**:立即修正 `Ahead_yc_notice_model::insert_after` 中的属性/方法名冲突,避免线上 Fatal Error。
2. **消除 SQL 注入风险**:将 `get_bill_goods_info` 及 `refund_by_notify` 中所有手动拼接的 SQL 条件替换为 CI 查询构造器或参数绑定。
3. **事务与外部调用解耦**:将微信支付/银联退款等网络请求移出数据库事务。采用“本地状态更新 → 提交事务 → 异步退款任务 → 回调对账”的标准支付架构。
### 🛠 后续重构与优化方向
1. **架构规范化**:
- 移除文件顶部的 `$CI = &get_instance();`,遵循 CI 模型生命周期。
- 统一使用 `$this->db->trans_begin()` / `trans_commit()` / `trans_rollback()` 替代 `trans_start()` + `try/catch` 的混合写法,提升事务可控性。
2. **性能与可维护性**:
- 消除 N+1 查询,对列表类接口采用批量查询或 `JOIN` 优化。
- 提取魔法数字为类常量(如 `OrderStatus::PAID`、`PayPlatform::WECHAT`),必要时引入 PHP 8.1+ `enum`。
- 拆分超长方法(如 `get_bill_goods_info` 超过 300 行),按职责拆分为 `calculateTotals()`、`mergeGoods()`、`formatBill()` 等私有方法。
3. **安全与规范**:
- 敏感配置(加密串、API 密钥、模板 ID)全部迁移至配置文件或环境变量。
- 清理历史注释代码,统一数组语法为 `[]`,遵循 PSR-12 命名与缩进规范。
- 日志记录避免直接输出 `$e->getTrace()`,改为记录 `$e->getMessage()` 与 `$e->getFile().':'.$e->getLine()`,防止敏感路径泄露。
> 💡 **提示**:若 `phpci` 为内部封装框架,请确认其事务管理器与 CI3 原生行为是否一致。建议在核心支付链路补充单元测试(PHPUnit)与集成测试,覆盖正常支付、退款失败、并发扣减库存等边界场景。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1781003524
|
1781003524
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
654
|
21
|
301
|
1
|
|
0
|
🔍 代码审查报告:pay-260616 - 现场扫码订单
|
## 自动代码审查报告
**分支**: pay-260616
**提交**: `f8aa117ea ## 自动代码审查报告
**分支**: pay-260616
**提交**: `f8aa117ea568aecfd6537e9b87159c6681f47c2b`
**提交人**: LITTLEMAIDI (11833999+littlemaidi@user.noreply.gitee.com)
**时间**: 2026-06-09 19:15:57
---
## 1. 审查摘要
- **代码质量评分**:5.5 / 10 分
- **总体评价**:业务逻辑覆盖较为完整,但存在明显的架构与编码缺陷。核心问题集中在 **N+1 查询导致的性能瓶颈**、**SQL 拼接注入风险**、**缺乏事务保护**以及**敏感信息硬编码**。代码风格偏向老旧的 CI2/3 写法,未充分利用现代 PHP 特性与查询构建器,且单一方法职责过重,可维护性较低。
- **风险等级**:🔴 高
---
## 2. 问题详情
| 严重程度 | 文件/行号 | 问题描述 | 建议修改方案 | 代码示例 (可选) |
| :--- | :--- | :--- | :--- | :--- |
| 🔴 严重 | `get_bill_goods_info` (~L200) | **SQL 注入风险**:使用字符串拼接构造查询条件 `$sql = '_unique_key="' . $unique_key . '" ...'` 并直接传入 `$this->select()`。若 `$unique_key` 来源不可控,将导致严重注入漏洞。 | 废弃字符串拼接,改用框架查询构建器(Query Builder)或参数绑定机制。 | `$this->db->where('_unique_key', $unique_key)->where_in('_status', [1,4])->get($this->table_name)->result_array();` |
| 🔴 严重 | `confirm_receipt` (~L155) | **数据一致性风险**:连续执行两次 `insert` 操作未包裹在数据库事务中。若第二次插入失败,将产生状态不一致的脏数据。 | 使用框架事务机制包裹关键写入操作,失败时自动回滚。 | `见下方事务示例` |
| 🔴 严重 | 类属性定义 (~L10) | **敏感信息硬编码**:加密串 `public $encrypt = "Vs!Fs7VT";` 直接暴露在源码中,易随版本控制泄露,且不利于多环境配置管理。 | 移至配置文件或环境变量,通过配置项动态读取。 | `protected $encrypt; public function __construct(){ parent::__construct(); $this->encrypt = config_item('order_encrypt_key'); }` |
| 🟠 警告 | `get_list` (~L75) | **严重性能瓶颈 (N+1 查询)**:在 `foreach` 循环内动态加载模型并执行单条查询。订单量超 50 时将引发数据库连接池耗尽与响应超时。 | 提前收集所有 `package_id`,使用 `WHERE IN` 批量查询,在内存中完成数据映射。 | `见下方批量查询示例` |
| 🟠 警告 | `get_detail` (~L115) | **冗余查询与未使用变量**:`$order_data['before_payment']` 赋值后从未返回或参与逻辑;在自身模型内调用 `$this->ahead_yc_order_model->get_one()` 属于冗余加载。 | 移除无效赋值;直接复用 `$this->get_one()`;合并重复的模型加载。 | `// 移除 $order_data 赋值块<br>// 改为: $before_order = $this->get_one(['_id' => $order_info['before_order_id']]);` |
| 🟠 警告 | `encode_group_buying_order` (~L310) | **弱加密算法**:使用 `md5()` 进行签名校验。MD5 已被证实存在碰撞漏洞,不适用于安全签名或防篡改场景。 | 改用 `hash_hmac('sha256', $data, $key)` 提供强加密签名。 | `return hash_hmac('sha256', $order_id, $this->encrypt);` |
| 🟡 建议 | 文件顶部 (~L4) | **框架生命周期误用**:`$CI = &get_instance();` 在类外部执行,文件被 `include` 时即触发,可能在框架未完全初始化时引发 Fatal Error。 | 移至构造函数中,或直接使用 `$this->load->` 链式调用。 | `public function __construct() { parent::__construct(); $this->load->model('Simple_model'); }` |
| 🟡 建议 | 全局/多处 | **违反 PSR-12 与单一职责**:类名 `Ahead_yc_order_model` 非驼峰;`get_bill_goods_info` 超 300 行,混合了数据查询、金额计算、格式化与业务分支。 | 类名改为 `AheadYcOrderModel`;将大方法拆分为 `fetchBillData()`、`calculateTotals()`、`formatGoods()`。 | `// 遵循 PSR-12<br>class AheadYcOrderModel extends Simple_model { ... }` |
| 🟡 建议 | `binding_order_check` (~L335) | **未定义属性引用**:使用 `$this->uid`,但类中未声明或初始化,依赖隐式全局或父类,破坏封装性。 | 显式声明属性,或通过方法参数/Session 安全注入。 | `protected $current_uid; public function set_current_uid(int $uid): void { $this->current_uid = $uid; }` |
### 🔧 关键代码修复示例
**1. 数据库事务保护 (`confirm_receipt`)**
```php
public function confirm_receipt($order_info, $aheaduid, $aheaduname, $star = 5)
{
$this->db->trans_start(); // 开启事务
// ... 前置校验逻辑 ...
$data = [
'_order_id' => $order_id,
'_process' => 7,
'_process_msg' => $aheaduname . ' - 已确认收货',
'_process_time' => time(),
'_ahead_user_id' => $aheaduid,
'_ahead_user_name' => $aheaduname,
'_star' => $star
];
$this->ahead_yc_order_process_model->insert($data);
$data['_process'] = 8;
$data['_process_msg'] = '订单完成';
$this->ahead_yc_order_process_model->insert($data);
$this->db->trans_complete(); // 提交事务
if ($this->db->trans_status() === FALSE) {
$this->db->trans_rollback();
return ['code' => false, 'msg' => '确认收货失败,数据已回滚'];
}
// ... 推送消息逻辑 ...
return ['code' => true, 'msg' => '确认收货成功'];
}
```
**2. 消除 N+1 查询 (`get_list` 优化思路)**
```php
// 优化前:循环内查库
// 优化后:批量查询 + 内存映射
$package_ids = array_filter(array_column($order_info, 'package_id'));
$package_imgs = [];
if ($package_ids) {
$this->load->model("ahead_room_package_model");
$this->load->model("ahead_wares_package_model");
// 假设框架支持 where_in 批量查询
$room_pkgs = $this->ahead_room_package_model->select(['_id' => $package_ids, 'where_in' => ['_id', $package_ids]], '_id,_img_url');
$wares_pkgs = $this->ahead_wares_package_model->select(['_id' => $package_ids, 'where_in' => ['_id', $package_ids]], '_id,_img_url');
foreach ($room_pkgs as $pkg) $package_imgs[$pkg['_id']] = $pkg['_img_url'] ?? DEFAULTIMG;
foreach ($wares_pkgs as $pkg) $package_imgs[$pkg['_id']] = $pkg['_img_url'] ?? DEFAULTIMG;
}
foreach ($order_info as &$val) {
$val['img'] = $package_imgs[$val['package_id']] ?? DEFAULTIMG;
// ... 其他字段处理 ...
}
```
---
## 3. 总结与行动建议
### 🚨 优先修复项(P0/P1)
1. **修复 SQL 注入**:立即将 `get_bill_goods_info` 中的字符串拼接替换为参数化查询或 Query Builder。
2. **补充事务控制**:为所有涉及多表写入或状态流转的方法(如 `confirm_receipt`、`bindingOrder`)添加事务包裹。
3. **移除硬编码密钥**:将 `$encrypt` 迁移至 `config/application.php` 或 `.env` 文件,并通过 `config_item()` 读取。
4. **解决 N+1 查询**:重构 `get_list` 与 `get_detail` 中的循环查库逻辑,改为批量查询+内存映射,预计可提升 80% 以上的列表接口响应速度。
### 🛠 后续重构方向
1. **方法职责拆分**:`get_bill_goods_info` 严重违反单一职责原则(SRP)。建议拆分为:
- `fetchRawBillData()`:负责纯数据查询
- `calculateFinancials()`:负责金额、折扣、积分计算
- `formatBillResponse()`:负责视图层数据格式化
2. **统一常量管理**:当前类中同时存在 `public $pay_id_arr` 和 `const ORDER_PAY_PLATFORM_ARR` 等重复定义。建议统一使用 `const` 或 `enum`(PHP 8.1+),并移除魔法数字。
3. **异常处理规范化**:将自定义的 `throwError()` 替换为 PHP 标准异常 `\Exception` 或框架提供的 `show_error()`,便于全局错误捕获与日志记录。
4. **类型声明与严格模式**:在文件头部添加 `declare(strict_types=1);`,并为方法参数与返回值添加类型提示(如 `int`, `array`, `bool`),提升代码健壮性。
> ⚠️ **局限性说明**:提交的代码在 `get_timing_order` 方法处被截断,未能审查完整逻辑。若该方法涉及核心计费或状态机流转,请补充完整代码以便进行二次深度审查。
> 📖 **框架适配提示**:基于代码结构(`get_instance()`、`system/` 目录、`$this->load->model()`),判定为基于 CodeIgniter 3 架构的定制框架(phpci)。上述事务与 Query Builder 语法均兼容 CI3 标准,若 phpci 有自定义封装,请以官方文档的 `DB` 驱动 API 为准。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1781003757
|
1781003757
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
655
|
21
|
302
|
1
|
|
0
|
🔍 代码审查报告:pay-260616 - 开房订单申请退款
|
## 自动代码审查报告
**分支**: pay-260616
**提交**: `75d502a79 ## 自动代码审查报告
**分支**: pay-260616
**提交**: `75d502a7967d58d46a34c788d574131fe3900efe`
**提交人**: LITTLEMAIDI (11833999+littlemaidi@user.noreply.gitee.com)
**时间**: 2026-06-09 19:26:01
---
## 1. 审查摘要
- **代码质量评分**:5/10 分
- **总体评价**:代码实现了订单创建、支付路由、账单统计等核心业务,但存在明显的架构反模式与安全/性能隐患。大量硬编码、重复的支付逻辑、循环内动态加载模型以及不规范的参数传递方式,严重影响了系统的可维护性与运行效率。整体偏向老旧的 CodeIgniter 3 风格,与现代 PHP 工程规范存在差距。
- **风险等级**:🔴 高(存在 SQL 注入隐患、敏感信息硬编码、越权删除风险及严重性能瓶颈)
## 2. 问题详情
| 严重程度 | 文件/行号 | 问题描述 | 建议修改方案 | 代码示例 (可选) |
| :--- | :--- | :--- | :--- | :--- |
| 🔴 严重 | `Ahead_yc_order_model.php`<br>文件顶部/类外 | **模型依赖加载位置错误**:在类外部直接执行 `$CI = &get_instance(); $CI->load->model('Simple_model');`。这会在文件被 `include/require` 时立即执行,破坏框架生命周期,且可能导致全局状态污染。 | 移除文件顶部的加载逻辑,模型应通过 `extends Simple_model` 继承,并在构造函数中调用 `parent::__construct()`。 | `class Ahead_yc_order_model extends Simple_model { public function __construct() { parent::__construct(); } }` |
| 🔴 严重 | `Ahead_yc_order_model.php`<br>`get_bill_goods_info` 方法内 | **SQL 注入风险**:使用字符串拼接构建查询条件 `$sql = '_unique_key="' . $unique_key . '" AND ...'`,若 `$unique_key` 未经严格过滤直接传入底层查询,将导致注入。 | 全面使用框架查询构造器或参数绑定,禁止手动拼接 SQL 条件字符串。 | `$this->db->where('_unique_key', $unique_key)->where('_status IN (1,4)')->get();` |
| 🔴 严重 | `Ahead_yc_order_model.php`<br>`delete_one` 方法 | **越权删除隐患**:当 `$uid = 0` 时,`if ($uid)` 条件不成立,直接执行软删除,未校验订单归属权。攻击者可传入 `0` 或空值删除任意订单。 | 强制要求传入有效用户 ID,或从 Session/Token 中获取当前用户 ID,禁止依赖外部可控参数。 | `if (empty($uid)) { throwError('用户身份校验失败'); } $where['_ahead_user_id'] = $uid;` |
| 🟠 警告 | `Ahead_yc_order_model.php`<br>`get_list` 方法 | **N+1 查询性能瓶颈**:在 `foreach` 循环内动态 `load->model()` 并执行 `get_one()`。订单量稍大时将导致数据库连接耗尽与响应超时。 | 提前收集所有 `package_id`,使用 `WHERE IN` 一次性批量查询,再通过 PHP 数组映射回填数据。 | 收集 `$ids` → `$this->db->where_in('_id', $ids)->get()->result_array()` → 建立映射表 `$map[$id]` 供循环使用。 |
| 🟠 警告 | `Order.php`<br>`check_params` 方法 | **参数来源不一致**:方法签名接收 `$param`,但在 `else` 分支中直接使用 `$this->param['family_server_id']`。若调用方未同步更新 `$this->param`,将引发 `Undefined index` 或逻辑错乱。 | 统一使用传入的 `$param` 数组,或在方法开头显式合并:`$param = array_merge($this->param, $param);` | `if ($from != '1') { $family_server_id = $param['family_server_id'] ?? ''; }` |
| 🟠 警告 | `Order.php`<br>`buyRenewalPackage` / `createOrder` | **支付路由逻辑高度重复**:微信支付与国通支付(Chinaums)的判断、参数组装、回调地址拼接在两个方法中几乎完全一致,维护成本极高。 | 提取为私有方法 `generatePaymentPayload($orderData, $payPlatform, $shopId)`,统一处理网关路由。 | 封装支付网关调用,控制器仅负责:`$payData = $this->buildPayParams($order, $platform);` |
| 🟠 警告 | `Ahead_yc_order_model.php`<br>类属性定义 | **敏感信息硬编码**:`public $encrypt = "Vs!Fs7VT";` 直接暴露在源码中,违反安全基线。 | 移至 `config/` 配置文件或环境变量,通过 `config_item()` 或 `getenv()` 动态获取。 | `protected $encrypt; public function __construct() { parent::__construct(); $this->encrypt = config_item('order_encrypt_key'); }` |
| 🟡 建议 | `Order.php` / `Ahead_yc_order_model.php`<br>全局 | **魔法数字泛滥**:大量使用 `1, 2, 4, -1, 10` 表示状态/类型。虽已定义 `const`,但业务逻辑中未全面替换,可读性差且易改错。 | 全面使用已定义的类常量,并在新增状态时同步更新常量映射表。 | `if ($order['type'] == self::ORDER_TIMING_OPEN_ROOM_TYPE)` 替代 `== 5` |
| 🟡 建议 | `Order.php`<br>`do_log` 调用处 | **日志记录敏感数据**:`do_log(var_export($order_add_res['order_data'], 1)...)` 直接打印完整订单数组,可能包含用户手机号、支付密钥等 PII/敏感信息。 | 脱敏处理后再记录,或使用框架标准日志函数,仅记录关键标识符。 | `log_message('debug', 'Pay initiated: order=' . $orderId . ', amount=' . $amount);` |
| 🟡 建议 | `Order.php`<br>文件头部 | **非标准父类引入**:使用 `include FCPATH . 'application' ...` 引入父控制器。现代框架应依赖自动加载或命名空间。 | 移除手动 `include`,确保框架自动加载机制已正确配置父类路径。 | 依赖 Composer 或框架 Autoloader 自动解析 `Index` 类。 |
> 📝 **局限性说明**:`Ahead_yc_order_model.php` 末尾的 `get_timing_order` 方法代码被截断,无法完整评估其查询逻辑与异常处理。建议补充完整代码后二次审查。
## 3. 总结与行动建议
### 🔑 优先修复的关键问题
1. **修复 SQL 注入与越权漏洞**:立即替换 `get_bill_goods_info` 中的字符串拼接查询,并为 `delete_one` 增加强制用户身份校验。
2. **消除 N+1 查询**:重构 `get_list` 方法,将循环内查询改为批量 `IN` 查询或 `JOIN`,预计可降低 80% 以上的数据库 IO 开销。
3. **统一支付逻辑**:将 `buyRenewalPackage` 与 `createOrder` 中的支付网关路由代码抽离为独立服务类或私有方法,遵循 DRY 原则。
### 🛠 后续重构与优化方向
- **架构规范化**:当前代码呈现典型的 CI3 风格。若 `phpci` 为定制框架,请严格遵循其生命周期(如模型构造函数、控制器基类加载)。建议逐步引入依赖注入(DI)容器,替代 `$this->load->model()` 的隐式加载。
- **常量与枚举管理**:将散落在类中的状态数组(如 `$pay_id_arr`, `$type_arr`)统一迁移至独立的 `Enum` 类或配置文件中,业务层仅通过常量引用。
- **日志与安全审计**:建立统一的日志脱敏中间件,禁止在业务代码中直接 `var_export` 敏感数组。支付回调地址建议通过配置中心动态下发,避免硬编码 `PAY_BASE_URL`。
- **测试覆盖**:针对 `check_params` 边界条件、支付状态流转(`pay_status != -1` 分支)、并发关房场景补充单元测试,防止状态机死锁或资损。
> 💡 **框架适配提示**:代码中大量使用 `get_instance()` 与 `$this->load->` 语法,符合 CodeIgniter 3 特征。若 `phpci` 为基于 CI 的二次开发框架,请确认其是否已升级至 PHP 8.x 兼容模式。若为独立微框架,建议逐步替换为 PSR-4 自动加载与标准 MVC 路由,以提升长期可维护性。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1781004361
|
1781004361
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
656
|
21
|
303
|
1
|
|
0
|
🔍 代码审查报告:pay-260616 - 申请退款
|
## 自动代码审查报告
**分支**: pay-260616
**提交**: `9b97b3156 ## 自动代码审查报告
**分支**: pay-260616
**提交**: `9b97b3156adface57571495d2eb22c652b5e440f`
**提交人**: LITTLEMAIDI (11833999+littlemaidi@user.noreply.gitee.com)
**时间**: 2026-06-09 19:35:24
---
## 1. 审查摘要
- **代码质量评分**:5.5 / 10 分
- **总体评价**:业务逻辑覆盖较全面,但存在明显的安全隐患(SQL注入、弱加密签名)、严重的性能瓶颈(N+1查询)以及框架生命周期使用不规范的问题。核心方法 `get_bill_goods_info` 过于臃肿,混合了数据查询、聚合计算与视图格式化逻辑,缺乏事务保护与常量复用。
- **风险等级**:🔴 高
> 📌 **注**:项目目录结构及 `$CI = &get_instance()` 语法高度符合 **CodeIgniter 3** 特征。若 `phpci` 为内部定制框架,请核对底层加载机制。以下审查基于标准 CI3/MVC 最佳实践与 PSR-12 规范。代码末尾存在截断,审查仅基于已提供片段。
---
## 2. 问题详情
| 严重程度 | 文件/行号 | 问题描述 | 建议修改方案 | 代码示例 (可选) |
| :--- | :--- | :--- | :--- | :--- |
| 🔴 严重 | `Ahead_yc_order_model.php`<br>`get_bill_goods_info` 方法 | **SQL 注入漏洞**:直接使用字符串拼接 `$unique_key` 构建 SQL 条件,未进行转义或使用查询构造器。 | 使用 CI3 查询构造器 `$this->db->where()` 自动转义,或显式调用 `$this->db->escape()`。 | `$this->db->where('_unique_key', $unique_key);`<br>`$this->db->where_in('_status', [1, 4]);` |
| 🔴 严重 | `Ahead_yc_order_model.php`<br>L12, L685 | **硬编码密钥与弱加密**:`$encrypt` 为公开属性且硬编码在类中;`encode_group_buying_order` 使用 `md5` 签名,易受碰撞与彩虹表攻击。 | 密钥移至 `config` 或环境变量;签名改用 `hash_hmac('sha256', ...)`。 | `hash_hmac('sha256', $order_id, config_item('order_sign_key'), true)` |
| 🔴 严重 | `Ahead_yc_order_model.php`<br>`get_detail` 方法 | **逻辑缺陷/数据丢失**:`$order_data['before_payment']` 被赋值,但后续未合并至 `$order_info` 且未返回,导致前端无法获取转房前金额。 | 修正变量名,将数据正确挂载到 `$order_info` 数组中。 | `$order_info['before_payment'] = $before_order_info_data['_actual_pay'] ?? '';` |
| 🔴 严重 | `Ahead_yc_order_model.php`<br>`confirm_receipt` 方法 | **缺乏数据库事务**:连续执行两次 `insert` 记录订单状态,若第二次失败或中断,将导致订单状态不一致(卡在“已确认收货”但未“完成”)。 | 使用 CI3 事务机制包裹关键写入操作。 | `$this->db->trans_start();`<br>`// insert 1 & 2`<br>`$this->db->trans_complete();` |
| 🟠 警告 | `Ahead_yc_order_model.php`<br>`get_list` 方法 | **N+1 查询性能瓶颈**:在 `foreach` 循环内频繁 `load->model` 并执行 `get_one` 查询套餐图片。数据量大时将导致严重延迟。 | 提前收集所有 `package_id`,使用 `WHERE IN` 批量查询,或在主 SQL 中使用 `LEFT JOIN`。 | `$ids = array_column($order_info, 'package_id');`<br>`$imgs = $this->db->where_in('_id', $ids)->get('ahead_room_package')->result_array();` |
| 🟠 警告 | `Ahead_yc_order_model.php`<br>L6-L7 | **框架反模式**:模型文件顶部直接调用 `$CI = &get_instance();` 和 `load->model()`。文件被 `include` 时即执行,破坏 CI 生命周期与单例机制。 | 移至 `__construct()` 中,或交由控制器/自动加载器管理。 | `public function __construct() { parent::__construct(); $this->load->model('Simple_model'); }` |
| 🟠 警告 | `Ahead_yc_order_model.php`<br>多处方法 | **重复加载模型**:各业务方法内频繁调用 `$this->load->model()`,增加不必要的 I/O 与内存开销。 | 统一在 `__construct()` 中加载,或配置 `application/config/autoload.php`。 | `public function __construct() { $this->load->model(['ahead_room_package_model', 'ahead_yc_order_extension_model']); }` |
| 🟠 警告 | `Ahead_yc_order_model.php`<br>多处条件判断 | **魔法数字泛滥**:大量使用 `10, 12, 14` 等硬编码判断支付类型/状态,未复用类顶部已定义的 `const`。 | 全面替换为类常量,提升可读性与可维护性。 | `if ($order['_pay_platform'] == self::ORDER_AFTER_PAY_PAYPLATFORM)` |
| 🟡 建议 | `Ahead_yc_order_model.php`<br>L9 | **命名规范不符 PSR-12**:类名使用下划线 `Ahead_yc_order_model`,不符合 PHP 标准驼峰命名规范。 | 重命名为 `AheadYcOrderModel`,并全局替换引用。 | `class AheadYcOrderModel extends Simple_model` |
| 🟡 建议 | `Ahead_yc_order_model.php`<br>L12-L14 | **属性可见性不当**:`$encrypt`, `$pay_id_arr` 等声明为 `public`,易被外部实例意外修改或暴露。 | 改为 `protected` 或 `private`,通过 Getter 方法访问。 | `protected $encrypt = "Vs!Fs7VT";`<br>`protected $pay_id_arr = [...];` |
| 🟡 建议 | `Ahead_yc_order_model.php`<br>`get_bill_goods_info` | **违背单一职责原则 (SRP)**:该方法超 300 行,混合了 SQL 查询、金额聚合、商品格式化、业务规则判断。 | 拆分为 `fetchBillData()`, `calculateTotals()`, `formatGoodsList()` 等私有方法,或抽离至 `OrderBillService`。 | 将聚合逻辑与视图格式化逻辑分离,降低圈复杂度。 |
---
## 3. 总结与行动建议
### 🚨 优先修复项(P0)
1. **修复 SQL 注入**:立即将 `get_bill_goods_info` 中的字符串拼接改为查询构造器或预处理语句。
2. **补充事务控制**:为 `confirm_receipt`、`close_room_after`、`bindingOrder` 等涉及多表写入的方法添加 `$this->db->trans_start()/trans_complete()`。
3. **修正数据丢失 Bug**:将 `get_detail` 中的 `$order_data['before_payment']` 更正为 `$order_info['before_payment']`。
4. **规范框架加载**:移除文件顶部的 `$CI = &get_instance();`,将模型依赖移至构造函数。
### 🛠 后续重构与优化方向
1. **性能优化**:
- 彻底解决 `get_list` 的 N+1 查询问题,改用批量查询或 SQL `JOIN`。
- `get_bill_goods_info` 中的金额汇总(`price_total`, `amount_total` 等)可考虑下沉至数据库层,使用 `SUM()`, `GROUP BY` 替代 PHP 循环累加,大幅降低内存与 CPU 消耗。
2. **安全加固**:
- 废弃 `md5` 签名,全面升级至 `hash_hmac('sha256', ...)` 或 JWT。
- 敏感配置(如 `$encrypt`)必须移出代码库,使用 `.env` 或 CI 的 `config` 文件管理。
3. **架构与规范**:
- 遵循 PSR-12 重命名类文件,统一常量使用,消除魔法数字。
- 将 `get_bill_goods_info` 等巨型方法按 **CQRS** 或 **Service 层** 思想拆分,模型仅负责数据存取,业务逻辑与格式化交由上层处理。
- 补充全局函数(如 `throwError`, `minToStr`, `DEFAULTIMG`)的依赖声明或替换为框架内置方法,避免隐式依赖导致维护困难。
> 💡 **提示**:由于提供的代码在 `get_timing_order` 方法处截断,若该方法包含关键业务逻辑(如订单状态机流转、定时任务触发等),请补充完整代码以便进行闭环审查。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1781004924
|
1781004924
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
657
|
21
|
304
|
1
|
|
0
|
🔍 代码审查报告:pay-260616 - 立即开房申请退款
|
## 自动代码审查报告
**分支**: pay-260616
**提交**: `992fc0cc4 ## 自动代码审查报告
**分支**: pay-260616
**提交**: `992fc0cc44f968c62e20e2681838a93533da9108`
**提交人**: linyangrui (yangruilin888@gmail.com)
**时间**: 2026-06-09 19:40:32
---
## 📋 审查摘要
- **变更文件数**: 4
- **严重问题**: 1
- **高危问题**: 3
- **中危问题**: 3
- **建议优化**: 4
> ⚠️ **框架说明**:本次审查的代码为 **微信小程序 JavaScript** 前端代码,非 PHP CodeIgniter 后端代码。因此 CI 框架特定的模型加载规范(如 `$this->load->model()`)不适用,但已严格按照最高优先级对前端跨文件引用、类/方法存在性进行了等效验证。
## 🐛 发现的问题
### <font color="red">[语法错误] 回调参数与内部变量同名导致重复声明</font>
- **严重程度**: <font color="red">严重</font>
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js`
- **行号**: 约 108 行 (`getOrderDetail` 方法内)
- **问题描述**: 在 `reserveModel.getBookOrderDetail` 的箭头函数回调 `(res) => { ... }` 中,内部使用了 `const res = wx.getStorageSync('handleOpenMachineResultRes')`。在 ES6 严格模式下,同一块级作用域内重复声明 `const` 变量会直接抛出 `SyntaxError: Identifier 'res' has already been declared`,导致页面白屏崩溃。即使不报错,也会覆盖外部传入的 API 响应对象 `res`,导致后续 `res.result` 访问失败。
- **修复建议**: 将内部存储变量重命名,避免与作用域参数冲突:
```javascript
// 修复前
const res = wx.getStorageSync('handleOpenMachineResultRes')
// 修复后
const storageRes = wx.getStorageSync('handleOpenMachineResultRes')
this.handleOpenMachineResult(storageRes)
```
### <font color="red">[跨文件调用] 引用了未提供的模型类及方法,无法验证存在性</font>
- **严重程度**: <font color="red">高危</font>
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js` 及 `apply-refund.js`
- **行号**: 约 4~6 行, 11~13 行, 22 行
- **问题描述**: 代码中通过 `import` 引入了 `ReserveModel`、`CabinetModel` 和 `HTTP`,并调用了大量未在当前变更文件中定义的方法(如 `reserveModel.applyBookRefund`, `reserveModel.openMachine`, `cabinetModel.reOpenCabinetDoor`, `this.request` 等)。由于未提供 `models/reserve.js`、`models/cabinet.js`、`utils/http.js` 的源码,无法确认这些类是否被正确 `export`,以及方法签名是否匹配。若缺失,将直接引发 `ReferenceError` 或 `TypeError`。
- **修复建议**:
1. 确保依赖文件路径正确且存在。
2. 检查 `utils/http.js` 是否导出了 `HTTP` 基类,且包含 `request` 方法。
3. 检查 `models/reserve.js` 和 `models/cabinet.js` 是否完整导出对应类及所有被调用的方法。建议补充这些文件以便进行完整静态分析。
### [安全隐患] 未校验本地存储数据直接访问属性
- **严重程度**: 高危
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js`
- **行号**: 约 95 行 (`onLoad` 方法内)
- **问题描述**: `const uid = wx.getStorageSync('userInfo').uid || ''`。若用户未登录、缓存被清理或 `userInfo` 为 `null`/`undefined`,直接调用 `.uid` 会抛出 `TypeError: Cannot read properties of null (reading 'uid')`,导致页面初始化失败。
- **修复建议**: 使用可选链或安全解构:
```javascript
const userInfo = wx.getStorageSync('userInfo') || {};
const uid = userInfo.uid || '';
```
### [逻辑 BUG] 对象属性重复定义与关键拼写错误
- **严重程度**: 高危
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js`
- **行号**: 约 238 行 (`handleOpenMachineResult` 方法内)
- **问题描述**: `showCancelBtn: false` 在 `setData` 对象中连续定义了两次。虽然 JS 引擎会取最后一次的值,但属于冗余代码且极易引发维护误解。此外,`avilable_room_list` 存在明显拼写错误(应为 `available`),虽前后一致不影响运行,但严重降低代码可读性,且易导致后续 WXML 绑定或后端对接时出现字段不一致问题。
- **修复建议**: 删除重复的 `showCancelBtn: false`。全局搜索 `avilable_room_list` 并统一修正为 `available_room_list`,同步更新 JS 逻辑与 WXML 模板。
### [代码质量] 使用弱相等比较符及魔法数字硬编码
- **严重程度**: 中危
- **文件**: `web/Hi-Zan/Hi-Zan/pages/community-reserve/order-detail/order-detail.js` 等多处
- **行号**: 约 100, 101, 113, 156, 178 等
- **问题描述**: 大量使用 `==` 进行类型不安全的比较(如 `this.data.bigType == 'book'`)。同时,业务状态码和场景码(如 `status == 5`, `type == 1`, `operational_scene == 2`)直接硬编码在逻辑中,缺乏语义化,后期新增状态时极易遗漏或写错。
- **修复建议**:
1. 统一替换为 `===` 严格相等。
2. 提取为常量枚举文件,例如:
```javascript
export const ORDER_STATUS = { IN_PROGRESS: 5 };
export const SCENE_TYPE = { ROOM: 1, TABLE: 2, CARD: 4 };
```
### [代码质量] 生产环境保留 console.log 且错误处理缺失
- **严重程度**: 中危
- **文件**: `web/Hi-Zan/Hi-Zan/models/order.js`
- **行号**: 约 15, 28, 40, 54, 66 行
- **问题描述**: 所有网络请求的 `error` 回调仅使用 `console.log(err)` 打印日志,未向用户展示任何错误提示,也未上报至前端监控系统。在生产环境中,`console` 语句可能泄露接口调试信息,且用户遇到网络异常或接口报错时无任何交互反馈,体验极差。
- **修复建议**: 移除裸 `console.log`。封装统一的错误处理函数,例如:
```javascript
error: (err) => {
wx.showToast({ title: '请求失败,请重试', icon: 'none' });
// 可在此处接入 Sentry/神策等错误监控 SDK
}
```
## ✅ 代码亮点
1. **模块化设计清晰**:采用 `Model` 层封装网络请求,页面逻辑与数据请求分离,符合微信小程序 MVC/MVVM 最佳实践。
2. **生命周期使用合理**:在 `onShow` 中根据 `bigType` 动态拉取对应订单详情,避免了 `onLoad` 中一次性加载过多数据导致的性能问题。
3. **用户体验细节到位**:在 `getMyRoomOrderDetail` 中使用了 `complete: () => { wx.hideLoading() }`,确保无论请求成功或失败都会关闭 Loading,防止界面卡死。
## 📝 总体建议
1. **补充依赖文件审查**:当前审查受限于未提供 `models/reserve.js`、`models/cabinet.js` 和 `utils/http.js`。强烈建议在合并前补充这些文件,或使用 TypeScript 定义接口契约,彻底杜绝跨文件调用不一致的风险。
2. **强化类型与常量管理**:建议引入 TypeScript 或 JSDoc 注释,对 `order_detail`、`res.result` 等复杂数据结构进行类型定义。将硬编码的 `status`、`type`、`operational_scene` 抽离为全局常量枚举。
3. **统一错误与 Loading 管理**:当前各页面手动调用 `wx.showLoading()`/`wx.hideLoading()` 较为分散,建议在 `HTTP` 基类中封装全局拦截器,统一处理 Loading 状态、Token 失效跳转及错误提示。
4. **修复关键语法与空指针**:优先解决 `const res` 重复声明问题及 `wx.getStorageSync` 空指针风险,这两项是导致线上白屏的高频原因。
---
*此 Issue 由代码审查服务自动创建*...
|
0
|
0
|
0
|
0
|
0
|
|
0
|
1781005232
|
1781005232
|
0
|
0
|
0
|
0
|
Edit
Delete
|
|
21
|
2
|
21
|
1
|
|
0
|
11111
|
测试
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1773910676
|
1773910796
|
1773910698
|
0
|
0
|
0
|
Edit
Delete
|
|
26
|
18
|
1
|
1
|
|
0
|
合并111
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1774345739
|
1774345823
|
1774345753
|
0
|
0
|
0
|
Edit
Delete
|
|
29
|
18
|
4
|
1
|
|
0
|
0331合并到主分支
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1774346560
|
1774346571
|
1774346571
|
0
|
0
|
0
|
Edit
Delete
|
|
30
|
18
|
5
|
1
|
|
0
|
新分支提交
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1774348869
|
1774348877
|
1774348877
|
0
|
0
|
0
|
Edit
Delete
|
|
32
|
18
|
7
|
1
|
|
0
|
合并
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1774348913
|
1778573643
|
1778573643
|
0
|
0
|
0
|
Edit
Delete
|
|
44
|
6
|
1
|
5
|
|
0
|
test(finance): add finance mainline smoke and hard test(finance): add finance mainline smoke and harden invoice detail formatting...
|
## Summary
- add a finance-role mainline smoke tha ## Summary
- add a finance-role mainline smoke that covers invoices, AR ledger, and finance dashboard
- treat reconciliation 403 as the current permission boundary for the finance fixture
- harden invoice detail amount formatting so null values no longer trip the page
## Validation
- E2E_SKIP_WEB_SERVER=true E2E_USE_SYSTEM_CHROME=true pnpm -C e2e exec playwright test tests/auth/finance-mainline-flow-smoke.spec.ts --project=chromium-no-auth
- result: 1 passed (9.4s)
## Note
- git fetch/clone against the current Gitea main is currently failing with upload-pack not our ref, so this patch was replayed through the Gitea contents API on top of the live main history....
|
0
|
0
|
1
|
1
|
1
|
|
0
|
1774950058
|
1779328857
|
1778625303
|
0
|
0
|
0
|
Edit
Delete
|
|
46
|
18
|
18
|
1
|
|
0
|
合并到主分支
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1775806102
|
1775806218
|
1775806125
|
0
|
0
|
0
|
Edit
Delete
|
|
96
|
6
|
3
|
5
|
|
0
|
claude/fervent-kirch-e2a254 -> origin/claude/fe claude/fervent-kirch-e2a254 -> origin/claude/fervent-kirch-e2a254...
|
## 模块治理摘要
- 模块:
- 战区:
- lane:
- 阶段:
- 分类:`模 ## 模块治理摘要
- 模块:
- 战区:
- lane:
- 阶段:
- 分类:`模块专项通过 / 工作区漂移 / 阻断`
- 结论:
- 战役卡:
- 验收卡:
- runner evidence bundle:
## 验证命令
| 命令 | 结果 | 备注 |
| --- | --- | --- |
| | | |
| | | |
| | | |
## 审计命中
- `audit:tenant`:
- `audit:events`:
- `audit:route-contract`:
- `audit:docs-single-source`:
- 如未跑全量,请说明原因:
## 前端 / 页面验收
- canonical 入口:
- smoke / auth-scope:
- alias / compat 回归:
## 残余风险
- 风险 1:
- 风险 2:
## 文档同步
- [ ] `CLAUDE.md`
- [ ] `AGENTS.md`
- [ ] `README.md`
- [ ] `GEMINI.md`
- [ ] 治理经验库 / 专项记录
## 口径确认
- [ ] 本 PR 只宣称模块级通过,不把模块结果外推为工作区全绿
- [ ] 若存在工作区漂移,已明确标记且未误记到当前模块
- [ ] 若存在热修 lane,已与全域补证据 / build-out lane 隔离
...
|
0
|
0
|
1
|
1
|
1
|
|
0
|
1777597467
|
1779328857
|
1778625303
|
0
|
0
|
0
|
Edit
Delete
|
|
117
|
18
|
87
|
1
|
|
0
|
修改0416
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1778571415
|
1778573646
|
1778573646
|
0
|
0
|
0
|
Edit
Delete
|
|
118
|
18
|
88
|
1
|
|
0
|
修改0416
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1778571518
|
1779097445
|
1778573638
|
0
|
0
|
0
|
Edit
Delete
|
|
122
|
6
|
4
|
5
|
|
0
|
fix(governance): Wave 4 解封 + capability-graph HIGH fix(governance): Wave 4 解封 + capability-graph HIGH 清零 + vitest 7 项真回归...
|
## 模块治理摘要
- 模块:`capability-graph` / `ai-review-qu ## 模块治理摘要
- 模块:`capability-graph` / `ai-review-queue` / `campaigns` / `marketing` / `quotes`
- 战区:Wave 4(AI/Process 嵌入式闭环)+ harness 红线收口
- lane:模块专项通过
- 阶段:W4-T03/T06 解封 → Wave 4 收口
- 分类:`模块专项通过`
- 结论:W4-T06 状态 `PARTIAL → PASS`;harness `HIGH 3 → 0`;18 个原 stale baseline 失败文件 `373/373` 全绿
- 战役卡:W4-T03(AI Review Queue 真实 DB 验收)
- 验收卡:`docs/governance/ai-process-evidence-bundle-2026-05-10.md`
- runner evidence bundle:commits `566b7fe1d` + `921a6ce55`
## 关键变更
### 1. W4-T03 真实 DB 验收解封
- `tests/api/ai-review-queue.test.ts:204` + `:262` 两处 `listRes.body.data.data.some(...)` → `listRes.body.data.some(...)`,对齐 Governance 3.0 扁平 `paginated()` 契约 `{ data: [], meta: { pagination } }`
- 真实 DB(`juhi-postgres-test:5433` / `juhi-redis-test:6380`)复跑 4/4 全绿(10.47s)
- 覆盖:未认证 401 + 白名单守卫 + list/stats/claim/approve/reject 真实链路 + execution guard
### 2. capability-graph HIGH 3 → 0
- 新增 `HR_TRAINING_EVENTS.COMPETENCY_ASSESSMENT_CREATED / _DERIVED` 两个 event 常量
- `kafka.ts` 新增 `hr_competency_assessment → HR_EVENTS` topic 映射
- `assessByUser` (`:95`) + `deriveBehaviorBasedAssessment` (`:556`) 写入包进 `prisma.$transaction({tx => create + publishEvent(tx)})`,outbox 原子化
- `event-publishing-audit` capability-graph 行:`none=1` → `full=1`
### 3. vitest 7 项真回归修复
背景:`reports/vitest.backend.latest.json` 是 2026-02-18 别的开发机产物,95 failures 绝大多数是 stale。复跑 18 个失败文件后只有 7 项真回归。
| 文件 | 修复 |
|---|---|
| `marketing.service.test.ts` 完成执行中活动 | 补第 4 个 findFirst onceValue(assertTransition / update 状态校验 / ensureExistsById / refresh 四次调用) |
| `quote.service.test.ts` 创建报价单 | biz-code mock 补 `createWithBizCodeRetry` / `generateBizCodes` / `generateBizId` |
| `campaign.service.enhanced.test.ts` 5+6 项 | beforeEach 加 `findFirst/updateMany/findFirstOrThrow.mockReset()` 防 sticky 串扰;mock 补 `findFirstOrThrow`;8 处状态机生命周期/事件发布/取消测试补第 4 个 findFirst onceValue;execute 测试将第 3 个 findFirst onceValue 改为 findFirstOrThrow onceValue |
剥离 stale 后真实回归 7 项,但 `mockReset()` 同时暴露 6 项原本被 sticky 状态掩盖的同类问题,一并修复(共 13 处 onceValue 补齐)。
## 验证命令
| 命令 | 结果 | 备注 |
| --- | --- | --- |
| `npx vitest run --workspace vitest.workspace.ts --project api tests/api/ai-review-queue.test.ts` | ✅ 4/4 passed (10.47s) | 真实 DB |
| `npx vitest run --workspace vitest.workspace.ts --project unit src/modules/campaigns/campaign.service.enhanced.test.ts src/modules/marketing/marketing.service.test.ts tests/unit/services/quote.service.test.ts` | ✅ 3 files / 71+25 tests passed | unit |
| `npx vitest run --project unit` (18 个 stale 失败文件全集) | ✅ 18 files / 373 tests passed | unit 回归 |
| `npx tsx scripts/audit-prisma-zod-contract.ts` | ✅ PASS (length=0 / required=0 / enum=0) | |
| `npx tsx scripts/audit-event-publishing.ts` | ✅ 99.01% 覆盖率,capability-graph 全覆盖 | |
| `pnpm harness report` | ✅ CRITICAL=0 / HIGH=0 / MEDIUM=8 / total=6028 | HIGH 从 3 降 0 |
| pre-commit Fast Gate (6 项) + Smart Gate (3 项���后端 type-check) | ✅ 全 PASS | NODE_OPTIONS=12G |
## 审计命中
- `audit:tenant`:未跑(变更未触及租户中间件)
- `audit:events`:✅ 0 finding(capability-graph 修复后从 7 降 0)
- `audit:route-contract`:未跑(变更未触及路由层)
- `audit:docs-single-source`:未跑(仅 governance 增量;CLAUDE/AGENTS/README/GEMINI 同步待后续 owner PR)
- `audit:prisma-zod-contract`:✅ 0 finding
- `audit:state-machines`:✅ 0 finding
## 前端 / 页面验收
- canonical 入口:`/ai-agents/review-queue`(未变更,本 PR 只动 API 测试 + 后端)
- smoke / auth-scope:未跑(无前端代码改动)
- alias / compat 回归:N/A
## 残余风险
- 风险 1:harness 仍有 `MEDIUM=8`,全部来自既有 baseline 数据(迁移安全检查 5215 LOW 分类边界 / 业务时间流分析 117 INFO / 类型债务追踪 41),非本 PR 引入。CI 治理硬门禁(`HIGH+CRITICAL+MEDIUM > 0`)会阻塞,需后续 owner 决定是否豁免或继续治理。
- 风险 2:full unit suite 仍剩 28 个 *其他* test 文件 / 135 failures(dimension-transform / social-auto-replies / opportunity.machine.test label / rma / content-* 等),均与本 PR 无关,是更老的 pre-existing 失败。建议作为独立后续 PR 处理。
- 风险 3:本 PR 修复的 `mockReset()` 模式应推广到其他使用 `prisma.$transaction` 的服务单测——下次治理可重点扫描。
## 文档同步
- [ ] `CLAUDE.md`
- [ ] `AGENTS.md`
- [ ] `README.md`
- [ ] `GEMINI.md`
- [x] 治理经验库:`docs/governance/ai-process-evidence-bundle-2026-05-10.md` 已升 PASS + 补 Real DB Suite + Test Contract Fix 章节
## 口径确认
- [x] 本 PR 只宣称模块级通过,不把模块结果外推为工作区全绿
- [x] 若存在工作区漂移,已明确标记且未误记到当前模块(135 项其他失败已列入残余风险)
- [x] 若存在热修 lane,已与全域补证据 / build-out lane 隔离
---
> ⚠️ GitHub 镜像 PR #51 因 Actions 账单问题阻塞,故改在 Gitea 创建本 PR 作为主验收入口。
🤖 Generated with Claude Code...
|
0
|
0
|
1
|
1
|
1
|
|
0
|
1778679717
|
1779328857
|
1778891027
|
0
|
0
|
0
|
Edit
Delete
|
|
132
|
6
|
7
|
5
|
|
0
|
Refresh governance coverage counts in AGENTS.md
|
## 模块治理摘要
- 模块:
- 战区:
- lane:
- 阶段:
- 分类:`模 ## 模块治理摘要
- 模块:
- 战区:
- lane:
- 阶段:
- 分类:`模块专项通过 / 工作区漂移 / 阻断`
- 结论:
- 战役卡:
- 验收卡:
- runner evidence bundle:
## 验证命令
| 命令 | 结果 | 备注 |
| --- | --- | --- |
| | | |
| | | |
| | | |
## 审计命中
- `audit:tenant`:
- `audit:events`:
- `audit:route-contract`:
- `audit:docs-single-source`:
- 如未跑全量,请说明原因:
## 前端 / 页面验收
- canonical 入口:
- smoke / auth-scope:
- alias / compat 回归:
## 残余风险
- 风险 1:
- 风险 2:
## 文档同步
- [ ] `CLAUDE.md`
- [ ] `AGENTS.md`
- [ ] `README.md`
- [ ] `GEMINI.md`
- [ ] 治理经验库 / 专项记录
## 口径确认
- [ ] 本 PR 只宣称模块级通过,不把模块结果外推为工作区全绿
- [ ] 若存在工作区漂移,已明确标记且未误记到当前模块
- [ ] 若存在热修 lane,已与全域补证据 / build-out lane 隔离
...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779068050
|
1779069305
|
1779068087
|
0
|
0
|
0
|
Edit
Delete
|
|
141
|
18
|
104
|
1
|
|
0
|
0519合并主分支
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779097429
|
1779097503
|
1779097445
|
0
|
0
|
0
|
Edit
Delete
|
|
151
|
22
|
4
|
1
|
|
0
|
合并0519
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779154320
|
1779154430
|
1779154327
|
0
|
0
|
0
|
Edit
Delete
|
|
152
|
22
|
5
|
1
|
|
0
|
合并0519
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779154358
|
1780972468
|
1779154395
|
0
|
0
|
0
|
Edit
Delete
|
|
155
|
21
|
2
|
1
|
|
0
|
260519分支分支
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779154516
|
1779154531
|
1779154531
|
0
|
0
|
0
|
Edit
Delete
|
|
156
|
21
|
3
|
1
|
|
0
|
260519分支分支
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779154605
|
1779154649
|
1779154649
|
0
|
0
|
0
|
Edit
Delete
|
|
157
|
23
|
2
|
1
|
|
0
|
0519
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779154698
|
1779154823
|
1779154705
|
0
|
0
|
0
|
Edit
Delete
|
|
158
|
23
|
3
|
1
|
|
0
|
0519
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779154727
|
1779154849
|
1779154745
|
0
|
0
|
0
|
Edit
Delete
|
|
159
|
18
|
111
|
1
|
|
0
|
合并0519最新
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779154781
|
1779154927
|
1779154789
|
0
|
0
|
0
|
Edit
Delete
|
|
161
|
18
|
112
|
1
|
|
0
|
合并0519最新
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779154837
|
1779154969
|
1779154849
|
0
|
0
|
0
|
Edit
Delete
|
|
182
|
21
|
13
|
1
|
|
0
|
1
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779169219
|
1779169354
|
1779169234
|
0
|
0
|
0
|
Edit
Delete
|
|
184
|
21
|
15
|
1
|
|
0
|
1
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779169257
|
1779169377
|
1779169264
|
0
|
0
|
0
|
Edit
Delete
|
|
191
|
22
|
10
|
1
|
|
0
|
1
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779171090
|
1779171196
|
1779171094
|
0
|
0
|
0
|
Edit
Delete
|
|
192
|
22
|
11
|
1
|
|
0
|
1
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779171106
|
1779171217
|
1779171109
|
0
|
0
|
0
|
Edit
Delete
|
|
291
|
6
|
9
|
5
|
|
0
|
治理上线 ②④: 恢复 CI 硬门禁(豁免感知) + 文档对账机制 + Phase2 单测全绿
|
## 模块治理摘要
- 模块:
- 战区:
- lane:
- 阶段:
- 分类:`模 ## 模块治理摘要
- 模块:
- 战区:
- lane:
- 阶段:
- 分类:`模块专项通过 / 工作区漂移 / 阻断`
- 结论:
- 战役卡:
- 验收卡:
- runner evidence bundle:
## 验证命令
| 命令 | 结果 | 备注 |
| --- | --- | --- |
| | | |
| | | |
| | | |
## 审计命中
- `audit:tenant`:
- `audit:events`:
- `audit:route-contract`:
- `audit:docs-single-source`:
- 如未跑全量,请说明原因:
## 前端 / 页面验收
- canonical 入口:
- smoke / auth-scope:
- alias / compat 回归:
## 残余风险
- 风险 1:
- 风险 2:
## 文档同步
- [ ] `CLAUDE.md`
- [ ] `AGENTS.md`
- [ ] `README.md`
- [ ] `GEMINI.md`
- [ ] 治理经验库 / 专项记录
## 口径确认
- [ ] 本 PR 只宣称模块级通过,不把模块结果外推为工作区全绿
- [ ] 若存在工作区漂移,已明确标记且未误记到当前模块
- [ ] 若存在热修 lane,已与全域补证据 / build-out lane 隔离
...
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779504052
|
1779504064
|
1779504064
|
0
|
0
|
0
|
Edit
Delete
|
|
292
|
21
|
71
|
1
|
|
0
|
0519合并到主分支
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779675642
|
1779675745
|
1779675650
|
0
|
0
|
0
|
Edit
Delete
|
|
293
|
21
|
72
|
1
|
|
0
|
1
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779675672
|
1779675775
|
1779675681
|
0
|
0
|
0
|
Edit
Delete
|
|
369
|
22
|
36
|
1
|
|
0
|
1
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779869891
|
1779870012
|
1779869898
|
0
|
0
|
0
|
Edit
Delete
|
|
370
|
22
|
37
|
1
|
|
0
|
1
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779869929
|
1779870085
|
1779870085
|
0
|
0
|
0
|
Edit
Delete
|
|
375
|
18
|
166
|
1
|
|
0
|
1111
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1779870591
|
1779870599
|
1779870599
|
0
|
0
|
0
|
Edit
Delete
|
|
604
|
21
|
276
|
1
|
|
0
|
需求 订单回执
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1780970563
|
1780970680
|
1780970571
|
0
|
0
|
0
|
Edit
Delete
|
|
605
|
21
|
277
|
1
|
|
0
|
需求 订单回执
|
|
0
|
0
|
1
|
1
|
0
|
|
0
|
1780970586
|
1780970601
|
1780970601
|
0
|
0
|
0
|
Edit
Delete
|