编辑 | blame | 历史 | 原始文档

归属机构动态加载功能说明

需求背景

在急救转运任务创建页面中,归属机构下拉列表原来是写死的静态数据,需要改为从后台数据库动态加载分公司数据。

原有问题:
- 归属机构数据硬编码:['广州分公司', '深圳分公司', '珠海分公司', '佛山分公司']
- 无法同步后台数据变化
- 新增分公司后前端无法自动显示

实现方案

1. 创建部门API

新建文件: app/api/system/dept.js

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

// 加载分公司数据(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

onLoad(options) {
  // ... 其他初始化代码
  
  // 加载分公司数据
  this.loadBranchCompanies()
  
  // 设置默认归属机构
  if (this.currentUser.branchCompanyName) {
    this.selectedOrganization = this.currentUser.branchCompanyName
  }
  
  // ... 其他初始化代码
}

说明:
- 在页面加载时自动调用loadBranchCompanies()
- 优先设置用户的默认分公司
- 确保数据加载顺序正确

6. 导入依赖

文件: app/pages/task/create-emergency.vue

import { listBranchCompany } from "@/api/system/dept"

数据流程

页面加载 (onLoad)
    ↓
调用 loadBranchCompanies()
    ↓
请求 /system/dept/list?parentId=100
    ↓
后端返回分公司列表
    ↓
前端过滤 parentId === 100
    ↓
生成 organizations 和 organizationOptions
    ↓
匹配用户默认分公司
    ↓
显示在下拉列表中
    ↓
用户选择归属机构
    ↓
触发 onOrganizationChange
    ↓
提取地域关键词
    ↓
重新加载医院列表(带地域过滤)

分公司数据结构

后端返回数据

{
  "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"
    }
  ]
}

前端数据转换

// 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

<select id="selectDeptList" parameterType="SysDept" resultMap="SysDeptResult">
    select d.dept_id, d.parent_id, d.dept_name, ...
    from sys_dept d
    where d.del_flag = '0'
    <if test="parentId != null and parentId != 0">
        AND parent_id = #{parentId}
    </if>
    order by d.parent_id, d.order_num
</select>

说明:
- 通过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. 数据过滤策略

采用**双重过滤**确保数据准确:

// 1. 后端过滤:通过parentId参数
listBranchCompany() // parentId: 100

// 2. 前端过滤:确保parentId === 100
this.organizationOptions = list.filter(dept => dept.parentId === 100)

3. 默认值处理

// 用户有默认分公司
if (this.currentUser.branchCompanyName) {
  this.selectedOrganization = this.currentUser.branchCompanyName
}

// 加载数据后匹配默认值
const index = this.organizationOptions.findIndex(
  dept => dept.deptName === this.currentUser.branchCompanyName
)

4. 错误处理

.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): 初始版本,实现归属机构动态加载功能