# 用户同步功能说明文档 ## 📋 功能概述 从SQL Server的`OA_User`表同步用户数据到若依系统的`sys_user`表,并通过`department_id`字段关联部门。 ## 🎯 数据源 ### SQL查询 ```sql SELECT OA_User_ID as OA_UserID, OA_User as user_name, OA_Name as nick_name, OA_departmentID as department_id, OA_gender as sex, OA_email as email, OA_mobile as phonenumber FROM OA_User WHERE OA_User IS NOT NULL AND OA_Name IS NOT NULL ``` ### 字段映射关系 | SQL Server字段 | 若依字段 | 说明 | |---------------|---------|------| | OA_User_ID | oa_user_id | OA用户ID(唯一标识) | | OA_User | user_name | 用户账号 | | OA_Name | nick_name | 用户昵称 | | OA_departmentID | department_id | 部门ID(通过此字段关联sys_dept) | | OA_gender | sex | 性别 | | OA_email | email | 邮箱 | | OA_mobile | phonenumber | 手机号 | ## 🔨 实现内容 ### 1. 数据库修改 #### 表结构变更 ```sql -- 在sys_user表中添加oa_user_id字段 ALTER TABLE sys_user ADD COLUMN oa_user_id INT NULL COMMENT 'SQL Server中的OA用户ID'; CREATE INDEX idx_oa_user_id ON sys_user(oa_user_id); ``` **文件**: `sql/add_oa_user_id_to_sys_user.sql` ### 2. 实体类修改 #### SysUser实体 **文件**: `ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java` **修改内容**: ```java /** SQL Server中的OA用户ID */ private Integer oaUserId; public Integer getOaUserId() { return oaUserId; } public void setOaUserId(Integer oaUserId) { this.oaUserId = oaUserId; } ``` ### 3. 核心文件 #### DTO层 **文件**: `UserSyncDTO.java` - 字段: oaUserId, userName, nickName, departmentId, sex, email, phonenumber #### Mapper层 **文件**: - `UserSyncMapper.java` - 查询SQL Server用户数据 - `UserSyncMapper.xml` - SQL映射 - `SysUserMapper.java`(扩展) - 添加根据oaUserId查询方法 - `SysUserMapper.xml`(扩展) - 添加字段映射和查询SQL #### Service层 **文件**: `UserSyncServiceImpl.java` **核心逻辑**: 1. 从SQL Server查询OA_User数据 2. 遍历每条用户数据 3. 根据department_id查找对应的dept_id 4. 检查用户是否已存在(根据oa_user_id) 5. 已存在则更新,不存在则创建 6. 记录同步统计信息 #### Controller层 **文件**: `DepartmentSyncController.java`(扩展) **接口**: - `POST /system/dept/sync/user` - 同步OA用户 - 权限: `system:user:sync` ## 🔍 同步逻辑详解 ### 部门关联逻辑 ``` 1. 获取OA_User的OA_departmentID ↓ 2. 在sys_dept表中查询department_id = OA_departmentID的记录 ↓ 3. 找到则使用该dept_id ↓ 4. 未找到则使用默认部门(100-若依科技) ``` ### 用户创建/更新逻辑 ``` 1. 根据oa_user_id查询用户 ↓ 2. 如果找到 ├─ 更新用户信息(昵称、部门、邮箱、手机、性别) └─ 返回"更新用户" ↓ 3. 如果未找到 ├─ 检查用户名是否存在 │ ├─ 存在:更新该用户的oa_user_id及其他信息 │ └─ 不存在:创建新用户 └─ 返回"创建用户"或"更新用户" ``` ### 默认值设置 创建新用户时的默认值: - **默认密码**: `123456`(加密存储) - **默认部门**: 100(若依科技) - **默认性别**: 2(未知) - **默认状态**: 0(正常) - **创建者**: sync ## 📊 接口说明 ### 同步接口 - **URL**: `POST /system/dept/sync/user` - **权限**: `system:user:sync` - **返回数据**: ```json { "code": 200, "msg": "同步完成!创建用户: 15, 更新用户: 5, 跳过: 2, 失败: 0", "data": { "created": 15, "updated": 5, "skipped": 2, "error": 0, "totalProcessed": 22 } } ``` ### 返回字段说明 - **created**: 创建的用户数量 - **updated**: 更新的用户数量 - **skipped**: 跳过的用户数量(数据不完整) - **error**: 失败的用户数量 - **totalProcessed**: 总处理数量 ## 🚀 使用步骤 ### 1. 执行数据库脚本 ```bash # 先同步部门(用户同步依赖部门数据) mysql -u root -p ry-vue < sql/add_department_id_to_sys_dept.sql # 再添加用户字段 mysql -u root -p ry-vue < sql/add_oa_user_id_to_sys_user.sql ``` ### 2. 同步部门(必须先执行) ```bash POST http://localhost:8080/system/dept/sync/branch ``` ### 3. 同步用户 ```bash POST http://localhost:8080/system/dept/sync/user Headers: Authorization: Bearer {你的token} ``` ## 💡 使用示例 ### 输入数据(SQL Server OA_User表) ``` OA_User_ID | OA_User | OA_Name | OA_departmentID | OA_gender | OA_email | OA_mobile 1001 | zhangsan | 张三 | 1001 | 0 | zhangsan@qq.com | 13800138001 1002 | lisi | 李四 | 1001 | 1 | lisi@qq.com | 13800138002 1003 | wangwu | 王五 | 1002 | 0 | wangwu@qq.com | 13800138003 ``` ### 处理过程 ``` 1. 用户zhangsan: - OA_departmentID=1001 → 查询sys_dept找到dept_id=201(护士部门) - 检查oa_user_id=1001的用户 → 不存在 - 检查用户名zhangsan → 不存在 - 创建新用户: userName=zhangsan, deptId=201, password=123456(加密) 2. 用户lisi: - OA_departmentID=1001 → dept_id=201 - 检查oa_user_id=1002的用户 → 不存在 - 检查用户名lisi → 已存在(之前手动创建的) - 更新用户: 设置oaUserId=1002, deptId=201 3. 用户wangwu: - OA_departmentID=1002 → dept_id=202(车队部门) - 检查oa_user_id=1003的用户 → 不存在 - 创建新用户: userName=wangwu, deptId=202 ``` ### 输出结果(sys_user表) ``` user_id | user_name | nick_name | dept_id | oa_user_id | email | phonenumber | password 101 | zhangsan | 张三 | 201 | 1001 | zhangsan@qq.com | 13800138001 | $2a$10$... 102 | lisi | 李四 | 201 | 1002 | lisi@qq.com | 13800138002 | (原密码) 103 | wangwu | 王五 | 202 | 1003 | wangwu@qq.com | 13800138003 | $2a$10$... ``` ## ⚙️ 特性说明 ### 1. 幂等性设计 - 通过`oa_user_id`判断用户是否已存在 - 多次同步不会创建重复用户 - 已存在用户只会更新信息 ### 2. 智能部门关联 - 通过`department_id`自动关联部门 - 未找到部门时使用默认部门 - 记录日志便于排查 ### 3. 数据完整性验证 - 验证必填字段(用户名、昵称) - 跳过不完整的数据 - 详细记录跳过原因 ### 4. 错误处理 - 单个用户失败不影响整体同步 - 记录错误日志 - 返回详细的统计信息 ### 5. 事务保护 - 使用`@Transactional`注解 - 失败自动回滚 - 保证数据一致性 ## 📝 注意事项 ### 重要提示 1. **必须先同步部门**: 用户同步依赖部门数据,必须先执行部门同步 2. **默认密码**: 新创建用户的默认密码为`123456`,建议首次登录后修改 3. **部门关联**: 如果找不到对应部门,将使用默认部门(100-若依科技) 4. **权限配置**: 需要配置`system:user:sync`权限 ### 执行顺序 ``` 1. 执行SQL脚本(部门和用户) 2. 同步部门数据 3. 同步用户数据 ``` ## 🔍 验证方法 ### 查看同步的用户 ```sql -- 查看所有同步的用户(有oa_user_id的) SELECT u.user_name, u.nick_name, u.oa_user_id, d.dept_name, u.email, u.phonenumber FROM sys_user u LEFT JOIN sys_dept d ON u.dept_id = d.dept_id WHERE u.oa_user_id IS NOT NULL ORDER BY u.oa_user_id; -- 检查部门关联情况 SELECT u.user_name, u.oa_user_id, d.dept_name, d.department_id FROM sys_user u LEFT JOIN sys_dept d ON u.dept_id = d.dept_id WHERE u.oa_user_id IS NOT NULL; -- 统计同步用户数 SELECT COUNT(*) as total_synced_users, COUNT(DISTINCT dept_id) as dept_count FROM sys_user WHERE oa_user_id IS NOT NULL; ``` ## 📚 常见问题 ### Q1: 用户同步后部门为空? A: 可能原因: 1. 部门数据未同步,先执行部门同步 2. department_id在sys_dept中不存在 3. 查看日志中的警告信息 ### Q2: 用户名重复导致创建失败? A: 系统会自动处理: 1. 如果用户名已存在,会更新该用户的oa_user_id 2. 不会创建重复用户 ### Q3: 新用户的默认密码是什么? A: 默认密码为`123456`,建议用户首次登录后修改 ### Q4: 如何重新同步某个用户? A: 直接调用同步接口即可,系统会根据oa_user_id自动判断是创建还是更新 ## 🎓 日志查看 查看同步日志: ```bash tail -f ruoyi-admin/logs/sys-info.log | grep -i "user" ``` 关键日志示例: ``` 2025-10-18 15:00:00 INFO UserSyncServiceImpl - 从SQL Server获取到 50 条用户数据 2025-10-18 15:00:01 INFO UserSyncServiceImpl - 创建新用户: 张三 (zhangsan), oaUserId: 1001, deptId: 201 2025-10-18 15:00:01 INFO UserSyncServiceImpl - 更新用户: 李四 (lisi), oaUserId: 1002 2025-10-18 15:00:01 WARN UserSyncServiceImpl - 未找到对应的部门: departmentId=9999, 用户: test 2025-10-18 15:00:02 INFO UserSyncServiceImpl - 同步完成!创建用户: 30, 更新用户: 15, 跳过: 3, 失败: 2 ``` ## 📦 完整文件清单 ### SQL脚本 - `sql/add_oa_user_id_to_sys_user.sql` - 添加字段 ### Java文件 - `SysUser.java`(修改) - 添加oaUserId字段 - `UserSyncDTO.java` - 用户同步DTO - `UserSyncMapper.java` + XML - 查询SQL Server数据 - `SysUserMapper.java`(扩展) - 添加查询方法 - `SysUserMapper.xml`(扩展) - 添加SQL映射 - `IUserSyncService.java` - Service接口 - `UserSyncServiceImpl.java` - Service实现(核心逻辑) - `DepartmentSyncController.java`(扩展) - 添加用户同步接口 ### 文档 - `prd/用户同步功能说明.md` - 本文档 ## 🔗 相关文档 - [部门同步功能说明](部门同步功能说明.md) - [部门同步测试指南](../部门同步测试指南.md) ## ✅ 作者 ruoyi ## 📅 日期 2025-10-18