# 畜牧医疗资源管理 — 技术方案 > 依据:`畜牧医疗资源管理功能需求.md`(同目录) --- ## 1. 技术架构 | 层级 | 说明 | | --- | --- | | **整体** | RuoYi **v3.9.2**(**springboot2** 分支)单体后端 + 若依 **Vue2** 前端(与分支配套) | | **运行时** | JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid | | **数据库** | MySQL **5.7.39**,存储引擎 InnoDB,字符集 **utf8mb4** | | **文件** | 复用 RuoYi 既有上传能力(本地/MinIO 等以项目现有配置为准);业务表存访问 **URL**、**存储路径**(`photo_file_url` / `photo_file_path`) | | **外部系统** | 平台 **用户/角色** 体系(分配账号时调用 `ISysUserService` 等);**移动端** 通过查询 `publish_status=1` 资源展示(具体接口由移动端或网关模块实现) | **后端分层(与若依一致)** - `Controller`:参数接收、权限注解、返回 `AjaxResult` / `TableDataInfo` - `Service`:按资源类型分支校验、发布状态机、分配账号、替换照片删旧文件 - `Mapper` + XML:持久化 - `domain`:实体;校验与枚举建议 `MedicalResourceValidation`、`MedicalResourceRules` **代码包(建议)**:`com.ruoyi.web.modules.diseasetreatment` **初始化脚本**:`sql/biz_medical_resource.sql` **一致性策略(与需求对齐)** - 四类资源 **单表** 存储,以 `resource_type` 区分;新增后 **不可改类型**。 - **修改 / 逻辑删除 / 发布**:仅 `publish_status=0` 且 `del_flag=0`(「已下架」亦为 `publish_status=0` 且 `offline_time` 非空,权限同未发布)。 - **下架**:仅 `publish_status=1` → 置 `publish_status=0`、写 `offline_time`;**保留** `publish_time` 供审计。 - **分配账号**:仅 `resource_type∈{004001,004003}`、`account_assigned=0`、`publish_status=0`;成功一次后不可重复;登录名冲突 **不** 置 `account_assigned=1`。 - **移动端可见**:仅 `publish_status=1` 且 `del_flag=0`。 --- ## 2. 数据库设计 ### 2.1 表:`biz_medical_resource`(畜牧医疗资源主表) 单表承载四类资源共用字段 + 类型差异化可空列;逻辑删除用 `del_flag`。 | 字段名 | 类型 | 非空 | 默认值 | 说明 | | --- | --- | --- | --- | --- | | `id` | `bigint(20)` | Y | 自增 | 主键 | | `resource_type` | `varchar(32)` | Y | — | 资讯类别编码(`parentCode=004`、`categoryType=6`),见 **2.2** | | `resource_name` | `varchar(32)` | Y | — | 展示名称(姓名/团队名/机构名/设备名),需求 1~10 字 | | `photo_file_url` | `varchar(512)` | Y | — | 照片访问 URL(与上传返回 `url` 对齐) | | `photo_file_path` | `varchar(512)` | Y | — | 照片**存储路径**(与上传返回 `fileName` 等对齐,一般为 `/profile/...`) | | `introduction` | `varchar(500)` | Y | — | 介绍,需求 1~500 字 | | `contact_phone` | `varchar(20)` | N | NULL | 联系电话;类型 1/2/3 由应用层必填 | | `affiliated_unit` | `varchar(64)` | N | NULL | 隶属单位 | | `detail_address` | `varchar(200)` | N | NULL | 详细地址(兽医、机构) | | `consult_modes` | `varchar(32)` | N | NULL | 接诊方式,逗号分隔 **1**定点 **2**上门 **3**在线 | | `service_area` | `varchar(200)` | N | NULL | 服务区域(兽医) | | `fee_standard` | `decimal(10,2)` | N | NULL | 收费标准(元/小时,兽医) | | `service_start_time` | `varchar(8)` | N | NULL | 服务开始 `HH:mm` | | `service_end_time` | `varchar(8)` | N | NULL | 服务结束 `HH:mm` | | `service_weekdays` | `varchar(32)` | N | NULL | 服务周日,逗号分隔 `1`~`7`(周一=1) | | `max_daily_appointments` | `int(11)` | N | NULL | 单日最大接诊人数(仅机构 type=3) | | `establish_date` | `date` | N | NULL | 成立时间(团队) | | `team_size` | `int(11)` | N | NULL | 团队规模(人) | | `team_members` | `varchar(500)` | N | NULL | 团队成员,选填 | | `person_in_charge` | `varchar(32)` | N | NULL | 负责人(团队、机构) | | `org_level` | `tinyint(4)` | N | NULL | 机构级别,见 **2.4** | | `equipment_model` | `varchar(32)` | N | NULL | 设备型号 | | `longitude` | `decimal(10,6)` | N | NULL | 经度(地图标点预留,本期不用) | | `latitude` | `decimal(10,6)` | N | NULL | 纬度(预留) | | `publish_status` | `tinyint(4)` | Y | `0` | 发布状态,见 **2.3** | | `publish_time` | `datetime` | N | NULL | 最近发布时间 | | `offline_time` | `datetime` | N | NULL | 最近下架时间;与 `publish_status=0` 组合表示「已下架」 | | `account_assigned` | `tinyint(4)` | Y | `0` | 是否已分配账号,见 **2.5** | | `sys_user_id` | `bigint(20)` | N | NULL | 关联 `sys_user.user_id` | | `assigned_login_name` | `varchar(64)` | N | NULL | 已分配登录名(列表冗余展示) | | `del_flag` | `char(1)` | Y | `'0'` | 删除标记,见 **2.5** | | `create_by` | `varchar(64)` | N | — | 若依惯例 | | `create_time` | `datetime` | N | — | 若依惯例 | | `update_by` | `varchar(64)` | N | — | 若依惯例 | | `update_time` | `datetime` | N | — | 若依惯例 | | `remark` | `varchar(500)` | N | NULL | 备注 | **索引** - `PRIMARY KEY (id)` - `KEY idx_type (resource_type)` — Tab / 列表按类型筛选 - `KEY idx_name (resource_name)` — 名称模糊 - `KEY idx_publish (publish_status)` — 发布状态筛选 - `KEY idx_del (del_flag)` — 逻辑删除 **DDL 示例(MySQL 5.7)** ```sql CREATE TABLE `biz_medical_resource` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `resource_type` varchar(32) NOT NULL COMMENT '资讯类别编码(parentCode=004,categoryType=6)', `resource_name` varchar(32) NOT NULL COMMENT '资源名称', `photo_file_url` varchar(512) DEFAULT NULL COMMENT '照片URL', `photo_file_path` varchar(512) DEFAULT NULL COMMENT '照片路径', `introduction` varchar(500) DEFAULT NULL COMMENT '介绍', `contact_phone` varchar(20) DEFAULT NULL COMMENT '联系电话', `affiliated_unit` varchar(64) DEFAULT NULL COMMENT '隶属单位', `detail_address` varchar(200) DEFAULT NULL COMMENT '详细地址', `consult_modes` varchar(32) DEFAULT NULL COMMENT '接诊方式1,2,3', `service_area` varchar(200) DEFAULT NULL COMMENT '服务区域', `fee_standard` decimal(10,2) DEFAULT NULL COMMENT '收费标准元/小时', `service_start_time` varchar(8) DEFAULT NULL COMMENT '服务开始HH:mm', `service_end_time` varchar(8) DEFAULT NULL COMMENT '服务结束HH:mm', `service_weekdays` varchar(32) DEFAULT NULL COMMENT '服务周日1-7', `max_daily_appointments` int(11) DEFAULT NULL COMMENT '单日最大接诊人数(仅机构)', `establish_date` date DEFAULT NULL COMMENT '成立时间', `team_size` int(11) DEFAULT NULL COMMENT '团队规模', `team_members` varchar(500) DEFAULT NULL COMMENT '团队成员', `person_in_charge` varchar(32) DEFAULT NULL COMMENT '负责人', `org_level` tinyint(4) DEFAULT NULL COMMENT '1诊所2医院', `equipment_model` varchar(32) DEFAULT NULL COMMENT '设备型号', `longitude` decimal(10,6) DEFAULT NULL COMMENT '经度预留', `latitude` decimal(10,6) DEFAULT NULL COMMENT '纬度预留', `publish_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0非发布态1已发布', `publish_time` datetime DEFAULT NULL COMMENT '发布时间', `offline_time` datetime DEFAULT NULL COMMENT '下架时间', `account_assigned` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0未分配1已分配', `sys_user_id` bigint(20) DEFAULT NULL COMMENT '关联用户ID', `assigned_login_name` varchar(64) DEFAULT NULL COMMENT '分配登录名', `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '0正常2删除', `create_by` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_by` varchar(64) DEFAULT '' COMMENT '更新者', `update_time` datetime DEFAULT NULL COMMENT '更新时间', `remark` varchar(500) DEFAULT NULL COMMENT '备注', PRIMARY KEY (`id`), KEY `idx_type` (`resource_type`), KEY `idx_name` (`resource_name`), KEY `idx_publish` (`publish_status`), KEY `idx_del` (`del_flag`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='畜牧医疗资源'; ``` **界面三态与落库条件(应用层映射,与需求 §2.4 一致)** | 界面状态 | `publish_status` | `offline_time` | | --- | --- | --- | | 未发布 | `0` | `NULL` | | 已发布 | `1` | 任意 | | 已下架 | `0` | **非** `NULL` | 列表 Query `publishStatus`:`0` 未发布 / `1` 已发布 / `2` 已下架(分别映射上表三行)。 **类型与字段落库矩阵(应用层强校验,禁止非法落库)** | 字段 | 兽医(1) | 团队(2) | 机构(3) | 设备(4) | | --- | --- | --- | --- | --- | | `resource_name` / `photo_*` / `introduction` | ○/○/○ | ○/○/○ | ○/○/○ | ○/○/○ | | `contact_phone` | ○ | ○ | ○ | — | | `affiliated_unit` | ○ | ○ | — | ○ | | `detail_address` | ○ | — | ○ | — | | `consult_modes` / `service_area` / `fee_standard` | ✓/○/○ | — | — | — | | `service_start_time` / `service_end_time` / `service_weekdays` | ○ | — | ○ | — | | `max_daily_appointments` | — | — | ○ | — | | `establish_date` / `team_size` / `team_members` | — | ○/○/○ | — | — | | `person_in_charge` | — | ○ | ○ | — | | `org_level` | — | — | ✓ | — | | `equipment_model` | — | — | — | ○ | ### 2.2 资源类型 `resource_type` 数据来自 `GET /category/informationCategory/children?parentCode=004&categoryType=6`(响应 `code`、`name`)。落库与接口传 **叶子 `code`**。 | 编码 | 含义 | | --- | --- | | `004001` | 兽医人员 | | `004002` | 专家团队 | | `004003` | 诊疗机构 | | `004004` | 医疗设备 | 保存校验:`MedicalResourceTypeValidator` 以上述 children 返回的 `code` 集合为准。历史 `tinyint` 迁移见 `sql/biz_medical_resource_alter_resource_type.sql`(`1`→`004001` … `4`→`004004`)。 ### 2.3 发布状态 `publish_status` | 值 | 含义 | | --- | --- | | `0` | 非发布态(含未发布、已下架;由 `offline_time` 区分展示) | | `1` | 已发布 | **发布:** `publish_status=1`,`publish_time=now()`。 **下架:** `publish_status=0`,`offline_time=now()`;**不修改** `publish_time`。 ### 2.4 机构级别 `org_level` | 值 | 含义 | | --- | --- | | `1` | 动物诊所 | | `2` | 动物医院 | ### 2.5 其他枚举 **接诊方式 `consult_modes`(多选入库)** | 值 | 含义 | | --- | --- | | `1` | 定点接诊 | | `2` | 上门接诊 | | `3` | 在线接诊 | **服务周日 `service_weekdays`(多选入库)**:`1`~`7` 表示周一至周日。 **账号分配 `account_assigned`** | 值 | 含义 | | --- | --- | | `0` | 未分配 | | `1` | 已分配 | **删除标记 `del_flag`** | 值 | 含义 | | --- | --- | | `0` | 正常 | | `2` | 已逻辑删除 | **分配账号默认角色(配置项,非本表字段)** | `resource_type` | 默认 `role_id` | | --- | --- | | `004001` 兽医 | **100** | | `004003` 机构 | **102** | 登录名规则:`Pinyin4j` 全拼(小写、无空格)+ `id`。 --- ## 3. 接口设计 统一响应:**RuoYi 惯例** `AjaxResult`(`code` / `msg` / `data`)或分页 `TableDataInfo`(`rows` / `total`);错误文案区分参数校验、状态非法、文件非法、账号创建失败等。 **权限标识建议(示例)**:`diseaseTreatment:medicalResource:list|query|add|edit|remove|publish|offline|assignAccount` **Base Path(示例)**:`/diseaseTreatment/medicalResource`(实际前缀与若依 `context-path`、模块路由对齐) ### 3.1 分页列表 | 项 | 说明 | | --- | --- | | **Method / URI** | `GET /diseaseTreatment/medicalResource/list` | | **权限** | `diseaseTreatment:medicalResource:list` | | **Query** | `pageNum`(默认 1)、`pageSize`(默认 **20**)、`resourceType`(**精确**,与 Tab 一致,**必填**)、`resourceName`(名称模糊,可空)、`publishStatus`(`0`/`1`/`2`,见 **§2.1** 三态映射,可空) | | **排序** | 默认 `create_time DESC`, `id DESC` | | **条件** | `del_flag='0'` | | **响应** | `TableDataInfo` 行内字段:id、resourceType、resourceName、introduction(可截断)、publishStatus、publishTime、accountAssigned、assignedLoginName、createTime 及类型相关列等 | ### 3.2 详情 | 项 | 说明 | | --- | --- | | **Method / URI** | `GET /diseaseTreatment/medicalResource/{id}` | | **权限** | `diseaseTreatment:medicalResource:query` | | **响应** | 全业务字段(驼峰);`consultModes`、`serviceWeekdays` 以数组返回;含双维发布展示字段、`accountAssigned`、`assignedLoginName`、审计字段;仅 `del_flag=0` | ### 3.3 新增 | 项 | 说明 | | --- | --- | | **Method / URI** | `POST /diseaseTreatment/medicalResource` | | **权限** | `diseaseTreatment:medicalResource:add` | | **Body** | JSON:`resourceType`、`resourceName`、`photoFileUrl`、`photoFilePath`、`introduction` 及按类型必填字段;`consultModes`、`serviceWeekdays` 为数组;`remark` 可空;照片须先上传 | | **校验** | `MedicalResourceValidation` 按 **§2.1** 矩阵校验;手机号、服务时段、正数/正整数、照片后缀 jpg/jpeg/png | | **落库** | `publish_status=0`,`offline_time=NULL`,`account_assigned=0`,`del_flag=0`;`resource_type` 保存后不可变 | ### 3.4 修改 | 项 | 说明 | | --- | --- | | **Method / URI** | `PUT /diseaseTreatment/medicalResource` | | **权限** | `diseaseTreatment:medicalResource:edit` | | **前置** | `publish_status=0` 且 `del_flag=0`;否则返回「已发布资源请先下架后再编辑」 | | **Body** | 含 `id`;可替换各业务字段及 `photoFileUrl` / `photoFilePath`;**不可修改** `resourceType` | | **逻辑** | 更新库表;替换照片时按旧 `photo_file_path` 删除磁盘文件;**不自动发布** | ### 3.5 删除 | 项 | 说明 | | --- | --- | | **Method / URI** | `DELETE /diseaseTreatment/medicalResource/{ids}` | | **权限** | `diseaseTreatment:medicalResource:remove` | | **规则** | **`publish_status=1` 禁止**;仅 `publish_status=0` 且 `del_flag=0` 允许逻辑删除 | | **副作用** | `del_flag='2'`;删除照片物理文件;**若 `account_assigned=1` 且 `sys_user_id` 非空**,调用 `ISysUserService.deleteUserById` 删除平台账号;存在下游引用时由 `MedicalResourceReferenceChecker` 拒绝 | ### 3.6 发布 | 项 | 说明 | | --- | --- | | **Method / URI** | `POST /diseaseTreatment/medicalResource/publish/{id}` | | **权限** | `diseaseTreatment:medicalResource:publish` | | **前置** | `publish_status=0` 且 `del_flag=0`;全量字段校验通过 | | **结果** | `publish_status=1`,`publish_time=now()`;移动端可查询展示 | ### 3.7 下架 | 项 | 说明 | | --- | --- | | **Method / URI** | `POST /diseaseTreatment/medicalResource/offline/{id}` | | **权限** | `diseaseTreatment:medicalResource:offline` | | **前置** | `publish_status=1` | | **结果** | `publish_status=0`,`offline_time=now()`;**保留** `publish_time`;移动端不可见 | ### 3.8 分配账号 | 项 | 说明 | | --- | --- | | **Method / URI** | `POST /diseaseTreatment/medicalResource/assignAccount/{id}` | | **权限** | `diseaseTreatment:medicalResource:assignAccount` | | **前置** | `resource_type∈{004001,004003}`;`account_assigned=0`;`publish_status=0`;`del_flag=0` | | **结果** | 创建 `sys_user`,绑定 **§2.5** 默认角色;写 `sys_user_id`、`assigned_login_name`、`account_assigned=1` | | **失败** | 登录名冲突等:返回明确 `msg`,**不**置 `account_assigned=1` | > **地图标点**:本期不提供接口。 --- ## 4. 与移动端、账号体系衔接(流程) ### 4.1 角色说明 | 角色 | 说明 | | --- | --- | | **畜牧医疗资源业务服务** | 本模块 CRUD、发布/下架、分配账号 | | **移动端 / 其他业务模块** | 查询 `publish_status=1` 且 `del_flag=0` 的资源用于列表、详情、预约引用 | | **平台用户服务** | 分配账号时创建用户并绑定角色 | ### 4.2 发布与移动端可见性 ```text 后台「发布」→ 本地 publish_status=1 → 移动端查询条件:publish_status=1 AND del_flag=0 后台「下架」→ 本地 publish_status=0,offline_time 有值 → 移动端不再返回该条 ``` ### 4.3 分配账号流程 ```text 用户点击「分配账号」→ Service 校验 type∈{1,3}、未分配、未发布 → 生成登录名(拼音+id)→ 调用户服务创建账号并绑定 role_id(100 或 102) ← 成功 → account_assigned=1,写入 sys_user_id、assigned_login_name ← 失败 → 提示原因,允许重试(仍须满足仅一次成功分配) ``` ### 4.4 删除与账号联动(草稿 §10) ```text 用户删除资源 → 校验未发布/已下架、无下游引用 → 若 account_assigned=1:MedicalResourceAccountAssigner.deleteLinkedAccount → deleteUserById → 删除照片文件 → logicDelete del_flag=2 ``` --- ## 5. 照片与上传(实现提示) - 前端:先调若依 **`/common/upload`**,得到 **`url`**(→ `photoFileUrl`)、**存储路径**(→ `photoFilePath`,一般为 `fileName`);**10MB** 在提交前校验,可不单独落库。 - 服务端:后缀白名单 **jpg/jpeg/png**;`photo_file_path` 须以 `/profile` 前缀;替换照片时删除旧物理文件。 --- ## 6. 菜单与权限(示例) | 类型 | 名称 | 权限标识 | | --- | --- | --- | | 菜单 | 畜牧医疗资源管理 | `diseaseTreatment:medicalResource:list` | | 按钮 | 查询 | `diseaseTreatment:medicalResource:query` | | 按钮 | 新增 | `diseaseTreatment:medicalResource:add` | | 按钮 | 修改 | `diseaseTreatment:medicalResource:edit` | | 按钮 | 删除 | `diseaseTreatment:medicalResource:remove` | | 按钮 | 发布 | `diseaseTreatment:medicalResource:publish` | | 按钮 | 下架 | `diseaseTreatment:medicalResource:offline` | | 按钮 | 分配账号 | `diseaseTreatment:medicalResource:assignAccount` | 组件路径:`diseaseTreatment/medicalResource/index`(挂载「牧业疫病诊疗服务」目录下)。 --- ## 7. 交付清单(研发勾选) - [ ] 表 `biz_medical_resource` DDL 与初始化脚本(`sql/biz_medical_resource.sql`) - [ ] Domain / Mapper / Service / Controller(`diseasetreatment` 包) - [ ] `MedicalResourceValidation`、`MedicalResourceRules`、分配账号组件 - [ ] 菜单与按钮权限 SQL - [ ] 单元测试 / MockMvc:类型校验、发布态三态、分配账号、已发布不可改删 --- ## 8. 修订记录 | 日期 | 说明 | | --- | --- | | — | 初稿,对齐 `畜牧医疗资源管理功能需求.md` | | — | 按 `养殖标准管理技术方案.md` 版式重整:技术架构分层表、库表五列、接口逐条表格、照片上传与交付清单章节 | | — | 明确 `publish_status`+`offline_time` 三态;分配角色 100/102;地图标点本期无接口 | | — | 删除接口:已分配账号时联动 `deleteUserById`(对齐草稿 §10) | | — | `max_daily_appointments` 仅机构 type=3 校验与落库;兽医保存时清空该字段(对齐草稿 §2) |