# 医院地域过滤功能说明 ## 需求背景 在急救转运任务创建页面中,需要优化医院选择功能: 1. 当归属机构选择广州分公司等地域信息后,需要将"广州"这样的地域关键词传入到医院搜索接口中进行筛选 2. 使用OR逻辑对HospData表中的HospProvince、HospCity、HospArea等字段进行模糊匹配 3. 如果输入框中有搜索关键词,也需要对HospProvince、HospCity、HospArea、HospAddress、HospName、HospShort进行模糊匹配 4. 最终选中的医院地址需要合并HospProvince、HospCity、HospArea和HospAddress完整显示 ## 实现方案 ### 1. 后端Mapper接口修改 **文件**: `ruoyi-system/src/main/java/com/ruoyi/system/mapper/HospDataMapper.java` **修改内容**: ```java /** * 根据医院名称或地址搜索医院 * * @param keyword 搜索关键词 * @param region 地域关键词(用于过滤省市区) * @return 医院列表 */ List searchHospitals(@Param("keyword") String keyword, @Param("region") String region); ``` **说明**: - 新增`region`参数,用于地域过滤 - 支持同时传入关键词和地域信息 ### 2. 后端SQL修改 **文件**: `ruoyi-system/src/main/resources/mapper/system/HospDataMapper.xml` **修改内容**: ```xml ``` **说明**: - 地域过滤:使用OR逻辑对省、市、区进行模糊匹配 - 关键词过滤:扩展为对省、市、区、地址、医院名称、简称进行模糊匹配 - 两个条件使用AND连接,实现组合过滤 ### 3. 后端Controller修改 **文件**: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/HospDataController.java` **修改内容**: ```java /** * 搜索医院 * 支持根据医院名称、地址、地域进行模糊搜索 * @param keyword 搜索关键词(医院名称、地址、简称、省市区) * @param region 地域关键词(用于过滤省市区) */ @GetMapping("/search") public AjaxResult searchHospitals( @RequestParam(value = "keyword", required = false) String keyword, @RequestParam(value = "region", required = false) String region) { List list = hospDataMapper.searchHospitals(keyword, region); return success(list); } ``` **说明**: - 新增`region`请求参数 - 两个参数都是可选的(required = false) ### 4. 前端API修改 **文件**: `app/api/hospital.js` **修改内容**: ```javascript /** * 搜索医院 * @param {string} keyword 搜索关键词(医院名称、地址、简称、省市区) * @param {string} region 地域关键词(用于过滤省市区) */ export function searchHospitals(keyword, region) { return request({ url: '/system/hospital/search', method: 'get', params: { keyword: keyword, region: region } }) } ``` **说明**: - 新增`region`参数 - 保持向后兼容:如果不传region,后端会忽略地域过滤 ### 5. 前端页面修改 **文件**: `app/pages/task/create-emergency.vue` #### 5.1 数据字段新增 ```javascript data() { return { selectedRegion: '', // 从归属机构中提取的地域信息(如:广州、深圳等) // ... 其他字段 } } ``` #### 5.2 归属机构选择变更 ```javascript onOrganizationChange(e) { this.selectedOrganization = this.organizations[e.detail.value] // 从归属机构中提取地域关键词(去除"分公司"后缀) // 例如:"广州分公司" -> "广州" this.selectedRegion = this.selectedOrganization.replace(/分公司$/g, '').trim() // 重新加载医院列表(带地域过滤) this.loadDefaultHospitals() }, ``` **说明**: - 从"广州分公司"中提取"广州"作为地域关键词 - 使用正则表达式去除"分公司"后缀 - 选择归属机构后立即重新加载医院列表 #### 5.3 加载默认医院列表 ```javascript // 加载默认医院列表(前100条) loadDefaultHospitals() { // 传入空字符串或特殊标识获取前100条,同时传入地域过滤 searchHospitals('', this.selectedRegion).then(response => { this.defaultHospitals = response.data || [] // 同时初始化两个搜索结果为默认数据 this.hospitalOutResults = [...this.defaultHospitals] this.hospitalInResults = [...this.defaultHospitals] }).catch(error => { console.error('加载默认医院列表失败:', error) this.defaultHospitals = [] }) }, ``` **说明**: - 传入地域参数`this.selectedRegion` - 如果未选择归属机构,地域为空,后端会忽略地域过滤 #### 5.4 医院搜索方法 ```javascript // 搜索转出医院 searchHospitalOut(keyword) { // 传入关键词和地域过滤 searchHospitals(keyword, this.selectedRegion).then(response => { this.hospitalOutResults = response.data || [] this.showHospitalOutResults = true }).catch(error => { console.error('搜索医院失败:', error) this.hospitalOutResults = [] }) }, // 搜索转入医院 searchHospitalIn(keyword) { // 传入关键词和地域过滤 searchHospitals(keyword, this.selectedRegion).then(response => { this.hospitalInResults = response.data || [] this.showHospitalInResults = true }).catch(error => { console.error('搜索医院失败:', error) this.hospitalInResults = [] }) }, ``` **说明**: - 同时传入关键词和地域参数 - 实现关键词 + 地域的组合过滤 #### 5.5 合并地址显示 **新增方法**: ```javascript // 合并医院地址(省 + 市 + 区 + 详细地址) buildFullAddress(hospital) { const parts = [] if (hospital.hopsProvince) { parts.push(hospital.hopsProvince) } if (hospital.hopsCity) { parts.push(hospital.hopsCity) } if (hospital.hopsArea) { parts.push(hospital.hopsArea) } if (hospital.hospAddress) { parts.push(hospital.hospAddress) } return parts.join('') } ``` **选择医院时使用完整地址**: ```javascript // 选择转出医院 selectHospitalOut(hospital) { this.taskForm.hospitalOut.id = hospital.hospId this.taskForm.hospitalOut.name = hospital.hospName // 合并省市区 + 详细地址 const fullAddress = this.buildFullAddress(hospital) this.taskForm.hospitalOut.address = fullAddress // ... 其他逻辑 }, // 选择转入医院 selectHospitalIn(hospital) { this.taskForm.hospitalIn.id = hospital.hospId this.taskForm.hospitalIn.name = hospital.hospName // 合并省市区 + 详细地址 const fullAddress = this.buildFullAddress(hospital) this.taskForm.hospitalIn.address = fullAddress // ... 其他逻辑 }, ``` **搜索结果列表显示完整地址**: ```html {{ hospital.hospName }} {{ buildFullAddress(hospital) }} {{ hospital.hospName }} {{ buildFullAddress(hospital) }} ``` ## 功能流程 ### 1. 选择归属机构后的过滤流程 ``` 用户选择"广州分公司" ↓ 提取地域关键词:"广州" ↓ 重新加载默认医院列表 ↓ 后端SQL执行地域过滤: WHERE (HopsProvince LIKE '%广州%' OR HopsCity LIKE '%广州%' OR HopsArea LIKE '%广州%') ↓ 返回广州相关的医院列表(前100条) ↓ 前端显示过滤后的医院 ``` ### 2. 输入搜索关键词后的组合过滤流程 ``` 用户输入关键词:"人民" 当前地域:"广州" ↓ 后端SQL执行组合过滤: WHERE (HopsProvince LIKE '%广州%' OR HopsCity LIKE '%广州%' OR HopsArea LIKE '%广州%') AND (HospProvince LIKE '%人民%' OR HopsCity LIKE '%人民%' OR HopsArea LIKE '%人民%' OR HospAddress LIKE '%人民%' OR HospName LIKE '%人民%' OR HospShort LIKE '%人民%') ↓ 返回同时满足地域和关键词的医院 ↓ 前端显示过滤后的医院 ``` ### 3. 地址显示流程 ``` 用户选择医院 ↓ 调用buildFullAddress(hospital) ↓ 合并地址字段: HopsProvince + HopsCity + HopsArea + HospAddress 例如:"广东省" + "广州市" + "天河区" + "天河路123号" ↓ 显示完整地址: "广东省广州市天河区天河路123号" ``` ## 优化效果 ### 1. 数据过滤更精准 - ✅ 根据归属机构自动过滤同地域医院 - ✅ 减少不相关医院数据,提升选择效率 - ✅ 支持省、市、区三级地域过滤 ### 2. 搜索功能更强大 - ✅ 关键词搜索范围扩大(省市区、地址、医院名称、简称) - ✅ 地域 + 关键词组合过滤 - ✅ OR逻辑匹配,提高命中率 ### 3. 地址显示更完整 - ✅ 显示完整的省市区地址 - ✅ 便于用户确认医院位置 - ✅ 统一地址格式,便于后续处理 ### 4. 用户体验优化 - ✅ 选择归属机构后自动刷新医院列表 - ✅ 搜索结果更贴合实际需求 - ✅ 地址信息更清晰明了 ## 数据示例 ### 示例1:选择广州分公司 **归属机构**: 广州分公司 **提取地域**: 广州 **SQL过滤条件**: ```sql WHERE (HopsProvince LIKE '%广州%' OR HopsCity LIKE '%广州%' OR HopsArea LIKE '%广州%') ``` **返回结果示例**: - 广东省人民医院(省:广东省,市:广州市) - 广州市第一人民医院(市:广州市) - 广州医科大学附属第一医院(市:广州市) ### 示例2:广州分公司 + 搜索"中山" **归属机构**: 广州分公司 **提取地域**: 广州 **搜索关键词**: 中山 **SQL过滤条件**: ```sql WHERE (HopsProvince LIKE '%广州%' OR HopsCity LIKE '%广州%' OR HopsArea LIKE '%广州%') AND (HospProvince LIKE '%中山%' OR HopsCity LIKE '%中山%' OR HopsArea LIKE '%中山%' OR HospAddress LIKE '%中山%' OR HospName LIKE '%中山%' OR HospShort LIKE '%中山%') ``` **返回结果示例**: - 中山大学附属第一医院(市:广州市,名称包含"中山") - 中山大学孙逸仙纪念医院(市:广州市,名称包含"中山") ### 示例3:地址合并显示 **原始数据**: - HopsProvince: 广东省 - HopsCity: 广州市 - HopsArea: 天河区 - HospAddress: 天河路123号 **合并后地址**: ``` 广东省广州市天河区天河路123号 ``` ## 注意事项 ### 1. 地域关键词提取 - 目前通过去除"分公司"后缀实现 - 如果归属机构命名不规范,需要调整提取逻辑 - 建议归属机构统一命名格式:{地域}分公司 ### 2. SQL性能优化 - 多个LIKE查询可能影响性能 - 建议在HopsProvince、HopsCity、HopsArea字段上建立索引 - 控制返回数据量(TOP 100) ### 3. 地址为空情况 - buildFullAddress方法会自动跳过空值字段 - 只合并有值的字段 - 确保至少有一个地址字段有值 ### 4. 向后兼容 - region参数为可选参数 - 如果不传region,功能退化为原有的关键词搜索 - 确保旧版本前端也能正常使用 ## 部署说明 ### 1. 后端部署 重启后端服务: ```bash # Windows bin\run.bat # Linux ./ry.sh restart ``` ### 2. 前端部署 重新编译前端: ```bash # H5版本 npm run build:h5 # 微信小程序版本 npm run build:mp-weixin ``` ### 3. 测试验证 测试步骤: 1. 选择归属机构"广州分公司" 2. 观察医院列表是否自动过滤为广州相关医院 3. 输入搜索关键词,验证组合过滤效果 4. 选择医院后,查看地址是否完整显示省市区信息 ## 文件清单 ### 后端文件 - `ruoyi-system/src/main/java/com/ruoyi/system/mapper/HospDataMapper.java` - `ruoyi-system/src/main/resources/mapper/system/HospDataMapper.xml` - `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/HospDataController.java` ### 前端文件 - `app/api/hospital.js` - `app/pages/task/create-emergency.vue` ### 文档文件 - `prd/医院地域过滤功能说明.md`(本文档) ## 版本历史 - **v1.0** (2025-10-25): 初始版本,实现医院地域过滤和地址合并显示功能