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

部门同步功能开发总结

📋 项目信息

  • 开发日期: 2025-10-18
  • 功能名称: 组织机构同步 - 分公司同步
  • 技术栈: Spring Boot + MyBatis + SQL Server

🎯 需求概述

从SQL Server数据库的uv_department视图中同步"合作单位"下的分公司和部门数据到若依系统的sys_dept表。

数据源SQL

SELECT b.departmentID, b.departmentName 
FROM uv_department a 
INNER JOIN uv_department b ON a.departmentID = b.parentID 
WHERE a.departmentName = '合作单位'

数据格式

SQL Server中的部门名称格式:城市--部门类型

示例:
- 湛江--护士
- 湛江--车队
- 湛江--客服
- 湛江--办公室

转换规则

  1. 提取城市名称,创建"XX分公司"
  2. 提取部门类型,作为分公司的子部门
  3. 记录SQL Server的departmentID到department_id字段

🔨 实现内容

1. 数据库修改

表结构变更

-- 在sys_dept表中添加department_id字段
ALTER TABLE sys_dept ADD COLUMN department_id INT NULL COMMENT 'SQL Server中的部门ID';
CREATE INDEX idx_department_id ON sys_dept(department_id);

文件: sql/add_department_id_to_sys_dept.sql

菜单权限

-- 添加部门同步的按钮权限
INSERT INTO sys_menu (menu_name, parent_id, order_num, url, menu_type, visible, perms, icon, create_by, create_time, remark)
SELECT '部门同步', menu_id, 6, '#', 'F', '0', 'system:dept:sync', '#', 'admin', sysdate(), '同步SQL Server分公司数据'
FROM sys_menu WHERE menu_name = '部门管理' AND menu_type = 'C' LIMIT 1;

文件: sql/dept_sync_menu.sql

2. 实体类修改

SysDept实体

文件: ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java

修改内容:
```java
/** SQL Server中的部门ID */
private Integer departmentId;

public Integer getDepartmentId() { return departmentId; }
public void setDepartmentId(Integer departmentId) { this.departmentId = departmentId; }
```

3. 新增文件

DTO层

文件: ruoyi-system/src/main/java/com/ruoyi/system/domain/DepartmentSyncDTO.java
- 功能: 部门同步数据传输对象
- 字段: departmentId, departmentName, parentId, parentName

Mapper层

文件:
- ruoyi-system/src/main/java/com/ruoyi/system/mapper/DepartmentSyncMapper.java
- ruoyi-system/src/main/resources/mapper/system/DepartmentSyncMapper.xml

主要方法:
- List<DepartmentSyncDTO> selectBranchDepartments() - 查询SQL Server分公司数据

Service层

文件:
- ruoyi-system/src/main/java/com/ruoyi/system/service/IDepartmentSyncService.java
- ruoyi-system/src/main/java/com/ruoyi/system/service/impl/DepartmentSyncServiceImpl.java

核心方法: syncBranchDepartments()

同步逻辑:
1. 从SQL Server获取分公司数据
2. 解析部门名称(城市--部门类型)
3. 创建或获取分公司(parent_id=100)
4. 创建或更新子部门
5. 记录department_id字段
6. 返回同步统计结果

Controller层

文件: ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/DepartmentSyncController.java

接口:
- POST /system/dept/sync/branch - 同步分公司数据
- 权限: system:dept:sync

4. Mapper扩展

SysDeptMapper

文件:
- ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java
- ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml

新增方法:
```java
// 根据departmentId查询部门
SysDept selectDeptByDepartmentId(@Param("departmentId") Integer departmentId);

// 根据departmentId和父部门ID查询部门
SysDept selectDeptByDepartmentIdAndParentId(@Param("departmentId") Integer departmentId, @Param("parentId") Long parentId);
```

修改内容:
- resultMap中添加department_id映射
- selectDeptVo中添加department_id字段
- insertDept中添加department_id支持
- updateDept中添加department_id支持

5. 文档

功能说明文档

文件: prd/部门同步功能说明.md
- 功能概述
- 数据处理规则
- 接口说明
- 使用步骤
- 同步示例
- 注意事项

测试指南

文件: 部门同步测试指南.md
- 测试前准备
- 测试步骤
- 验证清单
- 日志查看
- 问题排查

快速开始

文件: 部门同步-快速开始.md
- 安装步骤
- 使用方法
- 验证结果
- 核心文件清单

