# 我的预约(机构)— 技术方案
> 依据:`我的预约(机构)功能需求.md`(同目录);关联 `我的预约(兽医)技术方案.md`、`我的预约(专家)` 草稿与功能需求
---
## 1. 技术架构
| 项 | 说明 |
| --- | --- |
| **整体** | RuoYi **v3.9.2**(**springboot2** 分支)单体后端 + 若依 **Vue2** 管理端 |
| **运行时** | JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid |
| **数据库** | MySQL **5.7.39**,InnoDB,`utf8mb4` |
| **关联表** | `biz_medical_resource`(机构 `resource_type=3`,`sys_user_id` 绑定登录用户) |
| **预约数据** | 与兽医/专家共用 **`biz_service_appointment`**(见 **§2**);本模块**无写接口** |
| **移动端** | 机构预约 `INSERT` 由「预约服务」完成;本模块为**机构后台只读查询** |
**后端分层(机构模块)**
| 层 | 职责 |
| --- | --- |
| `Controller` | 分页列表、详情;`@PreAuthorize`;`AjaxResult` / `TableDataInfo` |
| `Service` | 解析当前机构 `provider_id`、机构合法状态校验、越权校验 |
| `Mapper` + XML | 共用 `BizServiceAppointmentMapper`,按 `provider_type=2` 查询 |
| `support` | `OrgAppointmentValidation`、`OrgAppointmentStatusResolver`、`OrgProviderResolver`;复用 `ServiceAppointmentRules` |
**代码包(建议)**:`com.ruoyi.web.modules.diagnosis`(与兽医预约、医疗资源同域)
**共用实体/Mapper**:`BizServiceAppointment`、`BizServiceAppointmentMapper`(兽医模块已建则**复用**,不重复建表)
**初始化脚本**:`sql/biz_service_appointment.sql`(三端共用,机构迭代前须已执行)
---
## 2. 关联方案设计(三端共用)
### 2.1 统一预约主表 `biz_service_appointment`
| `provider_type` | 服务对象 | `provider_id` 指向 | 后台模块 | 移动端提交后 `status` |
| --- | --- | --- | --- | --- |
| `1` | 兽医 | `biz_medical_resource.id`(`resource_type=1`) | 我的预约(兽医) | `0` 待确认 |
| **`2`** | **诊疗机构** | **`biz_medical_resource.id`(`resource_type=3`)** | **我的预约(机构)** | **`5` 已预约** |
| `3` | 科技专家 | `biz_tech_resource.id`(`resource_type=1`) | 我的预约(专家) | `0` 待确认 |
机构与兽医共用 **`biz_medical_resource`**,以 `resource_type` 区分行;机构账号绑定 **`resource_type=3`** 的记录。
### 2.2 状态枚举(库表 `status` → 机构展示)
| 值 | 常量 | 机构展示 | 机构列表可筛 | 兽医/专家 |
| --- | --- | --- | --- | --- |
| `5` | `BOOKED` | 已预约 | ✓ | — |
| `3` | `CANCELLED` | 已取消 | ✓ | ✓ |
| `4` | `COMPLETED` | 已完成 | ✓ | ✓ |
| `0/1/2` | 待确认/已确认/已拒绝 | **不得出现** | — | ✓ |
应用层:`provider_type=2` 时,`status` 仅允许 **`3`、`4`、`5`**;列表筛选传入 `0/1/2` 视为非法。
### 2.3 三端接口对照
| 模块 | Base Path | 写操作 |
| --- | --- | --- |
| 兽医 | `/diseaseTreatment/myAppointment/vet` | 确认、拒绝 |
| **机构(本文档)** | **`/diseaseTreatment/myAppointment/org`** | **无** |
| 专家 | `/techService/myAppointment/expert` | 确认、拒绝;评价列表 |
### 2.4 当前登录人解析(机构)
```text
loginUser.userId
→ biz_medical_resource
WHERE sys_user_id = ? AND resource_type = 3
AND account_assigned = 1 AND del_flag = '0'
→ provider_id = id
列表/详情 WHERE provider_type = 2 AND provider_id = ?
```
无绑定:列表返回空;详情/越权访问返回「未绑定机构资源,无法查询预约」。
**Mapper 扩展(与兽医 `selectVetResourceBySysUserId` 对称)**
```sql
SELECT ... FROM biz_medical_resource
WHERE sys_user_id = #{sysUserId}
AND resource_type = 3
AND account_assigned = 1
AND del_flag = '0'
LIMIT 1
```
### 2.5 机构与兽医/专家差异(实现约束)
| 项 | 机构 | 兽医/专家 |
| --- | --- | --- |
| 列表 SQL | 同表;`provider_type=2`;可不返回 `reject_reason` 列给前端(或返回但前端不展示) | `provider_type=1/3` |
| 详情 | 全字段只读;**不展示** `rejectReason`、评价 | 兽医无评价;专家有评价子表 |
| 状态标签 | `OrgAppointmentStatusResolver`(三态) | `VetAppointmentStatusResolver`(五态) |
| 专家评价表 | **不涉及** | 仅专家 `biz_service_appointment_review`(待建) |
---
## 3. 数据库设计
### 3.1 复用表 `biz_service_appointment`
机构模块**不新增业务表**;字段与兽医方案 **§3.1** 一致。机构侧关心字段如下:
| 字段 | 机构用途 |
| --- | --- |
| `provider_type` | 固定 `2` |
| `provider_id` | 机构医疗资源主键 |
| `appointee_name` / `appoint_date` / `time_start` / `time_end` | 列表(日期)+ 详情(时段) |
| `contact_phone` | 列表 + 详情 |
| `service_address` / `service_requirement` | **仅详情**(列表前端不展示,SQL 可仍查询) |
| `status` | `5/3/4` |
| `reject_reason` / `confirm_time` / `reject_time` | 机构流程不使用,**不展示** |
**DDL**:见 `sql/biz_service_appointment.sql`(项目已提供则无需重复执行)。
### 3.2 机构列表查询(Mapper XML 语义)
```sql
WHERE provider_type = 2 AND provider_id = #{providerId}
AND appointee_name LIKE concat('%', #{appointeeName}, '%')
AND appoint_date >= #{startDate}
AND appoint_date <= #{endDate}
AND status = #{status}
ORDER BY appoint_date DESC, create_time DESC, id DESC
```
**详情/越权**:`id` + `provider_type=2` + `provider_id=当前机构`。
### 3.3 机构侧无需的子表
- 无分圈、无评价子表;**不**为机构单独建表。
---
## 4. 接口设计(机构)
统一响应:RuoYi `AjaxResult` / `TableDataInfo`(`code`、`msg`、`data` / `rows`、`total`)。
**权限标识(示例)**:`diseaseTreatment:orgMyAppointment:list|query|complete`(**无** confirm/reject)
**Base Path(示例)**:`/diseaseTreatment/myAppointment/org`
| # | 说明 | Method | URI | 权限 | 要点 |
| --- | --- | --- | --- | --- | --- |
| 4.1 | 分页列表 | GET | `/list` | `...:list` | Query:`pageNum`(默认 1)、`pageSize`(默认 **20**)、`appointeeName`(模糊)、`startDate`、`endDate`(`yyyy-MM-dd`)、`status`(**仅 `3/4/5`**);**禁止**前端传 `providerId` |
| 4.2 | 详情 | GET | `/{id}` | `...:query` | 校验 `provider_type=2` 且归属当前机构;返回详情全字段(见下表) |
| 4.3 | 完成接诊 | POST | `/complete/{id}` | `...:complete` | 前置 `status=5`(已预约);更新 `status=4`(已完成) |
**本期不提供**:`POST` 确认/拒绝;除 **完成接诊** 外无其他写操作。
### 4.1 列表响应字段(建议)
与功能需求列表列对齐,后端可返回:
`id`、`appointeeName`、`appointDate`、`contactPhone`、`status`、`statusLabel`。
(`timeStart`、`timeEnd`、`serviceAddress` 等可由 SQL 查出但列表页不绑定,或不下发以减流量。)
### 4.2 详情 `data` 字段(建议)
| 字段 | 说明 |
| --- | --- |
| `id` | 主键 |
| `appointeeName` | 预约人 |
| `appointDate` | `yyyy-MM-dd` |
| `timeStart` / `timeEnd` | 时段;前端拼 `HH:mm~HH:mm` |
| `contactPhone` | 联系电话 |
| `serviceAddress` | 服务地址 |
| `serviceRequirement` | 服务需求 |
| `status` / `statusLabel` | 状态码与展示名 |
| `createTime` | 提交时间(审计,可选) |
**不下发**:`rejectReason`、`confirmTime`、`rejectTime`(机构无对应流程)。
### 4.3 业务错误(`msg` 示例)
| 场景 | 文案 |
| --- | --- |
| 日期筛选 | 结束日期不能早于开始日期 |
| 状态筛选非法 | 状态筛选无效 |
| 无机构绑定 | 未绑定机构资源,无法查询预约 |
| 越权 | 无权操作该预约记录 / 无权查看该预约记录 |
| 不存在 | 预约记录不存在或已删除 |
### 4.4 与兽医/专家接口差异(实现对照)
| 能力 | 机构 | 兽医 | 专家 |
| --- | --- | --- | --- |
| 列表 | `GET .../org/list` | `GET .../vet/list` | `GET .../expert/list` |
| 详情 | `GET .../org/{id}` | `GET .../vet/{id}` | `GET .../expert/{id}` |
| 确认 | — | `POST .../vet/confirm/{id}` | `POST .../expert/confirm/{id}` |
| 拒绝 | — | `POST .../vet/reject/{id}` | `POST .../expert/reject/{id}` |
| 评价 | — | — | `GET .../expert/reviewList/{id}` |
---
## 5. 实现要点
| 项 | 说明 |
| --- | --- |
| 越权 | 详情必须 `provider_type=2` 且 `provider_id=当前机构` |
| 只读 | Controller **仅** `GET`;Service 无 `insert/update` 预约方法 |
| 状态展示 | `status=5` →「已预约」;勿与兽医「已确认」混用 |
| 数据串单防护 | 若查到 `status∈{0,1,2}` 且 `provider_type=2`,记日志并按「数据异常」处理(不展示或报错) |
| 日志 | 详情查看可记 `@Log`(查询类,按平台惯例) |
| 组件路径 | `diseaseTreatment/myAppointment/org/index` |
**建议新增类(机构)**
| 类 | 职责 |
| --- | --- |
| `OrgProviderResolver` | `resource_type=3` 解析 `provider_id` |
| `OrgAppointmentValidation` | 列表日期区间、`status∈{3,4,5}` |
| `OrgAppointmentStatusResolver` | 三态中文标签 |
| `OrgMyAppointmentServiceImpl` | 列表/详情 scope |
| `BizOrgMyAppointmentController` | 两个 GET 接口 |
**复用(兽医已建)**
- `ServiceAppointmentRules`、`BizServiceAppointment`、`BizServiceAppointmentMapper`
- 扩展 Mapper:`selectOrgAppointmentList`、`selectOrgAppointmentByIdAndProvider`(或泛化 `selectByProvider` 减少重复)
---
## 6. 与上下游衔接
| 系统 | 说明 |
| --- | --- |
| 移动端预约服务 | 用户选机构并提交 → `INSERT`:`provider_type=2`,`status=5` |
| 移动端取消 | 更新 `status=3` |
| 已完成 | 业务闭环置 `status=4` |
| 畜牧医疗资源管理 | 机构须**已发布**且**已分配账号**(角色 **102**) |
| 我的预约(兽医) | 同表不同 `provider_type`;列表互不可见 |
---
## 7. 菜单与权限(示例)
| 类型 | 名称 | 权限标识 |
| --- | --- | --- |
| 菜单 | 我的预约(机构) | `diseaseTreatment:orgMyAppointment:list` |
| 按钮 | 查询 | `diseaseTreatment:orgMyAppointment:query` |
| 按钮 | 完成接诊 | `diseaseTreatment:orgMyAppointment:complete` |
组件路径:`diseaseTreatment/myAppointment/org/index`(「牧业疫病诊疗服务」目录下)。
---
## 8. 交付清单
- [ ] `BizMedicalResourceMapper.selectOrgResourceBySysUserId`(若尚未添加)
- [ ] `BizServiceAppointmentMapper` 机构查询方法 + XML
- [ ] `OrgMyAppointmentController` + Service + 校验/状态解析
- [ ] 菜单权限 SQL(机构,仅 list/query)
- [ ] 单元测试 + MockMvc(列表 scope、三态筛选、越权、无写接口)
---
## 9. 修订记录
| 版本 | 说明 |
| --- | --- |
| 1.0 | 初稿:共用 `biz_service_appointment`;机构只读接口;三态与兽医/专家关联;复用 diagnosis 包与医疗资源绑定 |