互联网医院04科室管理

目录

  • [1 创建数据模型](#1 创建数据模型)
  • [2 搭建页面](#2 搭建页面)
  • [3 获取部门信息](#3 获取部门信息)
  • [4 前端读取](#4 前端读取)
  • 总结

上一篇我们已经介绍了医院及院区信息的展示,有了院区之后,我们就需要在院区下建立科室。对于大型医院,通常科室是非常多的,而且科室下边还有子部门。

对于这种有多级结构的,我们通常使用树形结构来管理数据,本篇我们介绍一下科室管理的开发过程。

1 创建数据模型

对于这种父子关系的,我们在建表的时候需要建立自关联的关系。打开MySQL,创建数据模型,创建部门表,增加科室名称字段

增加科室编码字段

增加父部门,类型选择关联关系

增加层级字段

增加排序字段

增加科室简介字段

录入数据的时候就形成了一种层级关系

2 搭建页面

打开我们的后台应用,点击创建页面的图标,添加科室管理页面

在内容插槽里添加布局组件

我们用网格布局来将页面分为左右两部分

第一列添加树组件

第二列,我们用普通容器来搭建布局,形成上下两部分

上半部分,我们搭建一个布局显示当前选中部门的信息,可以添加子部门

下半部分添加数据表格组件,数据模型选择部门表

3 获取部门信息

因为科室是一颗树,但是我们表里的数据是以行进行组织的,所以需要写一个API将行结构改写为树结构。

打开扩展功能,点击+号创建API

选择自定义代码

输入API的名称和标识

修改一下方法名称和标识

输入如下代码

bash 复制代码
/**
 * API 标识: getDepartmentTree
 * 类型: 自定义代码
 */
module.exports = async function (params, context) {
  // 1. 从数据库获取所有部门数据
  // 注意:默认分页限制为 200 条 。
  // 如果部门超过 200,建议使用循环分页获取,此处演示单次获取。
  const result = await context.callModel({
    dataSourceName: 't_department', // 数据模型标识
    methodName: 'wedaGetRecordsV2', // 查询多条方法 [cite: 467]
    params: {
      pageSize: 200, 
      pageNumber: 1,
      select: {
        $master: true, // 获取主表字段 [cite: 859]
        // 确保获取 parent_id,这对于构建树至关重要
        parent_id: true 
      }
    }
  });

  const allDepts = result.records || [];

  // 定义图标常量 (根据你的需求配置)
  const ICONS = {
    fold: "0a94df-1307578329.tcloudbaseapp.com/resources/2023-05/lowcode-1177832",
    expand: "https://lowcode-1gk9y5ik310a94df-1307578329.tcloudbaseapp.com/resources/2023-05/lowcode-1177833",
    leaf: "https://lowcode-1gk9y5ik310a94df-1307578329.tcloudbaseapp.com/resources/2023-05/lowcode-1177834"
  };

  // 2. 定义转换函数:将数据库行转换为 UI 组件节点格式
  const transformNode = (dept) => {
    return {
      label: dept.name || '未命名部门',    // 组件要求的 label
      value: dept._id,                    // 组件要求的 value
      // 这里的 parentId 处理要小心,关联关系通常返回对象 {_id: "..."}
      parentId: dept.parent_id ? dept.parent_id._id : null, 
      foldIcon: ICONS.fold,
      expendIcon: ICONS.expand,
      // 预留 children 数组
      children: []
    };
  };

  // 3. 构建树的核心算法 (Map 映射法)
  const buildTree = (items) => {
    const tree = [];
    const map = {};

    // 第一轮遍历:初始化所有节点并存入 Map
    items.forEach(item => {
      const node = transformNode(item);
      map[node.value] = node; // 以 ID 为 Key 存入 Map
    });

    // 第二轮遍历:利用引用组装树
    items.forEach(item => {
      const node = map[item._id];
      const parentId = node.parentId;

      if (parentId && map[parentId]) {
        // 如果有父节点,且父节点在数据中存在,则加入父节点的 children
        map[parentId].children.push(node);
      } else {
        // 如果没有父节点(或父节点找不到),则视为根节点
        tree.push(node);
      }
    });

    return tree;
  };

  // 4. 执行转换并返回
  const treeData = buildTree(allDepts);
  
  // 可选:后期处理,例如如果是叶子节点(children为空),可以赋予特定的 leafIcon
  // 或处理 disabled 状态
  
  return treeData;
};

上述代码主要是把扁平的数据重新组织成树形目录。这样做有一个问题,我们用个人版去开发API,他默认的是预览库,但是后台写入的是生产库,导致我们的API没办法读取到数据。

为了解决这个问题,我们用API写入一些测试数据,再添加一个API用来生成数据

输入如下代码

bash 复制代码
/**
 * API 标识: initTestData
 * 名称: 初始化测试数据
 * 类型: 自定义代码
 */
module.exports = async function (params, context) {
  const dataSourceName = 't_department'; // 你的表名

  // 🛠️ 定义一个通用的创建函数,简化代码
  const createDept = async (name, parentId = null, level = 1) => {
    // 构造数据对象
    const record = {
      name: name,
      level: level,
      // ⚠️ 关键点:关联关系的写法。
      // 如果有 parentId,必须写成对象形式 {_id: "..."},否则写入失败
      parent_id: parentId ? { _id: parentId } : null 
    };

    // 调用微搭新建单条数据方法
    const result = await context.callModel({
      dataSourceName: dataSourceName,
      methodName: 'wedaCreateV2',
      params: {
        data: record
      }
    });

    // 返回新创建数据的 ID,供子节点使用
    return result.id || result._id; // 兼容不同版本的返回字段
  };

  try {
    console.log("开始生成测试数据...");

    // 1️⃣ 第一层:创建根节点(医院)
    const rootId = await createDept("内蒙古人民医院", null, 0);
    console.log("根节点创建成功 ID:", rootId);

    // 2️⃣ 第二层:创建分类(职能/临床)- 挂载到根节点
    const adminDeptId = await createDept("职能处室", rootId, 1);
    const clinicalDeptId = await createDept("临床科室", rootId, 1);
    const researchDeptId = await createDept("科研中心", rootId, 1);

    // 3️⃣ 第三层:创建具体科室 - 挂载到对应的第二层节点
    
    // --> 挂载到"职能处室"
    await createDept("人事处", adminDeptId, 2);
    await createDept("医务处", adminDeptId, 2);
    await createDept("办公室", adminDeptId, 2);

    // --> 挂载到"临床科室"
    await createDept("心血管内科", clinicalDeptId, 2);
    await createDept("呼吸与危重症医学科", clinicalDeptId, 2);
    await createDept("骨关节科", clinicalDeptId, 2);

    // --> 挂载到"科研中心"
    await createDept("医学科学院", researchDeptId, 2);

    return {
      success: true,
      message: "✅ 测试数据生成完毕!请去验证 getDepartmentTree 接口。",
      rootId: rootId
    };

  } catch (e) {
    console.error("生成失败", e);
    return {
      success: false,
      message: "❌ 生成失败,请查看日志",
      error: e.message
    };
  }
};

4 前端读取

我们有了后端API,主要是解决数据构造的问题,需要在前端创建一个API来读取一下数据

变量设置好之后,就可以绑定到我们的树组件上

继续创建一个变量用来保存部门的名称

当选中叶子节点,将叶子节点的信息赋值给变量

把这个变量绑定给文本,就实现了选中叶子节点,在右边显示部门名称的效果

总结

本篇我们介绍了一个稍微复杂的功能,机构树。难点在设计数据模型你就要让表进行自关联,然后用API去构造机构树,在前端绑定好数据即可。

相关推荐
流之云低代码平台11 小时前
告别繁琐合同管理,智能合同系统来助力
低代码·gadmin·智能合同系统优势·智能合同系统功能模块·智能合同系统应用案例·智能合同系统选择·企业合同管理痛点
qq_124987075312 小时前
基于微信小程序的校园跑腿系统的设计与实现(源码+论文+部署+安装)
spring boot·微信小程序·小程序·毕业设计·计算机毕业设计
小小王app小程序开发14 小时前
盲盒小程序一番赏特殊玩法超细分拆解:从底层逻辑到落地细节
大数据·小程序
说私域15 小时前
基于AI大模型与AI智能名片S2B2C商城小程序的抖音内容力构建与品牌增长研究
大数据·人工智能·小程序·开源
微爱帮监所写信寄信16 小时前
微爱帮监狱写信寄信小程序DDoS防护:智能负载均衡架构
小程序·负载均衡·ddos
计算机毕设指导616 小时前
基于微信小程序的设备报修系统【源码文末联系】
java·spring boot·微信小程序·小程序·tomcat·maven·intellij-idea
qq_124987075316 小时前
悦读圈图书共享微信小程序(源码+论文+部署+安装)
spring boot·后端·微信小程序·小程序·毕业设计·计算机毕业设计
戴西软件17 小时前
CAxWorks.VPG车辆工程仿真软件:打造新能源汽车安全的“数字防线“
android·大数据·运维·人工智能·安全·低代码·汽车
说私域1 天前
移动互联网生态下定制开发开源AI智能名片S2B2C商城小程序源码在营销技术中的应用与发展
人工智能·小程序·开源
微爱帮监所写信寄信1 天前
微爱帮监狱写信寄信工具服务器【Linux篇章】再续:TCP协议——用技术隐喻重构网络世界的底层逻辑
linux·服务器·开发语言·网络·网络协议·小程序·监狱寄信