📊 技术特性

1. 幂等性设计

  • 多次执行不会创建重复数据
  • 通过department_id和部门名称判断是否已存在
  • 已存在则更新,不存在则创建

2. 事务保护

  • 使用@Transactional注解
  • 同步过程中出错自动回滚
  • 保证数据一致性

3. 日志记录

  • 详细记录同步过程
  • 记录创建/更新的每个部门
  • 便于问题排查

4. 错误处理

  • 捕获并返回友好的错误信息
  • 记录错误日志
  • 部分数据格式错误不影响整体同步

5. 性能优化

  • 使用Map缓存已创建的分公司
  • 减少数据库查询次数
  • 批量处理提高效率

🔍 同步流程

1. 从SQL Server查询数据
   ↓
2. 遍历每条数据
   ↓
3. 解析部门名称 (城市--部门)
   ↓
4. 检查/创建分公司
   ├─ 已存在 → 获取ID
   └─ 不存在 → 创建新分公司
   ↓
5. 检查子部门
   ├─ 根据department_id查询
   ├─ 已存在 → 更新
   └─ 不存在 → 创建
   ↓
6. 返回统计结果

📈 同步结果示例

输入(SQL Server)

departmentID | departmentName
1001        | 湛江--护士
1002        | 湛江--车队
1003        | 湛江--客服
1004        | 湛江--办公室

输出(sys_dept表)

dept_id | parent_id | dept_name    | ancestors    | department_id
200     | 100       | 湛江分公司    | 0,100        | NULL
201     | 200       | 护士         | 0,100,200    | 1001
202     | 200       | 车队         | 0,100,200    | 1002
203     | 200       | 客服         | 0,100,200    | 1003
204     | 200       | 办公室       | 0,100,200    | 1004

接口返回

{
  "code": 200,
  "msg": "同步完成!创建分公司: 1, 更新分公司: 0, 创建部门: 4, 更新部门: 0",
  "data": {
    "createdBranch": 1,
    "updatedBranch": 0,
    "createdDept": 4,
    "updatedDept": 0,
    "totalProcessed": 4
  }
}

🎓 使用示例

1. Postman调用

POST http://localhost:8080/system/dept/sync/branch
Headers:
  Authorization: Bearer eyJhbGciOiJIUzUxMiJ9...

2. curl命令

curl -X POST http://localhost:8080/system/dept/sync/branch \
  -H "Authorization: Bearer {token}"

3. 前端调用

this.$http.post('/system/dept/sync/branch').then(res => {
  this.$message.success(res.msg);
  this.getList();
});

⚙️ 配置说明

SQL Server数据源

文件: ruoyi-admin/src/main/resources/application-dev.yml

spring:
  datasource:
    druid:
      sqlserver:
        enabled: true
        url: jdbc:sqlserver://your-server:1433;DatabaseName=your-db
        username: your-username
        password: your-password
        driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver

🚀 部署清单

1. 数据库操作

  • [ ] 执行 add_department_id_to_sys_dept.sql
  • [ ] 执行 dept_sync_menu.sql(可选)

2. 代码部署

  • [ ] 编译项目: mvn clean package -DskipTests
  • [ ] 部署jar包
  • [ ] 重启服务

3. 验证测试

  • [ ] 调用同步接口
  • [ ] 检查数据库数据
  • [ ] 验证日志输出

📝 待优化项

1. 功能增强

  • [ ] 前端添加同步按钮
  • [ ] 配置定时任务自动同步
  • [ ] 添加同步历史记录
  • [ ] 添加同步失败通知

2. 性能优化

  • [ ] 批量插入优化
  • [ ] 大数据量分页处理
  • [ ] 异步同步支持

3. 监控告警

  • [ ] 同步失败告警
  • [ ] 同步数据量监控
  • [ ] 同步耗时监控

📚 参考资料

✅ 总结

本次开发完成了从SQL Server到MySQL的分公司数据同步功能,主要特点:

  1. 数据转换准确: 正确解析"城市--部门"格式,创建两级部门结构
  2. 幂等性保证: 支持重复执行,不会创建重复数据
  3. 事务安全: 使用事务保证数据一致性
  4. 日志完善: 详细记录同步过程,便于排查问题
  5. 文档齐全: 提供功能说明、测试指南、快速开始等文档

功能已完成开发和自测,可以进入测试和部署阶段。