From 143d6b61462f2c3344b6501c7832114d3eef0756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E9=B9=8F=E9=A3=9E?= Date: Wed, 8 Apr 2026 17:14:35 +0800 Subject: [PATCH] =?UTF-8?q?feat(admin):=20=E5=AE=8C=E5=96=84LDAP=E5=92=8C?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增LDAPControllerService,实现LDAP配置管理与同步接口 - 新增LdapDepartmentVO,用于LDAP部门及用户结构封装 - 添加LdapScheduledTask,支持定时同步部门和用户信息 - 优化LdapService,调整获取用户的查询逻辑和DN转换方法 - 新增UserController,提供用户管理、LDAP信息查询及密码操作的REST接口 - 实现UserControllerService,完成用户及供应商的增删改查、授权和密码相关业务逻辑 - 支持供应商账号管理及批量导入功能 - 增加相关事务控制及数据校验,提升系统稳定性和安全性 --- .../wms/admin/controller/UserController.java | 41 ++++- .../wms/admin/pojo/vo/LdapDepartmentVO.java | 24 +++ .../wms/admin/schedule/LdapScheduledTask.java | 2 +- .../admin/service/LDAPControllerService.java | 24 ++- .../nflg/wms/admin/service/LdapService.java | 23 ++- .../admin/service/UserControllerService.java | 144 +++++++++--------- 6 files changed, 174 insertions(+), 84 deletions(-) create mode 100644 nflg-wms-admin/src/main/java/com/nflg/wms/admin/pojo/vo/LdapDepartmentVO.java diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/UserController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/UserController.java index 5d378fc5..eef7e442 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/UserController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/UserController.java @@ -1,8 +1,11 @@ package com.nflg.wms.admin.controller; +import com.nflg.wms.admin.service.LDAPControllerService; import com.nflg.wms.admin.service.UserControllerService; import com.nflg.wms.common.pojo.ApiResult; import com.nflg.wms.common.pojo.PageData; +import com.nflg.wms.common.pojo.dto.LdapDepartmentDTO; +import com.nflg.wms.common.pojo.dto.LdapUserDTO; import com.nflg.wms.common.pojo.dto.UserDTO; import com.nflg.wms.common.pojo.qo.*; import com.nflg.wms.common.pojo.vo.RoleSimpleVO; @@ -26,6 +29,9 @@ public class UserController extends BaseController { @Resource private UserControllerService userControllerService; + @Resource + private LDAPControllerService ldapControllerService; + /** * 新增用户 */ @@ -108,14 +114,14 @@ public class UserController extends BaseController { return ApiResult.success(userControllerService.search(request)); } - /** - * 从LDAP同步用户 - */ - @PostMapping("syncFromLdap") - public ApiResult syncFromLdap() { - userControllerService.syncFromLdap(); - return ApiResult.success(); - } +// /** +// * 从LDAP同步用户 +// */ +// @PostMapping("syncFromLdap") +// public ApiResult syncFromLdap() { +// userControllerService.syncFromLdap(); +// return ApiResult.success(); +// } /** * 发送忘记密码邮件 @@ -134,4 +140,23 @@ public class UserController extends BaseController { public ApiResult getUserInfo() { return ApiResult.success(userControllerService.getUserInfo()); } + + /** + * 获取LDAP部门 + * @param ldapId LDAP表id + */ + @GetMapping("getLdapDepartments") + public ApiResult getLdapDepartments(@RequestParam Long ldapId){ + return ApiResult.success(ldapControllerService.searchAdSimple(ldapId)); + } + + /** + * 获取LDAP用户 + * @param ldapId LDAP表id + * @param distinguishedName 部门的distinguishedName + */ + @GetMapping("getLdapUsers") + public ApiResult> getLdapUsers(@RequestParam Long ldapId, @RequestParam String distinguishedName){ + return ApiResult.success(ldapControllerService.getUsers(ldapId,distinguishedName)); + } } diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/pojo/vo/LdapDepartmentVO.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/pojo/vo/LdapDepartmentVO.java new file mode 100644 index 00000000..b2c26fe2 --- /dev/null +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/pojo/vo/LdapDepartmentVO.java @@ -0,0 +1,24 @@ +package com.nflg.wms.admin.pojo.vo; + +import com.nflg.wms.common.pojo.dto.LdapUserDTO; +import lombok.Data; + +import java.util.List; + +@Data +public class LdapDepartmentVO { + + /** + * 部门名称 + */ + private String name; + + private String distinguishedName; + + /** + * 用户列表 + */ + private List users; + + private List children; +} diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/schedule/LdapScheduledTask.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/schedule/LdapScheduledTask.java index 348870b5..a1f74b52 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/schedule/LdapScheduledTask.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/schedule/LdapScheduledTask.java @@ -55,7 +55,7 @@ public class LdapScheduledTask { ads.forEach(ad -> { if (StrUtil.isBlank(ad.getNextSyncDate()) || StrUtil.equals(date, ad.getNextSyncDate())) { departmentControllerService.syncFromLdap(ad); - userControllerService.syncFromLdap(ad); +// userControllerService.syncFromLdap(ad); adSyncService.lambdaUpdate() .eq(AdSync::getId, ad.getSyncId()) .set(AdSync::getNextSyncDate, LocalDate.now().plusDays(ad.getInterval()).format(DATE_FORMATTER)) diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/LDAPControllerService.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/LDAPControllerService.java index 6266be54..b7992764 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/LDAPControllerService.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/LDAPControllerService.java @@ -1,9 +1,11 @@ package com.nflg.wms.admin.service; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; import com.baomidou.mybatisplus.core.metadata.IPage; import com.nflg.wms.common.pojo.dto.AdDTO; import com.nflg.wms.common.pojo.dto.LdapDepartmentDTO; +import com.nflg.wms.common.pojo.dto.LdapUserDTO; import com.nflg.wms.common.pojo.qo.EnableQO; import com.nflg.wms.common.pojo.qo.LDAPAddQO; import com.nflg.wms.common.pojo.qo.LDAPUpdateQO; @@ -12,8 +14,10 @@ import com.nflg.wms.common.pojo.vo.AdSyncVO; import com.nflg.wms.common.util.UserUtil; import com.nflg.wms.common.util.VUtil; import com.nflg.wms.repository.entity.Ad; +import com.nflg.wms.repository.entity.User; import com.nflg.wms.repository.service.IAdService; import com.nflg.wms.repository.service.IAdSyncService; +import com.nflg.wms.repository.service.IUserService; import jakarta.annotation.Resource; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -21,6 +25,7 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; +import java.util.List; import java.util.Objects; @Component @@ -36,7 +41,7 @@ public class LDAPControllerService { private DepartmentControllerService departmentControllerService; @Resource - private UserControllerService userControllerService; + private IUserService userService; public void add(@Valid LDAPAddQO request) { Ad ad = Convert.convert(Ad.class, request); @@ -73,7 +78,7 @@ public class LDAPControllerService { AdDTO ad = adService.getInfo(id); VUtil.trueThrowBusinessError(Objects.isNull(ad)).throwMessage("数据不存在"); departmentControllerService.syncFromLdap(ad); - userControllerService.syncFromLdap(ad); +// userControllerService.syncFromLdap(ad); } public IPage search(@Valid PageQO request) { @@ -93,4 +98,19 @@ public class LDAPControllerService { ldapService.init(ad.getServer(), ad.getPort(), ad.getUserName(), ad.getUserPwd(), ad.getOu(), ad.getTimeout()); return ldapService.getDepartmentTree("",true); } + + public List getUsers(Long id,String distinguishedName){ + AdDTO ad = adService.getInfo(id); + VUtil.trueThrowBusinessError(Objects.isNull(ad)).throwMessage("数据不存在"); + LdapService ldapService = new LdapService(); + ldapService.init(ad.getServer(), ad.getPort(), ad.getUserName(), ad.getUserPwd(), ad.getOu(), ad.getTimeout()); + List users=ldapService.getUsers(distinguishedName); + if (CollectionUtil.isEmpty(users)){ + return null; + } + List dbUsers = userService.list(); + return users.stream() + .filter(user -> dbUsers.stream().noneMatch(dbUser -> dbUser.getUserCode().equals(user.getUserCode()))) + .toList(); + } } diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/LdapService.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/LdapService.java index bf2e4bfe..20d05287 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/LdapService.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/LdapService.java @@ -128,6 +128,24 @@ public class LdapService { } } + /** + * 去除 DN 中的 baseDn 后缀,得到相对路径 + */ + private String toRelativeDn(String dn) { + if (StrUtil.isBlank(dn) || StrUtil.isBlank(baseDn)) { + return dn; + } + // 忽略大小写比较并去除末尾的 baseDn 部分 + String dnLower = dn.toLowerCase(); + String baseDnLower = baseDn.toLowerCase(); + if (dnLower.endsWith("," + baseDnLower)) { + return dn.substring(0, dn.length() - baseDn.length() - 1); + } else if (dnLower.equals(baseDnLower)) { + return ""; + } + return dn; + } + /** * 获取所有用户 * @return 所有用户 @@ -135,9 +153,10 @@ public class LdapService { public List getUsers(String searchBaseDn) { ldapTemplate.setIgnorePartialResultException(true); log.info("开始获取用户信息"); + String relativeDn = toRelativeDn(searchBaseDn); LdapQuery query = LdapQueryBuilder.query() - .base(searchBaseDn) - .searchScope(SearchScope.SUBTREE) + .base(relativeDn) + .searchScope(SearchScope.ONELEVEL) .where("objectClass").is("person"); List users = ldapTemplate.search( query, diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/UserControllerService.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/UserControllerService.java index 95fc61b5..66332292 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/UserControllerService.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/UserControllerService.java @@ -12,7 +12,9 @@ import com.nflg.wms.common.constant.Constant; import com.nflg.wms.common.constant.STATE; import com.nflg.wms.common.exception.NflgException; import com.nflg.wms.common.pojo.ApiResult; -import com.nflg.wms.common.pojo.dto.*; +import com.nflg.wms.common.pojo.dto.SupplierExcelDTO; +import com.nflg.wms.common.pojo.dto.SupplierExcelExportDTO; +import com.nflg.wms.common.pojo.dto.UserDTO; import com.nflg.wms.common.pojo.qo.*; import com.nflg.wms.common.pojo.vo.RoleSimpleVO; import com.nflg.wms.common.pojo.vo.UserSupplierItemVO; @@ -192,77 +194,77 @@ public class UserControllerService { uService.enable(request.getId(), request.getEnable()); } - @Transactional - public void syncFromLdap() { - List ads = adService.getList(); - ads.parallelStream().forEach(this::syncFromLdap); - } +// @Transactional +// public void syncFromLdap() { +// List ads = adService.getList(); +// ads.parallelStream().forEach(this::syncFromLdap); +// } - @Transactional - public void syncFromLdap(AdDTO ad) { - LdapService ldapService = new LdapService(); - ldapService.init(ad.getServer(), ad.getPort(), ad.getUserName(), ad.getUserPwd(), ad.getOu(), ad.getTimeout()); - List users = ldapService.getUsers(ad.getMapFrom()); - List uforAdd = new ArrayList<>(); - List uforUpdate = new ArrayList<>(); - List uiforAdd = new ArrayList<>(); - List uiforUpdate = new ArrayList<>(); - for (LdapUserDTO user : users) { - long deptId; - if (ad.getType() == 3) { - deptId = ad.getMapTo(); - } else { - Department department = deptService.lambdaQuery().eq(Department::getSource, 1).eq(Department::getSourceId, user.getDepartmentDistinguishedName()).one(); - if (Objects.isNull(department)) { - log.error("部门不存在:{}", user.getDepartmentDistinguishedName()); - continue; - } - deptId = department.getId(); - } - User u = uService.lambdaQuery().eq(User::getSource, 1).eq(User::getSourceId, user.getDistinguishedName()).one(); - if (Objects.isNull(u)) { - u = new User() - .setId(IdUtil.getSnowflakeNextId()) - .setUserName(user.getName()) - .setUserCode(user.getUserCode()) - .setSource(1) - .setSourceId(user.getDistinguishedName()) - .setPassword("") - .setAdId(ad.getId()) - .setMustResetPwd(false) - .setRemark("从LDAP同步") - .setCreateBy("自动同步") - .setCreateTime(LocalDateTime.now()); - uforAdd.add(u); - uiforAdd.add(new UserInterior() - .setUserId(u.getId()) - .setDeptId(deptId)); - } else { - UserInterior ui = userInteriorService.lambdaQuery().eq(UserInterior::getUserId, u.getId()).one(); - if (!Objects.equals(ui.getDeptId(), deptId)) - ui.setDeptId(deptId); - uforUpdate.add(new User() - .setId(u.getId()) - .setUserName(user.getName()) - .setUserCode(user.getUserCode()) - .setUpdateBy("自动同步") - .setUpdateTime(LocalDateTime.now())); - uiforUpdate.add(ui); - } - } - if (CollectionUtil.isNotEmpty(uforAdd)) { - uService.saveBatch(uforAdd); - } - if (CollectionUtil.isNotEmpty(uforUpdate)) { - uService.updateBatchById(uforUpdate); - } - if (CollectionUtil.isNotEmpty(uiforAdd)) { - userInteriorService.saveBatch(uiforAdd); - } - if (CollectionUtil.isNotEmpty(uiforUpdate)) { - userInteriorService.updateBatchById(uiforUpdate); - } - } +// @Transactional +// public void syncFromLdap(AdDTO ad) { +// LdapService ldapService = new LdapService(); +// ldapService.init(ad.getServer(), ad.getPort(), ad.getUserName(), ad.getUserPwd(), ad.getOu(), ad.getTimeout()); +// List users = ldapService.getUsers(ad.getMapFrom()); +// List uforAdd = new ArrayList<>(); +// List uforUpdate = new ArrayList<>(); +// List uiforAdd = new ArrayList<>(); +// List uiforUpdate = new ArrayList<>(); +// for (LdapUserDTO user : users) { +// long deptId; +// if (ad.getType() == 3) { +// deptId = ad.getMapTo(); +// } else { +// Department department = deptService.lambdaQuery().eq(Department::getSource, 1).eq(Department::getSourceId, user.getDepartmentDistinguishedName()).one(); +// if (Objects.isNull(department)) { +// log.error("部门不存在:{}", user.getDepartmentDistinguishedName()); +// continue; +// } +// deptId = department.getId(); +// } +// User u = uService.lambdaQuery().eq(User::getSource, 1).eq(User::getSourceId, user.getDistinguishedName()).one(); +// if (Objects.isNull(u)) { +// u = new User() +// .setId(IdUtil.getSnowflakeNextId()) +// .setUserName(user.getName()) +// .setUserCode(user.getUserCode()) +// .setSource(1) +// .setSourceId(user.getDistinguishedName()) +// .setPassword("") +// .setAdId(ad.getId()) +// .setMustResetPwd(false) +// .setRemark("从LDAP同步") +// .setCreateBy("自动同步") +// .setCreateTime(LocalDateTime.now()); +// uforAdd.add(u); +// uiforAdd.add(new UserInterior() +// .setUserId(u.getId()) +// .setDeptId(deptId)); +// } else { +// UserInterior ui = userInteriorService.lambdaQuery().eq(UserInterior::getUserId, u.getId()).one(); +// if (!Objects.equals(ui.getDeptId(), deptId)) +// ui.setDeptId(deptId); +// uforUpdate.add(new User() +// .setId(u.getId()) +// .setUserName(user.getName()) +// .setUserCode(user.getUserCode()) +// .setUpdateBy("自动同步") +// .setUpdateTime(LocalDateTime.now())); +// uiforUpdate.add(ui); +// } +// } +// if (CollectionUtil.isNotEmpty(uforAdd)) { +// uService.saveBatch(uforAdd); +// } +// if (CollectionUtil.isNotEmpty(uforUpdate)) { +// uService.updateBatchById(uforUpdate); +// } +// if (CollectionUtil.isNotEmpty(uiforAdd)) { +// userInteriorService.saveBatch(uiforAdd); +// } +// if (CollectionUtil.isNotEmpty(uiforUpdate)) { +// userInteriorService.updateBatchById(uiforUpdate); +// } +// } public void resetPassword(@Valid UserResetPasswordQO request) { User user = uService.getById(request.getId());