# 医生排班日期范围搜索修复 ## 问题描述 访问 `adminapi/doctor.roster/lists?start_date=2026-03-02&end_date=2026-03-08` 时,`searchWhere` 为空,无法按日期范围筛选排班数据。 ## 根本原因 `ListsSearchTrait` 中的 `between` 搜索类型只支持固定的参数名 `start` 和 `end`,而不支持自定义参数名如 `start_date` 和 `end_date`。 ### 原始代码问题 ```php public function setSearch(): array { return [ '=' => ['doctor_id', 'period', 'status'], 'between' => ['date' => ['start_date', 'end_date']], // ❌ 不会生效 ]; } ``` `ListsSearchTrait` 中的 `between` 处理逻辑: ```php case 'between': if (empty($this->start) || empty($this->end)) { // 只检查 start 和 end break; } $where[] = [$whereFields, 'between', [$this->start, $this->end]]; break; ``` ## 解决方案 在 `lists()` 和 `count()` 方法中手动处理日期范围搜索。 ### 修复后的代码 ```php public function setSearch(): array { return [ '=' => ['doctor_id', 'period', 'status'], ]; } public function lists(): array { $where = $this->searchWhere; // 处理日期范围搜索 if (!empty($this->params['start_date']) && !empty($this->params['end_date'])) { $where[] = ['date', 'between', [$this->params['start_date'], $this->params['end_date']]]; } $lists = Roster::where($where) ->field(['id', 'doctor_id', 'date', 'period', 'status', 'quota', 'max_patients', 'booked_count', 'remark', 'create_time', 'update_time']) ->order(['date' => 'asc', 'period' => 'asc']) ->limit($this->limitOffset, $this->limitLength) ->select() ->toArray(); return $lists; } public function count(): int { $where = $this->searchWhere; // 处理日期范围搜索 if (!empty($this->params['start_date']) && !empty($this->params['end_date'])) { $where[] = ['date', 'between', [$this->params['start_date'], $this->params['end_date']]]; } return Roster::where($where)->count(); } ``` ## 测试 ### 测试 URL ``` GET /adminapi/doctor.roster/lists?start_date=2026-03-02&end_date=2026-03-08 ``` ### 预期结果 - ✅ 返回 2026-03-02 到 2026-03-08 之间的排班数据 - ✅ `where` 条件包含日期范围:`['date', 'between', ['2026-03-02', '2026-03-08']]` ### 其他搜索参数 ``` GET /adminapi/doctor.roster/lists?doctor_id=1&start_date=2026-03-02&end_date=2026-03-08 GET /adminapi/doctor.roster/lists?period=1&status=1&start_date=2026-03-02&end_date=2026-03-08 ``` ## 其他说明 ### ListsSearchTrait 支持的搜索类型 1. **等值查询**:`=`, `<>`, `>`, `>=`, `<`, `<=`, `in` 2. **模糊查询**:`%like%`, `%like`, `like%` 3. **时间范围**:`between_time`(使用 `start_time` 和 `end_time`) 4. **范围查询**:`between`(使用 `start` 和 `end`) 5. **集合查询**:`find_in_set` ### 如果要使用框架的 between 需要修改前端传递的参数名: ```javascript // 前端修改 params: { start: '2026-03-02', // 改为 start end: '2026-03-08' // 改为 end } ``` ```php // 后端配置 public function setSearch(): array { return [ '=' => ['doctor_id', 'period', 'status'], 'between' => 'date', // 简化配置 ]; } ``` 但这种方式不够语义化,不推荐使用。 ## 已修复的文件 - ✅ `server/app/adminapi/lists/doctor/RosterLists.php` --- **修复日期:** 2024-03-04 **状态:** ✅ 完成