# 归属机构动态加载功能说明 ## 需求背景 在急救转运任务创建页面中,归属机构下拉列表原来是写死的静态数据,需要改为从后台数据库动态加载分公司数据。 **原有问题**: - 归属机构数据硬编码:`['广州分公司', '深圳分公司', '珠海分公司', '佛山分公司']` - 无法同步后台数据变化 - 新增分公司后前端无法自动显示 ## 实现方案 ### 1. 创建部门API **新建文件**: `app/api/system/dept.js` ```javascript import request from '@/utils/request' /** * 查询部门列表 * @param {Object} query 查询参数 */ export function listDept(query) { return request({ url: '/system/dept/list', method: 'get', params: query }) } /** * 查询分公司列表(parent_id=100的部门) */ export function listBranchCompany() { return request({ url: '/system/dept/list', method: 'get', params: { parentId: 100 } }) } /** * 查询部门详细 * @param {Number} deptId 部门ID */ export function getDept(deptId) { return request({ url: '/system/dept/' + deptId, method: 'get' }) } ``` **说明**: - `listBranchCompany()` - 专门用于查询分公司数据(parent_id=100) - `listDept(query)` - 通用部门查询接口 - `getDept(deptId)` - 查询单个部门详情 ### 2. 修改页面数据结构 **文件**: `app/pages/task/create-emergency.vue` **修改前**: ```javascript data() { return { organizations: ['广州分公司', '深圳分公司', '珠海分公司', '佛山分公司'], } } ``` **修改后**: ```javascript data() { return { organizations: [], // 归属机构列表(从后台加载分公司数据) organizationOptions: [], // 归属机构选项(用于picker显示) } } ``` **关键变化**: - ✅ `organizations` - 改为空数组,从后台动态加载 - ✅ `organizationOptions` - 新增字段,存储完整的部门对象信息 ### 3. 添加加载分公司方法 **文件**: `app/pages/task/create-emergency.vue` ```javascript // 加载分公司数据(parent_id=100的部门) loadBranchCompanies() { listBranchCompany().then(response => { const list = response.data || [] // 过滤出 parent_id = 100 的部门(分公司) this.organizationOptions = list.filter(dept => dept.parentId === 100) // 生成picker的数据源(只显示名称) this.organizations = this.organizationOptions.map(dept => dept.deptName) // 如果当前用户有默认分公司,设置为选中项 if (this.currentUser.branchCompanyName) { const index = this.organizationOptions.findIndex( dept => dept.deptName === this.currentUser.branchCompanyName ) if (index !== -1) { this.selectedOrganization = this.currentUser.branchCompanyName // 提取地域关键词 this.selectedRegion = this.selectedOrganization.replace(/分公司$/g, '').trim() } } }).catch(error => { console.error('加载分公司数据失败:', error) this.organizationOptions = [] this.organizations = [] }) }, ``` **说明**: - 调用`listBranchCompany()`查询分公司 - 双重过滤确保只显示parent_id=100的部门 - 自动匹配当前用户的默认分公司 - 提取地域关键词用于医院过滤 ### 4. 修改选择事件 **文件**: `app/pages/task/create-emergency.vue` **修改前**: ```javascript onOrganizationChange(e) { this.selectedOrganization = this.organizations[e.detail.value] // ... } ``` **修改后**: ```javascript onOrganizationChange(e) { const index = e.detail.value const selected = this.organizationOptions[index] this.selectedOrganization = selected.deptName // 从归属机构中提取地域关键词(去除"分公司"后缀) // 例如:"广州分公司" -> "广州" this.selectedRegion = selected.deptName.replace(/分公司$/g, '').trim() // 重新加载医院列表(带地域过滤) this.loadDefaultHospitals() }, ``` **关键变化**: - ✅ 从`organizationOptions`获取完整的部门对象 - ✅ 通过`selected.deptName`获取部门名称 - ✅ 保持地域关键词提取逻辑 ### 5. 页面加载初始化 **文件**: `app/pages/task/create-emergency.vue` ```javascript onLoad(options) { // ... 其他初始化代码 // 加载分公司数据 this.loadBranchCompanies() // 设置默认归属机构 if (this.currentUser.branchCompanyName) { this.selectedOrganization = this.currentUser.branchCompanyName } // ... 其他初始化代码 } ``` **说明**: - 在页面加载时自动调用`loadBranchCompanies()` - 优先设置用户的默认分公司 - 确保数据加载顺序正确 ### 6. 导入依赖 **文件**: `app/pages/task/create-emergency.vue` ```javascript import { listBranchCompany } from "@/api/system/dept" ``` ## 数据流程 ``` 页面加载 (onLoad) ↓ 调用 loadBranchCompanies() ↓ 请求 /system/dept/list?parentId=100 ↓ 后端返回分公司列表 ↓ 前端过滤 parentId === 100 ↓ 生成 organizations 和 organizationOptions ↓ 匹配用户默认分公司 ↓ 显示在下拉列表中 ↓ 用户选择归属机构 ↓ 触发 onOrganizationChange ↓ 提取地域关键词 ↓ 重新加载医院列表(带地域过滤) ``` ## 分公司数据结构 ### 后端返回数据 ```json { "code": 200, "data": [ { "deptId": 101, "parentId": 100, "deptName": "广州分公司", "ancestors": "0,100", "orderNum": 1, "status": "0" }, { "deptId": 102, "parentId": 100, "deptName": "深圳分公司", "ancestors": "0,100", "orderNum": 2, "status": "0" }, { "deptId": 103, "parentId": 100, "deptName": "珠海分公司", "ancestors": "0,100", "orderNum": 3, "status": "0" } ] } ``` ### 前端数据转换 ```javascript // organizationOptions - 完整对象列表 [ { deptId: 101, parentId: 100, deptName: '广州分公司', ... }, { deptId: 102, parentId: 100, deptName: '深圳分公司', ... } ] // organizations - 只包含名称的数组(用于picker显示) ['广州分公司', '深圳分公司', '珠海分公司'] ``` ## 优化效果 ### 1. 数据同步 - ✅ 自动同步后台分公司数据 - ✅ 新增分公司后无需修改前端代码 - ✅ 删除分公司后自动从列表中移除 ### 2. 用户体验 - ✅ 自动显示当前用户所在分公司 - ✅ 下拉列表实时反映后台数据 - ✅ 选择后自动过滤相关医院 ### 3. 系统维护 - ✅ 前端代码无需硬编码 - ✅ 集中管理分公司数据 - ✅ 便于扩展和维护 ## 后端支持说明 ### API接口 **接口地址**: `GET /system/dept/list` **请求参数**: ```javascript { parentId: 100 // 查询parent_id=100的部门(分公司) } ``` **返回数据**: ```json { "code": 200, "msg": "查询成功", "data": [ { "deptId": 101, "parentId": 100, "deptName": "广州分公司", "ancestors": "0,100", "orderNum": 1, "leader": "张三", "phone": "13800138000", "status": "0" } ] } ``` ### SQL查询 **Mapper**: `SysDeptMapper.xml` ```xml ``` **说明**: - 通过`parentId`参数过滤 - 只返回未删除的部门(del_flag='0') - 按排序号排序 ## 测试验证 ### 测试场景1:正常加载分公司 **前提条件**: ```sql -- 数据库中存在分公司 SELECT * FROM sys_dept WHERE parent_id = 100 AND del_flag = '0'; ``` **预期结果**: - 页面加载时自动显示分公司列表 - 下拉框包含所有分公司 - 用户默认分公司自动选中 ### 测试场景2:无分公司数据 **前提条件**: ```sql -- 数据库中没有分公司 DELETE FROM sys_dept WHERE parent_id = 100; ``` **预期结果**: - 下拉框显示为空 - 不会报错 - 提示用户"请选择归属机构" ### 测试场景3:新增分公司 **操作步骤**: 1. 在后台管理系统中新增分公司 2. 刷新任务创建页面 3. 查看归属机构下拉列表 **预期结果**: - 新增的分公司自动出现在列表中 - 无需修改前端代码 ### 测试场景4:选择归属机构后过滤医院 **操作步骤**: 1. 选择"广州分公司" 2. 点击医院搜索框 3. 查看医院列表 **预期结果**: - 医院列表自动过滤出广州相关的医院 - 地域关键词正确提取("广州") ## 注意事项 ### 1. 部门层级结构 **分公司定义**: - `parent_id = 100` - 标识分公司 - `ancestors = "0,100"` - 祖级列表 - `del_flag = '0'` - 未删除状态 **子部门**: - `parent_id != 100` - 不是分公司 - 不会出现在归属机构列表中 ### 2. 数据过滤策略 采用**双重过滤**确保数据准确: ```javascript // 1. 后端过滤:通过parentId参数 listBranchCompany() // parentId: 100 // 2. 前端过滤:确保parentId === 100 this.organizationOptions = list.filter(dept => dept.parentId === 100) ``` ### 3. 默认值处理 ```javascript // 用户有默认分公司 if (this.currentUser.branchCompanyName) { this.selectedOrganization = this.currentUser.branchCompanyName } // 加载数据后匹配默认值 const index = this.organizationOptions.findIndex( dept => dept.deptName === this.currentUser.branchCompanyName ) ``` ### 4. 错误处理 ```javascript .catch(error => { console.error('加载分公司数据失败:', error) this.organizationOptions = [] this.organizations = [] }) ``` - 失败时设置为空数组 - 不影响页面其他功能 - 记录错误日志便于排查 ## 相关文件 ### 前端文件 - `app/api/system/dept.js` - 部门API接口(新建) - `app/pages/task/create-emergency.vue` - 任务创建页面(修改) ### 后端文件 - `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java` - 部门Controller - `ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java` - 部门Service - `ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml` - 部门Mapper ### 文档文件 - `prd/归属机构动态加载功能说明.md`(本文档) ## 版本历史 - **v1.0** (2025-10-25): 初始版本,实现归属机构动态加载功能