From d7dc81455d8bb8ca23c394150cebc1829722e501 Mon Sep 17 00:00:00 2001 From: JEECG <445654970@qq.com> Date: Sun, 14 Sep 2025 11:53:36 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90v3.8.3=E3=80=91=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=BB=84=E7=BB=87=E6=9C=BA=E6=9E=84=E5=A4=A7=E6=94=B9=E9=80=A0?= =?UTF-8?q?=EF=BC=88=E6=96=B0=E5=A2=9E=E4=B8=BB=E5=B2=97=E4=BD=8D=E3=80=81?= =?UTF-8?q?=E4=B8=BB=E5=B2=97=E4=BD=8D=E3=80=81=E7=94=A8=E6=88=B7=E7=AD=BE?= =?UTF-8?q?=E5=90=8D=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constant/enums/DepartCategoryEnum.java | 97 ++++ .../constant/enums/PositionLevelEnum.java | 180 ++++++ .../org/jeecg/common/system/vo/LoginUser.java | 4 + .../jeecg/common/system/api/ISysBaseAPI.java | 60 +- .../api/fallback/SysBaseAPIFallback.java | 25 + .../jeecg/common/system/api/ISysBaseAPI.java | 48 ++ .../api/controller/SystemApiController.java | 58 ++ .../controller/SysDepartController.java | 93 +++- .../controller/SysPositionController.java | 2 + .../controller/SysTenantController.java | 22 + .../controller/SysUserAgentController.java | 265 --------- .../system/controller/SysUserController.java | 258 ++++----- .../modules/system/entity/SysDataLog.java | 11 +- .../modules/system/entity/SysDepart.java | 21 +- .../jeecg/modules/system/entity/SysLog.java | 7 + .../modules/system/entity/SysPosition.java | 15 +- .../modules/system/entity/SysTenantPack.java | 7 + .../jeecg/modules/system/entity/SysUser.java | 32 ++ .../modules/system/entity/SysUserAgent.java | 74 --- .../modules/system/entity/SysUserDepPost.java | 85 +++ .../excelstyle/ExcelExportSysUserStyle.java | 34 ++ .../system/mapper/SysDepartMapper.java | 60 +- .../system/mapper/SysUserAgentMapper.java | 17 - .../system/mapper/SysUserDepPostMapper.java | 25 + .../modules/system/mapper/SysUserMapper.java | 34 +- .../system/mapper/xml/SysDepartMapper.xml | 54 +- .../system/mapper/xml/SysUserAgentMapper.xml | 5 - .../system/mapper/xml/SysUserMapper.xml | 124 +++++ .../modules/system/model/DepartIdModel.java | 13 + .../system/model/SysDepartTreeModel.java | 28 +- .../system/model/SysUserSysDepPostModel.java | 139 +++++ .../service/ISysAnnouncementService.java | 10 + .../system/service/ISysDepartService.java | 46 +- .../system/service/ISysUserAgentService.java | 14 - .../service/ISysUserDepPostService.java | 13 + .../system/service/ISysUserDepartService.java | 14 + .../system/service/ISysUserService.java | 41 +- .../service/impl/SysDepartServiceImpl.java | 524 +++++++++++++++++- .../service/impl/SysUserAgentServiceImpl.java | 19 - .../impl/SysUserDepPostServiceImpl.java | 16 + .../impl/SysUserDepartServiceImpl.java | 98 ++++ .../service/impl/SysUserServiceImpl.java | 456 +++++++++++++-- .../system/util/ImportSysUserCache.java | 53 ++ .../modules/system/vo/SysDepartExportVo.java | 3 + .../system/vo/SysDepartPositionVo.java | 53 ++ .../system/vo/SysPositionSelectTreeVo.java | 83 +++ .../jeecg/modules/system/vo/SysUserDepVo.java | 10 + .../modules/system/vo/SysUserExportVo.java | 35 +- .../modules/system/vo/SysUserImportVo.java | 129 +++++ .../modules/system/vo/SysUserTenantVo.java | 13 +- .../modules/system/test/SysUserApiTest.java | 3 - 51 files changed, 2869 insertions(+), 661 deletions(-) create mode 100644 jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/DepartCategoryEnum.java create mode 100644 jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/PositionLevelEnum.java delete mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserAgentController.java delete mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysUserAgent.java create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysUserDepPost.java create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/excelstyle/ExcelExportSysUserStyle.java delete mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserAgentMapper.java create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserDepPostMapper.java delete mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserAgentMapper.xml create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/model/SysUserSysDepPostModel.java delete mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserAgentService.java create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserDepPostService.java delete mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserAgentServiceImpl.java create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepPostServiceImpl.java create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/util/ImportSysUserCache.java create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysDepartPositionVo.java create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysPositionSelectTreeVo.java create mode 100644 jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserImportVo.java diff --git a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/DepartCategoryEnum.java b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/DepartCategoryEnum.java new file mode 100644 index 000000000..1f018feea --- /dev/null +++ b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/DepartCategoryEnum.java @@ -0,0 +1,97 @@ +package org.jeecg.common.constant.enums; + +import org.jeecg.common.util.oConvertUtils; + +/** +* @Description: 部门类型枚举类 +* +* @author: wangshuai +* @date: 2025/8/19 21:37 +*/ +public enum DepartCategoryEnum { + + DEPART_CATEGORY_COMPANY("部门类型:公司","公司","1"), + DEPART_CATEGORY_DEPART("部门类型:部门","部门","2"), + DEPART_CATEGORY_POST("部门类型:岗位","岗位","3"), + DEPART_CATEGORY_SUB_COMPANY("部门类型:子公司","子公司","4"); + + DepartCategoryEnum(String described, String name, String value) { + this.value = value; + this.name = name; + this.described = described; + } + + /** + * 描述 + */ + private String described; + /** + * 值 + */ + private String value; + + /** + * 名称 + */ + private String name; + + public String getDescribed() { + return described; + } + + public void setDescribed(String described) { + this.described = described; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + /** + * 根据值获取名称 + * + * @param value + * @return + */ + public static String getNameByValue(String value){ + if (oConvertUtils.isEmpty(value)) { + return null; + } + for (DepartCategoryEnum val : values()) { + if (val.getValue().equals(value)) { + return val.getName(); + } + } + return value; + } + + /** + * 根据名称获取值 + * + * @param name + * @return + */ + public static String getValueByName(String name){ + if (oConvertUtils.isEmpty(name)) { + return null; + } + for (DepartCategoryEnum val : values()) { + if (val.getName().equals(name)) { + return val.getValue(); + } + } + return name; + } +} diff --git a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/PositionLevelEnum.java b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/PositionLevelEnum.java new file mode 100644 index 000000000..fedab9e5a --- /dev/null +++ b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/PositionLevelEnum.java @@ -0,0 +1,180 @@ +package org.jeecg.common.constant.enums; + +import java.util.Arrays; +import java.util.List; + +/** + * 职级枚举类 + * + * 注意:此枚举仅适用于天津临港控股OA项目,职级的名称和等级均为写死(需要与数据库配置一致) + * @date 2025-08-26 + * @author scott + */ +public enum PositionLevelEnum { + + // 领导层级(等级1-3) + CHAIRMAN("董事长", 1, PositionType.LEADER), + GENERAL_MANAGER("总经理", 2, PositionType.LEADER), + VICE_GENERAL_MANAGER("副总经理", 3, PositionType.LEADER), + + // 职员层级(等级4-6) + MINISTER("部长", 4, PositionType.STAFF), + VICE_MINISTER("副部长", 5, PositionType.STAFF), + STAFF("职员", 6, PositionType.STAFF); + + private final String name; + private final int level; + private final PositionType type; + + PositionLevelEnum(String name, int level, PositionType type) { + this.name = name; + this.level = level; + this.type = type; + } + + public String getName() { + return name; + } + + public int getLevel() { + return level; + } + + public PositionType getType() { + return type; + } + + /** + * 职级类型枚举 + */ + public enum PositionType { + STAFF("职员层级"), + LEADER("领导层级"); + + private final String desc; + + PositionType(String desc) { + this.desc = desc; + } + + public String getDesc() { + return desc; + } + } + + /** + * 根据职级名称获取枚举 + * @param name 职级名称 + * @return 职级枚举 + */ + public static PositionLevelEnum getByName(String name) { + for (PositionLevelEnum position : values()) { + if (position.getName().equals(name)) { + return position; + } + } + return null; + } + + /** + * 根据职级等级获取枚举 + * @param level 职级等级 + * @return 职级枚举 + */ + public static PositionLevelEnum getByLevel(int level) { + for (PositionLevelEnum position : values()) { + if (position.getLevel() == level) { + return position; + } + } + return null; + } + + /** + * 根据职级名称判断是否为职员层级 + * @param name 职级名称 + * @return true-职员层级,false-非职员层级 + */ + public static boolean isStaffLevel(String name) { + PositionLevelEnum position = getByName(name); + return position != null && position.getType() == PositionType.STAFF; + } + + /** + * 根据职级名称判断是否为领导层级 + * @param name 职级名称 + * @return true-领导层级,false-非领导层级 + */ + public static boolean isLeaderLevel(String name) { + PositionLevelEnum position = getByName(name); + return position != null && position.getType() == PositionType.LEADER; + } + + /** + * 比较两个职级的等级高低 + * @param name1 职级名称1 + * @param name2 职级名称2 + * @return 正数表示name1等级更高,负数表示name2等级更高,0表示等级相同 + */ + public static int compareLevel(String name1, String name2) { + PositionLevelEnum pos1 = getByName(name1); + PositionLevelEnum pos2 = getByName(name2); + + if (pos1 == null || pos2 == null) { + return 0; + } + + // 等级数字越小代表职级越高 + return pos2.getLevel() - pos1.getLevel(); + } + + /** + * 判断是否为更高等级 + * @param currentName 当前职级名称 + * @param targetName 目标职级名称 + * @return true-目标职级更高,false-目标职级不高于当前职级 + */ + public static boolean isHigherLevel(String currentName, String targetName) { + return compareLevel(targetName, currentName) > 0; + } + + /** + * 获取所有职员层级名称 + * @return 职员层级名称列表 + */ + public static List getStaffLevelNames() { + return Arrays.asList(MINISTER.getName(), VICE_MINISTER.getName(), STAFF.getName()); + } + + /** + * 获取所有领导层级名称 + * @return 领导层级名称列表 + */ + public static List getLeaderLevelNames() { + return Arrays.asList(CHAIRMAN.getName(), GENERAL_MANAGER.getName(), VICE_GENERAL_MANAGER.getName()); + } + + /** + * 获取所有职级名称(按等级排序) + * @return 所有职级名称列表 + */ + public static List getAllPositionNames() { + return Arrays.asList( + CHAIRMAN.getName(), GENERAL_MANAGER.getName(), VICE_GENERAL_MANAGER.getName(), + MINISTER.getName(), VICE_MINISTER.getName(), STAFF.getName() + ); + } + + /** + * 获取指定等级范围的职级 + * @param minLevel 最小等级 + * @param maxLevel 最大等级 + * @return 职级名称列表 + */ + public static List getPositionsByLevelRange(int minLevel, int maxLevel) { + return Arrays.stream(values()) + .filter(p -> p.getLevel() >= minLevel && p.getLevel() <= maxLevel) + .map(PositionLevelEnum::getName) + .collect(java.util.stream.Collectors.toList()); + } +} \ No newline at end of file diff --git a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/LoginUser.java b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/LoginUser.java index 5e58e3ffd..4be24555d 100644 --- a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/LoginUser.java +++ b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/LoginUser.java @@ -144,4 +144,8 @@ public class LoginUser { /**设备id uniapp推送用*/ private String clientId; + /** + * 主岗位 + */ + private String mainDepPostId; } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java b/jeecg-boot/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java index 5d2271da4..ce427704e 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java @@ -2,6 +2,7 @@ package org.jeecg.common.system.api; import com.alibaba.fastjson.JSONObject; import org.jeecg.common.api.CommonAPI; +import org.jeecg.common.api.dto.AiragFlowDTO; import org.jeecg.common.api.dto.DataLogDTO; import org.jeecg.common.api.dto.OnlineAuthDTO; import org.jeecg.common.api.dto.message.*; @@ -13,6 +14,7 @@ import org.jeecg.common.system.api.factory.SysBaseAPIFallbackFactory; import org.jeecg.common.system.vo.*; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.*; @@ -681,7 +683,7 @@ public interface ISysBaseAPI extends CommonAPI { * @return */ @GetMapping("/sys/api/getRoleCode") - String getRoleCodeById(String id); + String getRoleCodeById(@RequestParam(name = "id") String id); /** * 根据roleCode查询角色信息,可逗号分隔多个 @@ -709,7 +711,7 @@ public interface ISysBaseAPI extends CommonAPI { * @return JSONObject */ @GetMapping("/sys/api/queryUserById") - JSONObject queryUserById(String id); + JSONObject queryUserById(@RequestParam(name="id") String id); /** @@ -770,7 +772,7 @@ public interface ISysBaseAPI extends CommonAPI { * @return */ @GetMapping("/sys/api/queryUserIdsByPositionIds") - List queryUserIdsByPositionIds(List positionIds); + List queryUserIdsByPositionIds(@RequestParam("positionIds") List positionIds); /** * 根据部门和子部门下的所有用户账号 @@ -815,4 +817,56 @@ public interface ISysBaseAPI extends CommonAPI { @RequestParam(value = "currentUserName") String currentUserName ); + /** + * 根据部门编码查询公司信息 + * @param orgCode 部门编码 + * @return + * @author chenrui + * @date 2025/8/12 14:45 + */ + @GetMapping(value = "/sys/api/queryCompByOrgCode") + SysDepartModel queryCompByOrgCode(@RequestParam(name = "sysCode") String orgCode); + + /** + * 根据部门编码和层次查询上级公司 + * + * @param orgCode 部门编码 + * @param level 可以传空 默认为1级 最小值为1 + * @return + */ + @GetMapping(value = "/sys/api/queryCompByOrgCodeAndLevel") + SysDepartModel queryCompByOrgCodeAndLevel(@RequestParam("orgCode") String orgCode, @RequestParam("level") Integer level); + + /** + * 16 运行AIRag流程 + * for [QQYUN-13634]在baseapi里面封装方法,方便其他模块调用 + * + * @param airagFlowDTO + * @return 流程执行结果,可能是String或者Map + * @author chenrui + * @date 2025/9/2 11:43 + */ + @PostMapping(value = "/sys/api/runAiragFlow") + Object runAiragFlow(@RequestBody AiragFlowDTO airagFlowDTO); + + /** + * 根据部门code或部门id获取部门名称(当前和上级部门) + * + * @param orgCode 部门编码 + * @param depId 部门id + * @return String 部门名称 + */ + @GetMapping("/getDepartPathNameByOrgCode") + String getDepartPathNameByOrgCode(@RequestParam(name = "orgCode", required = false) String orgCode, @RequestParam(name = "depId", required = false) String depId); + + + /** + * 根据部门ID查询部门及其子部门下用户ID
+ * @param deptIds + * @return + * @author chenrui + * @date 2025/09/08 15:28 + */ + @GetMapping("/sys/api/queryUserIdsByCascadeDeptIds") + List queryUserIdsByCascadeDeptIds(@RequestParam("deptIds") List deptIds); } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java b/jeecg-boot/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java index 804d4d5a5..0d3ea50a6 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java @@ -3,6 +3,7 @@ package org.jeecg.common.system.api.fallback; import com.alibaba.fastjson.JSONObject; import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.api.dto.AiragFlowDTO; import org.jeecg.common.api.dto.DataLogDTO; import org.jeecg.common.api.dto.OnlineAuthDTO; import org.jeecg.common.api.dto.message.*; @@ -475,4 +476,28 @@ public class SysBaseAPIFallback implements ISysBaseAPI { } + @Override + public SysDepartModel queryCompByOrgCode(String orgCode) { + return null; + } + + @Override + public SysDepartModel queryCompByOrgCodeAndLevel(String orgCode, Integer level) { + return null; + } + + @Override + public Object runAiragFlow(AiragFlowDTO airagFlowDTO) { + return null; + } + + @Override + public String getDepartPathNameByOrgCode(String orgCode, String depId) { + return ""; + } + + @Override + public List queryUserIdsByCascadeDeptIds(List deptIds) { + return null; + } } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-api/jeecg-system-local-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java b/jeecg-boot/jeecg-module-system/jeecg-system-api/jeecg-system-local-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java index 2b1d733df..758deebeb 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-api/jeecg-system-local-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-api/jeecg-system-local-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java @@ -2,12 +2,14 @@ package org.jeecg.common.system.api; import com.alibaba.fastjson.JSONObject; import org.jeecg.common.api.CommonAPI; +import org.jeecg.common.api.dto.AiragFlowDTO; import org.jeecg.common.api.dto.DataLogDTO; import org.jeecg.common.api.dto.OnlineAuthDTO; import org.jeecg.common.api.dto.message.*; import org.jeecg.common.constant.enums.DySmsEnum; import org.jeecg.common.constant.enums.EmailTemplateEnum; import org.jeecg.common.system.vo.*; +import org.springframework.web.bind.annotation.RequestParam; import java.util.List; import java.util.Map; @@ -504,6 +506,14 @@ public interface ISysBaseAPI extends CommonAPI { * @return */ List queryUserIdsByDeptIds(List deptIds); + + + /** + * 根据部门ID查询部门及其子部门下用户ID
+ * @param deptIds + * @return + */ + List queryUserIdsByCascadeDeptIds(List deptIds); /** * 根据部门ID查询用户账号 @@ -557,4 +567,42 @@ public interface ISysBaseAPI extends CommonAPI { * @param currentUserName */ void announcementAutoRelease(String dataId, String currentUserName); + + /** + * 根据部门编码查询公司信息 + * @param orgCode 部门编码 + * @return + * @author chenrui + * @date 2025/8/12 14:53 + */ + SysDepartModel queryCompByOrgCode(@RequestParam(name = "sysCode") String orgCode); + + /** + * 根据部门编码和层次查询上级公司 + * + * @param orgCode 部门编码 + * @param level 可以传空 默认为1级 最小值为1 + * @return + */ + SysDepartModel queryCompByOrgCodeAndLevel(String orgCode, Integer level); + + /** + * 16 运行AIRag流程 + * for [QQYUN-13634]在baseapi里面封装方法,方便其他模块调用 + * + * @param airagFlowDTO + * @return 流程执行结果,可能是String或者Map + * @author chenrui + * @date 2025/9/2 11:43 + */ + Object runAiragFlow(AiragFlowDTO airagFlowDTO); + + /** + * 根据部门code或部门id获取部门名称(当前和上级部门) + * + * @param orgCode 部门编码 + * @param depId 部门id + * @return String 部门名称 + */ + String getDepartPathNameByOrgCode(String orgCode, String depId); } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/api/controller/SystemApiController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/api/controller/SystemApiController.java index 32aae7b9c..d6d6f9fd5 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/api/controller/SystemApiController.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/api/controller/SystemApiController.java @@ -2,6 +2,7 @@ package org.jeecg.modules.api.controller; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.api.dto.AiragFlowDTO; import org.jeecg.common.api.dto.DataLogDTO; import org.jeecg.common.api.dto.OnlineAuthDTO; import org.jeecg.common.api.dto.message.*; @@ -1014,4 +1015,61 @@ public class SystemApiController { sysBaseApi.announcementAutoRelease(dataId, currentUserName); } + /** + * 根据部门编码查询公司信息 + * @param orgCode 部门编码 + * @return + * @author chenrui + * @date 2025/8/12 14:45 + */ + @GetMapping(value = "/queryCompByOrgCode") + SysDepartModel queryCompByOrgCode(@RequestParam(name = "sysCode") String orgCode) { + return sysBaseApi.queryCompByOrgCode(orgCode); + } + + /** + * 根据部门编码和层次查询上级公司 + * + * @param orgCode 部门编码 + * @param level 可以传空 默认为1级 最小值为1 + * @return + */ + @GetMapping(value = "/queryCompByOrgCodeAndLevel") + SysDepartModel queryCompByOrgCodeAndLevel(@RequestParam("orgCode") String orgCode, @RequestParam("level") Integer level){ + return sysBaseApi.queryCompByOrgCodeAndLevel(orgCode,level); + } + + /** + * 运行AIRag流程 + * for [QQYUN-13634]在baseapi里面封装方法,方便其他模块调用 + * @param airagFlowDTO + * @return 流程执行结果,可能是String或者Map + * @return + */ + @PostMapping(value = "/runAiragFlow") + Object runAiragFlow(@RequestBody AiragFlowDTO airagFlowDTO) { + return sysBaseApi.runAiragFlow(airagFlowDTO); + } + + /** + * 根据部门code或部门id获取部门名称(当前和上级部门) + * + * @param orgCode 部门编码 + * @param depId 部门id + * @return String 部门名称 + */ + @GetMapping(value = "/getDepartPathNameByOrgCode") + String getDepartPathNameByOrgCode(@RequestParam(name = "orgCode", required = false) String orgCode, @RequestParam(name = "depId", required = false) String depId) { + return sysBaseApi.getDepartPathNameByOrgCode(orgCode, depId); + } + + /** + * 根据部门ID查询用户ID + * @param deptIds + * @return + */ + @GetMapping("/queryUserIdsByCascadeDeptIds") + public List queryUserIdsByCascadeDeptIds(@RequestParam("deptIds") List deptIds){ + return sysBaseApi.queryUserIdsByCascadeDeptIds(deptIds); + } } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java index 5e1b1232f..93d179edf 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java @@ -2,7 +2,6 @@ package org.jeecg.modules.system.controller; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.shiro.SecurityUtils; @@ -11,22 +10,22 @@ import org.jeecg.common.api.vo.Result; import org.jeecg.common.config.TenantContext; import org.jeecg.common.constant.CacheConstant; import org.jeecg.common.constant.CommonConstant; -import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.util.JwtUtil; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.ImportExcelUtil; import org.jeecg.common.util.RedisUtil; -import org.jeecg.common.util.YouBianCodeUtil; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; import org.jeecg.modules.system.entity.SysDepart; import org.jeecg.modules.system.entity.SysUser; +import org.jeecg.modules.system.excelstyle.ExcelExportSysUserStyle; import org.jeecg.modules.system.model.DepartIdModel; import org.jeecg.modules.system.model.SysDepartTreeModel; import org.jeecg.modules.system.service.ISysDepartService; import org.jeecg.modules.system.service.ISysUserDepartService; import org.jeecg.modules.system.service.ISysUserService; import org.jeecg.modules.system.vo.SysDepartExportVo; +import org.jeecg.modules.system.vo.SysPositionSelectTreeVo; import org.jeecg.modules.system.vo.lowapp.ExportDepartVo; import org.jeecgframework.poi.excel.ExcelImportUtil; import org.jeecgframework.poi.excel.def.NormalExcelConstants; @@ -148,6 +147,32 @@ public class SysDepartController { return result; } + /** + * 异步查询部门和岗位list + * @param parentId 父节点 异步加载时传递 + * @param ids 前端回显是传递 + * @param primaryKey 主键字段(id或者orgCode) + * @return + */ + @RequestMapping(value = "/queryDepartAndPostTreeSync", method = RequestMethod.GET) + public Result> queryDepartAndPostTreeSync(@RequestParam(name = "pid", required = false) String parentId, + @RequestParam(name = "ids", required = false) String ids, + @RequestParam(name = "primaryKey", required = false) String primaryKey, + @RequestParam(name = "departIds", required = false) String departIds, + @RequestParam(name = "name", required = false) String orgName) { + Result> result = new Result<>(); + try { + List list = sysDepartService.queryDepartAndPostTreeSync(parentId,ids, primaryKey, departIds, orgName); + result.setResult(list); + result.setSuccess(true); + } catch (Exception e) { + log.error(e.getMessage(),e); + result.setSuccess(false); + result.setMessage("查询失败"); + } + return result; + } + /** * 获取某个部门的所有父级部门的ID * @@ -321,7 +346,10 @@ public class SysDepartController { * @return */ @RequestMapping(value = "/searchBy", method = RequestMethod.GET) - public Result> searchBy(@RequestParam(name = "keyWord", required = true) String keyWord,@RequestParam(name = "myDeptSearch", required = false) String myDeptSearch) { + public Result> searchBy(@RequestParam(name = "keyWord", required = true) String keyWord, + @RequestParam(name = "myDeptSearch", required = false) String myDeptSearch, + @RequestParam(name = "orgCategory", required = false) String orgCategory, + @RequestParam(name = "departIds", required = false) String depIds) { Result> result = new Result>(); //部门查询,myDeptSearch为1时为我的部门查询,登录用户为上级时查只查负责部门下数据 LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); @@ -329,7 +357,7 @@ public class SysDepartController { if(oConvertUtils.isNotEmpty(user.getUserIdentity()) && user.getUserIdentity().equals( CommonConstant.USER_IDENTITY_2 )){ departIds = user.getDepartIds(); } - List treeList = this.sysDepartService.searchByKeyWord(keyWord,myDeptSearch,departIds); + List treeList = this.sysDepartService.searchByKeyWord(keyWord,myDeptSearch,departIds,orgCategory,depIds); if (treeList == null || treeList.size() == 0) { result.setSuccess(false); result.setMessage("未查询匹配数据!"); @@ -382,11 +410,14 @@ public class SysDepartController { mv.addObject(NormalExcelConstants.FILE_NAME, "部门列表"); mv.addObject(NormalExcelConstants.CLASS, SysDepartExportVo.class); LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); - mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("导入规则:\n" + - "1、标题为第三行,部门路径和部门名称的标题不允许修改,否则会匹配失败;第四行为数据填写范围;\n" + - "2、部门路径用英文字符/分割,部门名称为部门路径的最后一位;\n" + - "3、部门从一级名称开始创建,如果有同级就需要多添加一行,如研发部/研发一部;研发部/研发二部;\n" + - "4、自定义的部门编码需要满足规则才能导入。如一级部门编码为A01,那么子部门为A01A01,同级子部门为A01A02,编码固定为三位,首字母为A-Z,后两位为数字0-99,依次递增;", "导出人:"+user.getRealname(), "导出信息")); + ExportParams exportParams = new ExportParams("导入规则:\n" + + "1、标题为第三行,部门路径和部门名称的标题不允许修改,否则会匹配失败;第四行为数据填写范围;\n" + + "2、部门路径用英文字符/分割,部门名称为部门路径的最后一位;\n" + + "3、部门从一级名称开始创建,如果有同级就需要多添加一行,如研发部/研发一部;研发部/研发二部;\n" + + "4、自定义的部门编码需要满足规则才能导入。如一级部门编码为A01,那么子部门为A01A01,同级子部门为A01A02,编码固定为三位,首字母为A-Z,后两位为数字0-99,依次递增;", "导出人:" + user.getRealname(), "导出信息"); + exportParams.setTitleHeight((short)70); + exportParams.setStyle(ExcelExportSysUserStyle.class); + mv.addObject(NormalExcelConstants.PARAMS, exportParams); mv.addObject(NormalExcelConstants.DATA_LIST, sysDepartExportVos); //update-end---author:wangshuai---date:2023-10-19---for:【QQYUN-5482】系统的部门导入导出也可以改成敲敲云模式的部门路径--- @@ -580,6 +611,11 @@ public class SysDepartController { String[] ids = deptIds.split(","); Collection idList = Arrays.asList(ids); Collection deptList = sysDepartService.listByIds(idList); + // 设置部门路径名称 + for (SysDepart depart : deptList) { + String departPathName = sysDepartService.getDepartPathNameByOrgCode(depart.getOrgCode(),null); + depart.setDepartPathName(departPathName); + } result.setSuccess(true); result.setResult(deptList); return result; @@ -685,5 +721,40 @@ public class SysDepartController { } return Result.error("文件导入失败!"); } - + + /** + * 根据部门id和职级id获取岗位信息 + */ + @GetMapping("/getPositionByDepartId") + public Result> getPositionByDepartId(@RequestParam(name = "parentId") String parentId, + @RequestParam(name = "departId",required = false) String departId, + @RequestParam(name = "positionId") String positionId){ + List positionByDepartId = sysDepartService.getPositionByDepartId(parentId, departId, positionId); + return Result.OK(positionByDepartId); + } + + /** + * 获取职级关系 + * @param departId + * @return + */ + @GetMapping("/getRankRelation") + public Result> getRankRelation(@RequestParam(name = "departId") String departId){ + List list = sysDepartService.getRankRelation(departId); + return Result.ok(list); + } + + /** + * 根据部门code获取当前和上级部门名称 + * + * @param orgCode + * @param depId + * @return String 部门名称 + */ + @GetMapping("/getDepartPathNameByOrgCode") + public Result getDepartPathNameByOrgCode(@RequestParam(name = "orgCode", required = false) String orgCode, + @RequestParam(name = "depId", required = false) String depId) { + String departName = sysDepartService.getDepartPathNameByOrgCode(orgCode, depId); + return Result.OK(departName); + } } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPositionController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPositionController.java index 31a7a82dd..a7b8045f4 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPositionController.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPositionController.java @@ -90,6 +90,8 @@ public class SysPositionController { } //------------------------------------------------------------------------------------------------ QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysPosition, req.getParameterMap()); + queryWrapper.orderByAsc("post_level"); + queryWrapper.orderByDesc("create_time"); Page page = new Page(pageNo, pageSize); IPage pageList = sysPositionService.page(page, queryWrapper); result.setSuccess(true); diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java index a6def334c..9f9a11466 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java @@ -1001,4 +1001,26 @@ public class SysTenantController { sysTenantService.deleteUser(sysUser, tenantId); return Result.ok("删除用户成功"); } + + /** + * 根据租户id和用户id获取用户的产品包列表和当前用户下的产品包id + * + * @param tenantId + * @param request + * @return + */ + @GetMapping("/listPackByTenantUserId") + public Result> listPackByTenantUserId(@RequestParam("tenantId") String tenantId, + @RequestParam("userId") String userId, + HttpServletRequest request) { + if (null == tenantId) { + return null; + } + List list = sysTenantPackService.getPackListByTenantId(tenantId); + List userPackIdList = sysTenantPackService.getPackIdByUserIdAndTenantId(userId, oConvertUtils.getInt(tenantId)); + Map map = new HashMap<>(5); + map.put("packList", list); + map.put("userPackIdList", userPackIdList); + return Result.ok(map); + } } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserAgentController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserAgentController.java deleted file mode 100644 index cd6daeed1..000000000 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserAgentController.java +++ /dev/null @@ -1,265 +0,0 @@ -package org.jeecg.modules.system.controller; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.shiro.SecurityUtils; -import org.jeecg.common.api.vo.Result; -import org.jeecg.common.system.query.QueryGenerator; -import org.jeecg.common.system.vo.LoginUser; -import org.jeecg.common.util.oConvertUtils; -import org.jeecg.modules.system.entity.SysUserAgent; -import org.jeecg.modules.system.service.ISysUserAgentService; -import org.jeecgframework.poi.excel.ExcelImportUtil; -import org.jeecgframework.poi.excel.def.NormalExcelConstants; -import org.jeecgframework.poi.excel.entity.ExportParams; -import org.jeecgframework.poi.excel.entity.ImportParams; -import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.multipart.MultipartHttpServletRequest; -import org.springframework.web.servlet.ModelAndView; - -import com.alibaba.fastjson.JSON; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; - -import lombok.extern.slf4j.Slf4j; - - /** - * @Title: Controller - * @Description: 用户代理人设置 - * @Author: jeecg-boot - * @Date: 2019-04-17 - * @Version: V1.0 - */ -@RestController -@RequestMapping("/sys/sysUserAgent") -@Slf4j -public class SysUserAgentController { - @Autowired - private ISysUserAgentService sysUserAgentService; - - @Value("${jeecg.path.upload}") - private String upLoadPath; - - /** - * 分页列表查询 - * @param sysUserAgent - * @param pageNo - * @param pageSize - * @param req - * @return - */ - @GetMapping(value = "/list") - public Result> queryPageList(SysUserAgent sysUserAgent, - @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, - @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, - HttpServletRequest req) { - Result> result = new Result>(); - QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysUserAgent, req.getParameterMap()); - Page page = new Page(pageNo, pageSize); - IPage pageList = sysUserAgentService.page(page, queryWrapper); - result.setSuccess(true); - result.setResult(pageList); - return result; - } - - /** - * 添加 - * @param sysUserAgent - * @return - */ - @PostMapping(value = "/add") - public Result add(@RequestBody SysUserAgent sysUserAgent) { - Result result = new Result(); - try { - sysUserAgentService.save(sysUserAgent); - result.success("代理人设置成功!"); - } catch (Exception e) { - log.error(e.getMessage(),e); - result.error500("操作失败"); - } - return result; - } - - /** - * 编辑 - * @param sysUserAgent - * @return - */ - @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) - public Result edit(@RequestBody SysUserAgent sysUserAgent) { - Result result = new Result(); - SysUserAgent sysUserAgentEntity = sysUserAgentService.getById(sysUserAgent.getId()); - if(sysUserAgentEntity==null) { - result.error500("未找到对应实体"); - }else { - boolean ok = sysUserAgentService.updateById(sysUserAgent); - //TODO 返回false说明什么? - if(ok) { - result.success("代理人设置成功!"); - } - } - - return result; - } - - /** - * 通过id删除 - * @param id - * @return - */ - @DeleteMapping(value = "/delete") - public Result delete(@RequestParam(name="id",required=true) String id) { - Result result = new Result(); - SysUserAgent sysUserAgent = sysUserAgentService.getById(id); - if(sysUserAgent==null) { - result.error500("未找到对应实体"); - }else { - boolean ok = sysUserAgentService.removeById(id); - if(ok) { - result.success("删除成功!"); - } - } - - return result; - } - - /** - * 批量删除 - * @param ids - * @return - */ - @DeleteMapping(value = "/deleteBatch") - public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { - Result result = new Result(); - if(ids==null || "".equals(ids.trim())) { - result.error500("参数不识别!"); - }else { - this.sysUserAgentService.removeByIds(Arrays.asList(ids.split(","))); - result.success("删除成功!"); - } - return result; - } - - /** - * 通过id查询 - * @param id - * @return - */ - @GetMapping(value = "/queryById") - public Result queryById(@RequestParam(name="id",required=true) String id) { - Result result = new Result(); - SysUserAgent sysUserAgent = sysUserAgentService.getById(id); - if(sysUserAgent==null) { - result.error500("未找到对应实体"); - }else { - result.setResult(sysUserAgent); - result.setSuccess(true); - } - return result; - } - - /** - * 通过userName查询 - * @param userName - * @return - */ - @GetMapping(value = "/queryByUserName") - public Result queryByUserName(@RequestParam(name="userName",required=true) String userName) { - Result result = new Result(); - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); - queryWrapper.eq(SysUserAgent::getUserName, userName); - SysUserAgent sysUserAgent = sysUserAgentService.getOne(queryWrapper); - if(sysUserAgent==null) { - result.error500("未找到对应实体"); - }else { - result.setResult(sysUserAgent); - result.setSuccess(true); - } - return result; - } - - /** - * 导出excel - * - * @param sysUserAgent - * @param request - */ - @RequestMapping(value = "/exportXls") - public ModelAndView exportXls(SysUserAgent sysUserAgent,HttpServletRequest request) { - // Step.1 组装查询条件 - QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysUserAgent, request.getParameterMap()); - //Step.2 AutoPoi 导出Excel - ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); - List pageList = sysUserAgentService.list(queryWrapper); - //导出文件名称 - mv.addObject(NormalExcelConstants.FILE_NAME, "用户代理人设置列表"); - mv.addObject(NormalExcelConstants.CLASS, SysUserAgent.class); - LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); - ExportParams exportParams = new ExportParams("用户代理人设置列表数据", "导出人:"+user.getRealname(), "导出信息"); - exportParams.setImageBasePath(upLoadPath); - mv.addObject(NormalExcelConstants.PARAMS, exportParams); - mv.addObject(NormalExcelConstants.DATA_LIST, pageList); - return mv; - } - - /** - * 通过excel导入数据 - * - * @param request - * @param response - * @return - */ - @RequestMapping(value = "/importExcel", method = RequestMethod.POST) - public Result importExcel(HttpServletRequest request, HttpServletResponse response) { - MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; - Map fileMap = multipartRequest.getFileMap(); - for (Map.Entry entity : fileMap.entrySet()) { - // 获取上传文件对象 - MultipartFile file = entity.getValue(); - ImportParams params = new ImportParams(); - params.setTitleRows(2); - params.setHeadRows(1); - params.setNeedSave(true); - try { - List listSysUserAgents = ExcelImportUtil.importExcel(file.getInputStream(), SysUserAgent.class, params); - for (SysUserAgent sysUserAgentExcel : listSysUserAgents) { - sysUserAgentService.save(sysUserAgentExcel); - } - return Result.ok("文件导入成功!数据行数:" + listSysUserAgents.size()); - } catch (Exception e) { - log.error(e.getMessage(),e); - return Result.error("文件导入失败!"); - } finally { - try { - file.getInputStream().close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - return Result.error("文件导入失败!"); - } - -} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java index 0062e0d39..68d9f0458 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java @@ -3,7 +3,6 @@ package org.jeecg.modules.system.controller; import cn.hutool.core.util.RandomUtil; import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -13,10 +12,8 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.apache.shiro.authz.annotation.RequiresRoles; import org.jeecg.common.api.vo.Result; import org.jeecg.common.aspect.annotation.PermissionData; -import org.jeecg.common.base.BaseMap; import org.jeecg.common.config.TenantContext; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.SymbolConstant; @@ -28,23 +25,23 @@ import org.jeecg.common.util.*; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; import org.jeecg.modules.base.service.BaseCommonService; import org.jeecg.modules.system.entity.*; +import org.jeecg.modules.system.excelstyle.ExcelExportSysUserStyle; import org.jeecg.modules.system.model.DepartIdModel; +import org.jeecg.modules.system.model.SysUserSysDepPostModel; import org.jeecg.modules.system.model.SysUserSysDepartModel; import org.jeecg.modules.system.service.*; +import org.jeecg.modules.system.util.ImportSysUserCache; import org.jeecg.modules.system.vo.SysDepartUsersVO; +import org.jeecg.modules.system.vo.SysUserExportVo; import org.jeecg.modules.system.vo.SysUserRoleVO; import org.jeecg.modules.system.vo.lowapp.DepartAndUserInfo; import org.jeecg.modules.system.vo.lowapp.UpdateDepartInfo; -import org.jeecgframework.poi.excel.ExcelImportUtil; import org.jeecgframework.poi.excel.def.NormalExcelConstants; import org.jeecgframework.poi.excel.entity.ExportParams; -import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; @@ -93,9 +90,6 @@ public class SysUserController { @Autowired private BaseCommonService baseCommonService; - @Autowired - private ISysUserAgentService sysUserAgentService; - @Autowired private ISysPositionService sysPositionService; @@ -170,7 +164,7 @@ public class SysUserController { // 保存用户走一个service 保证事务 //获取租户ids String relTenantIds = jsonObject.getString("relTenantIds"); - sysUserService.saveUser(user, selectedRoles, selectedDeparts, relTenantIds); + sysUserService.saveUser(user, selectedRoles, selectedDeparts, relTenantIds, false); baseCommonService.addLog("添加用户,username: " +user.getUsername() ,CommonConstant.LOG_TYPE_2, 2); result.success("添加成功!"); } catch (Exception e) { @@ -484,15 +478,25 @@ public class SysUserController { } //update-end--Author:kangxiaolin Date:20180825 for:[03]用户导出,如果选择数据则只导出相关数据---------------------- List pageList = sysUserService.list(queryWrapper); + List list = sysUserService.getDepartAndRoleExportMsg(pageList); //导出文件名称 mv.addObject(NormalExcelConstants.FILE_NAME, "用户列表"); - mv.addObject(NormalExcelConstants.CLASS, SysUser.class); + mv.addObject(NormalExcelConstants.CLASS, SysUserExportVo.class); LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); - ExportParams exportParams = new ExportParams("用户列表数据", "导出人:"+user.getRealname(), "导出信息"); + ExportParams exportParams = new ExportParams("导入规则:\n" + + "1. 用户名为必填项,仅支持新增数据导入;\n" + + "2. 多个部门、角色或负责部门请用英文分号 ; 分隔,如:财务部;研发部;\n" + + "3. 部门层级请用英文斜杠 / 分隔,如:北京公司/财务部/财务一部;\n" + + "4. 部门类型需与部门层级一致,也用 / 分隔,如:公司/部门/部门 或 1/3/3,多个类型用 ; 分隔。机构类型编码:公司(1),子公司(4),部门(3);\n" + + "5. 部门根据用户名匹配,若存在多个则关联最新创建的部门,不存在时自动新增;\n" + + "6. 负责部门与所属部门导入规则一致,若所属部门不包含负责部门,则不关联负责部门;\n" + + "7. 用户主岗位导入时会在部门下自动创建新岗位,职级为空时默认不与岗位建立关联。", "导出人:" + user.getRealname(), "导出信息"); + exportParams.setTitleHeight((short)70); + exportParams.setStyle(ExcelExportSysUserStyle.class); exportParams.setImageBasePath(upLoadPath); mv.addObject(NormalExcelConstants.PARAMS, exportParams); - mv.addObject(NormalExcelConstants.DATA_LIST, pageList); + mv.addObject(NormalExcelConstants.DATA_LIST, list); return mv; } @@ -506,78 +510,8 @@ public class SysUserController { @RequiresPermissions("system:user:import") @RequestMapping(value = "/importExcel", method = RequestMethod.POST) public Result importExcel(HttpServletRequest request, HttpServletResponse response)throws IOException { - MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; - Map fileMap = multipartRequest.getFileMap(); - // 错误信息 - List errorMessage = new ArrayList<>(); - int successLines = 0, errorLines = 0; - for (Map.Entry entity : fileMap.entrySet()) { - MultipartFile file = entity.getValue();// 获取上传文件对象 - ImportParams params = new ImportParams(); - params.setTitleRows(2); - params.setHeadRows(1); - params.setNeedSave(true); - try { - List listSysUsers = ExcelImportUtil.importExcel(file.getInputStream(), SysUser.class, params); - for (int i = 0; i < listSysUsers.size(); i++) { - SysUser sysUserExcel = listSysUsers.get(i); - if (StringUtils.isBlank(sysUserExcel.getPassword())) { - // 密码默认为 “123456” - sysUserExcel.setPassword("123456"); - } - // 密码加密加盐 - String salt = oConvertUtils.randomGen(8); - sysUserExcel.setSalt(salt); - String passwordEncode = PasswordUtil.encrypt(sysUserExcel.getUsername(), sysUserExcel.getPassword(), salt); - sysUserExcel.setPassword(passwordEncode); - try { - sysUserService.save(sysUserExcel); - successLines++; - } catch (Exception e) { - errorLines++; - String message = e.getMessage().toLowerCase(); - int lineNumber = i + 1; - // 通过索引名判断出错信息 - if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER_USERNAME)) { - errorMessage.add("第 " + lineNumber + " 行:用户名已经存在,忽略导入。"); - } else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER_WORK_NO)) { - errorMessage.add("第 " + lineNumber + " 行:工号已经存在,忽略导入。"); - } else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER_PHONE)) { - errorMessage.add("第 " + lineNumber + " 行:手机号已经存在,忽略导入。"); - } else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER_EMAIL)) { - errorMessage.add("第 " + lineNumber + " 行:电子邮件已经存在,忽略导入。"); - } else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_USER)) { - errorMessage.add("第 " + lineNumber + " 行:违反表唯一性约束。"); - } else { - errorMessage.add("第 " + lineNumber + " 行:未知错误,忽略导入"); - log.error(e.getMessage(), e); - } - } - // 批量将部门和用户信息建立关联关系 - String departIds = sysUserExcel.getDepartIds(); - if (StringUtils.isNotBlank(departIds)) { - String userId = sysUserExcel.getId(); - String[] departIdArray = departIds.split(","); - List userDepartList = new ArrayList<>(departIdArray.length); - for (String departId : departIdArray) { - userDepartList.add(new SysUserDepart(userId, departId)); - } - sysUserDepartService.saveBatch(userDepartList); - } - - } - } catch (Exception e) { - errorMessage.add("发生异常:" + e.getMessage()); - log.error(e.getMessage(), e); - } finally { - try { - file.getInputStream().close(); - } catch (IOException e) { - log.error(e.getMessage(), e); - } - } - } - return ImportExcelUtil.imporReturnRes(errorLines,successLines,errorMessage); + //return ImportOldUserUtil.importOldSysUser(request); + return sysUserService.importSysUser(request); } /** @@ -614,6 +548,17 @@ public class SysUserController { return result; } + /** + * @功能:根据userName查询用户以及部门信息 + * @param userName + * @return + */ + @RequestMapping(value = "/queryUserAndDeptByName", method = RequestMethod.GET) + public Result> queryUserAndDeptByName(@RequestParam(name = "userName") String userName) { + Map userInfo= sysUserService.queryUserAndDeptByName(userName); + return Result.ok(userInfo); + } + /** * 首页用户重置密码 */ @@ -646,7 +591,8 @@ public class SysUserController { Page page = new Page(pageNo, pageSize); String roleId = req.getParameter("roleId"); String username = req.getParameter("username"); - IPage pageList = sysUserService.getUserByRoleId(page,roleId,username); + String realname = req.getParameter("realname"); + IPage pageList = sysUserService.getUserByRoleId(page,roleId,username,realname); result.setSuccess(true); result.setResult(pageList); return result; @@ -811,38 +757,8 @@ public class SysUserController { SysUser userParams ) { IPage page = new Page(pageNo, pageSize); - IPage pageList = sysUserService.queryUserByOrgCode(orgCode, userParams, page); - List list = pageList.getRecords(); - - // 记录所有出现过的 user, key = userId - Map hasUser = new HashMap<>(list.size()); - - JSONArray resultJson = new JSONArray(list.size()); - - for (SysUserSysDepartModel item : list) { - String userId = item.getId(); - // userId - JSONObject getModel = hasUser.get(userId); - // 之前已存在过该用户,直接合并数据 - if (getModel != null) { - String departName = getModel.get("departName").toString(); - getModel.put("departName", (departName + " | " + item.getDepartName())); - } else { - // 将用户对象转换为json格式,并将部门信息合并到 json 中 - JSONObject json = JSON.parseObject(JSON.toJSONString(item)); - json.remove("id"); - json.put("userId", userId); - json.put("departId", item.getDepartId()); - json.put("departName", item.getDepartName()); -// json.put("avatar", item.getSysUser().getAvatar()); - resultJson.add(json); - hasUser.put(userId, json); - } - } - - IPage result = new Page<>(pageNo, pageSize, pageList.getTotal()); - result.setRecords(resultJson.toJavaList(JSONObject.class)); - return Result.ok(result); + IPage pageList = sysUserService.queryDepartPostUserByOrgCode(orgCode, userParams, page); + return Result.ok(pageList); } /** @@ -1227,6 +1143,14 @@ public class SysUserController { map.put("sysUserName", sysUser.getRealname()); // 当前登录用户真实名称 map.put("sysOrgCode", sysUser.getOrgCode()); // 当前登录用户部门编号 + // 【QQYUN-12930】设置部门名称 + if (oConvertUtils.isNotEmpty(sysUser.getOrgCode())) { + SysDepart sysDepart = sysDepartService.lambdaQuery().select(SysDepart::getDepartName).eq(SysDepart::getOrgCode, sysUser.getOrgCode()).one(); + if (sysDepart != null) { + map.put("sysOrgName", sysDepart.getDepartName()); // 当前登录用户部门名称 + } + } + log.debug(" ------ 通过令牌获取部分用户信息,已获取的用户信息: " + map); return Result.ok(map); @@ -1618,23 +1542,7 @@ public class SysUserController { IPage pageList = sysUserDepartService.getUserInformation(tenantId, departId,roleId, keyword, pageSize, pageNo,excludeUserIdList); return Result.OK(pageList); } - - /** - * 用户离职(新增代理人和用户状态变更操作)【低代码应用专用接口】 - * @param sysUserAgent - * @return - */ - @PutMapping("/userQuitAgent") - public Result userQuitAgent(@RequestBody SysUserAgent sysUserAgent){ - //判断id是否为空 - if(oConvertUtils.isNotEmpty(sysUserAgent.getId())){ - sysUserAgentService.updateById(sysUserAgent); - }else{ - sysUserAgentService.save(sysUserAgent); - } - sysUserService.userQuit(sysUserAgent.getUserName()); - return Result.ok("离职成功"); - } + /** * 获取被逻辑删除的用户列表,无分页【低代码应用专用接口】 @@ -1656,29 +1564,6 @@ public class SysUserController { return Result.ok(quitList); } - /** - * 更新刪除状态和离职状态【低代码应用专用接口】 - * @param jsonObject - * @return Result - */ - @PutMapping("/putCancelQuit") - public Result putCancelQuit(@RequestBody JSONObject jsonObject, HttpServletRequest request){ - String userIds = jsonObject.getString("userIds"); - String usernames = jsonObject.getString("usernames"); - Integer tenantId = oConvertUtils.getInt(TokenUtils.getTenantIdByRequest(request),0); - //将状态改成未删除 - if (StringUtils.isNotBlank(userIds)) { - userTenantService.putCancelQuit(Arrays.asList(userIds.split(SymbolConstant.COMMA)),tenantId); - } - if(StringUtils.isNotEmpty(usernames)){ - //根据用户名删除代理人 - LambdaQueryWrapper query = new LambdaQueryWrapper<>(); - query.in(SysUserAgent::getUserName,Arrays.asList(usernames.split(SymbolConstant.COMMA))); - sysUserAgentService.remove(query); - } - return Result.ok("取消离职成功"); - } - /** * 获取用户信息(vue3用户设置专用)【低代码应用专用接口】 * @return @@ -1756,7 +1641,7 @@ public class SysUserController { } return result; } - + /** * 根据关键词搜索部门和用户【low-app】 * @param keyword @@ -1876,7 +1761,7 @@ public class SysUserController { public Result importAppUser(HttpServletRequest request, HttpServletResponse response)throws IOException { return sysUserService.importAppUser(request); } - + /** * 更改手机号(敲敲云个人设置专用) * @@ -1890,7 +1775,7 @@ public class SysUserController { sysUserService.changePhone(json,username); return Result.ok("修改手机号成功!"); } - + /** * 发送短信验证码接口(修改手机号) * @@ -1929,4 +1814,53 @@ public class SysUserController { result.setMessage("发送验证码成功!"); return result; } + + /** + * 没有绑定手机号 直接修改密码 + * @param oldPassword + * @param password + * @return + */ + @PutMapping("/updatePasswordNotBindPhone") + public Result updatePasswordNotBindPhone(@RequestParam(value="oldPassword") String oldPassword, + @RequestParam(value="password") String password, + @RequestParam(value="username") String username){ + sysUserService.updatePasswordNotBindPhone(oldPassword, password, username); + return Result.OK("修改密码成功!"); + } + + /** + * 根据部门岗位选择用户【部门岗位选择用户专用】 + * @return + */ + @GetMapping("/queryDepartPostUserPageList") + public Result> queryDepartPostUserPageList( @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + @RequestParam(name = "departId", required = false) String departId, + @RequestParam(name="realname",required=false) String realname, + @RequestParam(name="username",required=false) String username, + @RequestParam(name="isMultiTranslate",required=false) String isMultiTranslate, + @RequestParam(name="id",required = false) String id){ + String[] arr = new String[]{departId, realname, username, id}; + SqlInjectionUtil.filterContent(arr, SymbolConstant.SINGLE_QUOTATION_MARK); + IPage pageList = sysUserDepartService.queryDepartPostUserPageList(departId, username, realname, pageSize, pageNo,id,isMultiTranslate); + return Result.OK(pageList); + } + + /** + * 获取上传文件的进度 + * + * @param fileKey + * @param type + * @return + */ + @GetMapping("/getUploadFileProgress") + public Result getUploadFileProgress(@RequestParam(name = "fileKey") String fileKey, + @RequestParam("type") String type){ + Double progress = ImportSysUserCache.getImportSysUserMap(fileKey, type); + if(progress == 100){ + ImportSysUserCache.removeImportLowAppMap(fileKey); + } + return Result.ok(progress); + } } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDataLog.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDataLog.java index 3eca93234..6774c23b5 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDataLog.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDataLog.java @@ -8,8 +8,11 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.SecurityUtils; +import org.jeecg.common.config.mqtoken.UserTokenContext; +import org.jeecg.common.system.util.JwtUtil; import org.jeecg.common.system.vo.LoginUser; import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.util.StringUtils; import java.io.Serializable; import java.util.Date; @@ -96,7 +99,13 @@ public class SysDataLog implements Serializable { LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); this.setCreateName(sysUser.getRealname()); } catch (Exception e) { - log.warn("SecurityUtils.getSubject() 获取用户信息异常:" + e.getMessage()); + // QQYUN-13669 进一步优化:解决某些异步场景下获取用户信息为空的问题 + String token = UserTokenContext.getToken(); + if (StringUtils.hasText(token)) { + this.setCreateName(JwtUtil.getUsername(token)); + } else { + log.warn("SecurityUtils.getSubject() 获取用户信息异常:" + e.getMessage()); + } } } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDepart.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDepart.java index d585e6644..075533eb4 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDepart.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysDepart.java @@ -35,6 +35,9 @@ public class SysDepart implements Serializable { /**机构/部门名称*/ @Excel(name="机构/部门名称",width=15) private String departName; + /**机构/部门路径名称(非持久化字段)*/ + @TableField(exist = false) + private String departPathName; /**英文名*/ @Excel(name="英文名",width=15) private String departNameEn; @@ -46,7 +49,7 @@ public class SysDepart implements Serializable { /**描述*/ @Excel(name="描述",width=15) private String description; - /**机构类别 1=公司,2=组织机构,3=岗位*/ + /**机构类别 1=公司,2=组织机构,3=岗位 4=子公司*/ @Excel(name="机构类别",width=15,dicCode="org_category") private String orgCategory; /**机构类型*/ @@ -102,7 +105,21 @@ public class SysDepart implements Serializable { @TableField(exist = false) private String oldDirectorUserIds; //update-end---author:wangshuai ---date:20200308 for:[JTC-119]新增字段负责人ids和旧的负责人ids - + + /** + * 职级id + */ + @Excel(name="职级",width=15,dictTable = "sys_position", dicCode = "id", dicText = "name") + @Dict(dictTable = "sys_position", dicCode = "id", dicText = "name") + private String positionId; + + /** + * 部门岗位id + */ + @Excel(name="上级岗位",width=15,dictTable = "sys_depart", dicCode = "id", dicText = "depart_name") + @Dict(dictTable = "sys_depart", dicCode = "id", dicText = "depart_name") + private String depPostParentId; + /** * 重写equals方法 */ diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysLog.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysLog.java index 9aa07eded..3b89d0a38 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysLog.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysLog.java @@ -3,6 +3,7 @@ package org.jeecg.modules.system.entity; import java.util.Date; import org.jeecg.common.aspect.annotation.Dict; +import org.jeecgframework.poi.excel.annotation.Excel; import org.springframework.format.annotation.DateTimeFormat; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; @@ -41,6 +42,7 @@ public class SysLog implements Serializable { /** * 创建时间 */ + @Excel(name = "创建时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; @@ -58,11 +60,13 @@ public class SysLog implements Serializable { /** * 耗时 */ + @Excel(name = "耗时(毫秒)", width = 15) private Long costTime; /** * IP */ + @Excel(name = "IP", width = 15) private String ip; /** @@ -91,10 +95,12 @@ public class SysLog implements Serializable { /** * 操作人用户账户 */ + @Excel(name = "操作人", width = 15) private String userid; /** * 操作详细日志 */ + @Excel(name = "日志内容", width = 50) private String logContent; /** @@ -112,6 +118,7 @@ public class SysLog implements Serializable { /** * 客户终端类型 pc:电脑端 app:手机端 h5:移动网页端 */ + @Excel(name = "客户端类型", width = 15, dicCode = "client_type") @Dict(dicCode = "client_type") private String clientType; diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysPosition.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysPosition.java index 1db498a9e..08078511e 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysPosition.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysPosition.java @@ -14,7 +14,7 @@ import org.jeecgframework.poi.excel.annotation.Excel; import org.springframework.format.annotation.DateTimeFormat; /** - * @Description: 职务表 + * @Description: 职务级别 * @Author: jeecg-boot * @Date: 2019-09-19 * @Version: V1.0 @@ -23,7 +23,7 @@ import org.springframework.format.annotation.DateTimeFormat; @TableName("sys_position") @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) -@Schema(description="职务表") +@Schema(description="职务级别表") public class SysPosition { /** @@ -39,18 +39,17 @@ public class SysPosition { @Schema(description = "职务编码") private java.lang.String code; /** - * 职务名称 + * 职务级别名称 */ - @Excel(name = "职务名称", width = 15) - @Schema(description = "职务名称") + @Excel(name = "职务级别名称", width = 15) + @Schema(description = "职务级别名称") private java.lang.String name; /** * 职级 */ //@Excel(name = "职级", width = 15,dicCode ="position_rank") - @Schema(description = "职级") - @Dict(dicCode = "position_rank") - private java.lang.String postRank; + @Schema(description = "职务等级") + private java.lang.Integer postLevel; /** * 公司id */ diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysTenantPack.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysTenantPack.java index fa13ff99d..d79a71fa6 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysTenantPack.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysTenantPack.java @@ -67,6 +67,13 @@ public class SysTenantPack implements Serializable { @Excel(name = "产品包类型", width = 15) @Schema(description = "产品包类型") private String packType; + + /** + * 是否自动分配给用户(0 否 1是) + */ + @Excel(name = "是否自动分配给用户(0 否 1是)", width = 15) + @Schema(description = "是否自动分配给用户") + private String izSysn; /**菜单id 临时字段用于新增编辑菜单id传递*/ @TableField(exist = false) diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysUser.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysUser.java index 52d03d9d6..a7816d6f1 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysUser.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysUser.java @@ -211,4 +211,36 @@ public class SysUser implements Serializable { */ @TableField(exist = false) private boolean izBindThird; + + /** + * 个性签名 + */ + private String sign; + + /** + * 是否开启个性签名 + */ + private Integer signEnable; + + /** + * 主岗位 + */ + @Excel(name="主岗位",width = 15,dictTable ="sys_depart",dicText = "depart_name",dicCode = "id") + @Dict(dictTable ="sys_depart",dicText = "depart_name",dicCode = "id") + private String mainDepPostId; + + /** + * 兼职岗位 + */ + @Excel(name="兼职岗位",width = 15,dictTable ="sys_depart",dicText = "depart_name",dicCode = "id") + @Dict(dictTable ="sys_depart",dicText = "depart_name",dicCode = "id") + @TableField(exist = false) + private String otherDepPostId; + + /** + * 职务(字典) + */ + @Excel(name = "职务", width = 15, dicCode = "position_type") + @Dict(dicCode = "position_type") + private String positionType; } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysUserAgent.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysUserAgent.java deleted file mode 100644 index f443f5d20..000000000 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysUserAgent.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.jeecg.modules.system.entity; - -import java.io.Serializable; -import java.util.Date; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import com.fasterxml.jackson.annotation.JsonFormat; -import org.springframework.format.annotation.DateTimeFormat; -import org.jeecgframework.poi.excel.annotation.Excel; - -/** - * @Description: 用户代理人设置 - * @Author: jeecg-boot - * @Date: 2019-04-17 - * @Version: V1.0 - */ -@Data -@TableName("sys_user_agent") -public class SysUserAgent implements Serializable { - private static final long serialVersionUID = 1L; - - /**序号*/ - @TableId(type = IdType.ASSIGN_ID) - private java.lang.String id; - /**用户名*/ - @Excel(name = "用户名", width = 15) - private java.lang.String userName; - /**代理人用户名*/ - @Excel(name = "代理人用户名", width = 15) - private java.lang.String agentUserName; - /**代理开始时间*/ - @Excel(name = "代理开始时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") - @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") - @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") - private java.util.Date startTime; - /**代理结束时间*/ - @Excel(name = "代理结束时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") - @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") - @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") - private java.util.Date endTime; - /**状态0无效1有效*/ - @Excel(name = "状态0无效1有效", width = 15) - private java.lang.String status; - /**创建人名称*/ - @Excel(name = "创建人名称", width = 15) - private java.lang.String createName; - /**创建人登录名称*/ - @Excel(name = "创建人登录名称", width = 15) - private java.lang.String createBy; - /**创建日期*/ - @Excel(name = "创建日期", width = 20, format = "yyyy-MM-dd HH:mm:ss") - @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") - @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") - private java.util.Date createTime; - /**更新人名称*/ - @Excel(name = "更新人名称", width = 15) - private java.lang.String updateName; - /**更新人登录名称*/ - @Excel(name = "更新人登录名称", width = 15) - private java.lang.String updateBy; - /**更新日期*/ - @Excel(name = "更新日期", width = 20, format = "yyyy-MM-dd HH:mm:ss") - @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") - @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") - private java.util.Date updateTime; - /**所属部门*/ - @Excel(name = "所属部门", width = 15) - private java.lang.String sysOrgCode; - /**所属公司*/ - @Excel(name = "所属公司", width = 15) - private java.lang.String sysCompanyCode; -} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysUserDepPost.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysUserDepPost.java new file mode 100644 index 000000000..796464c8a --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysUserDepPost.java @@ -0,0 +1,85 @@ +package org.jeecg.modules.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * @Description: 部门岗位用户 + * @author: wangshuai + * @date: 2025/9/5 11:45 + */ +@Data +@TableName("sys_user_dep_post") +public class SysUserDepPost implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(type = IdType.ASSIGN_ID) + @Schema(description = "主键id") + private String id; + /** + * 用户id + */ + @Schema(description = "用户id") + private String userId; + /** + * 部门岗位id + */ + @Schema(description = "部门岗位id") + private String depId; + + /** + * 创建人 + */ + @Schema(description = "创建人") + private String createBy; + + /** + * 创建时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Schema(description = "创建时间") + private Date createTime; + /** + * 更新人 + */ + @Schema(description = "更新人") + private String updateBy; + /** + * 更新时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Schema(description = "更新时间") + private Date updateTime; + /** + * 机构编码 + */ + @Excel(name = "机构编码", width = 15) + @Schema(description = "机构编码") + private String orgCode; + + public SysUserDepPost(String id, String userId, String depId) { + super(); + this.id = id; + this.userId = userId; + this.depId = depId; + } + + public SysUserDepPost(String userId, String departId) { + this.userId = userId; + this.depId = departId; + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/excelstyle/ExcelExportSysUserStyle.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/excelstyle/ExcelExportSysUserStyle.java new file mode 100644 index 000000000..9799e1375 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/excelstyle/ExcelExportSysUserStyle.java @@ -0,0 +1,34 @@ +package org.jeecg.modules.system.excelstyle; + +import org.apache.poi.ss.usermodel.*; +import org.jeecgframework.poi.excel.export.styler.ExcelExportStylerDefaultImpl; + +/** + * @Description: 导入用户获取标题头部样式 覆盖默认样式 + * + * @author: wangshuai + * @date: 2025/8/28 14:05 + */ +public class ExcelExportSysUserStyle extends ExcelExportStylerDefaultImpl { + + public ExcelExportSysUserStyle(Workbook workbook) { + super(workbook); + } + + /** + * 获取标题样式 + * + * @param color + * @return + */ + public CellStyle getHeaderStyle(short color) { + CellStyle titleStyle = this.workbook.createCellStyle(); + Font font = this.workbook.createFont(); + font.setFontHeightInPoints((short)12); + titleStyle.setFont(font); + titleStyle.setAlignment(HorizontalAlignment.LEFT); + titleStyle.setVerticalAlignment(VerticalAlignment.CENTER); + titleStyle.setWrapText(true); + return titleStyle; + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysDepartMapper.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysDepartMapper.java index b12915863..1e41aff7c 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysDepartMapper.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysDepartMapper.java @@ -7,9 +7,8 @@ import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import org.jeecg.modules.system.entity.SysDepart; import org.jeecg.modules.system.entity.SysUser; -import org.jeecg.modules.system.model.SysDepartTreeModel; -import org.jeecg.modules.system.model.TreeModel; import org.jeecg.modules.system.vo.SysDepartExportVo; +import org.jeecg.modules.system.vo.SysDepartPositionVo; import org.jeecg.modules.system.vo.SysUserDepVo; import org.jeecg.modules.system.vo.lowapp.ExportDepartVo; import org.springframework.data.repository.query.Param; @@ -195,4 +194,61 @@ public interface SysDepartMapper extends BaseMapper { */ @InterceptorIgnore(tenantLine = "true") List getUserDepartByUserId(@Param("userList")List userList); + + /** + * 根据父级id/职级/部门id获取部门岗位信息 + * + * @param parentId + * @param postLevel + * @param departId + */ + List getDepartPositionByParentId(@Param("parentId") String parentId, @Param("postLevel") Integer postLevel, @Param("departId") String departId); + + /** + * 根据父级id获取部门中的数据 + * @param parentId + * @return + */ + @Select("select id, depart_name, parent_id, iz_leaf, org_category, org_code from sys_depart where parent_id = #{parentId} order by depart_order,create_time desc") + List getDepartByParentId(@Param("parentId") String parentId); + + /** + * 根据部门id查询部门信息 + + * @param departId + * @return 部门岗位信息 + */ + SysDepartPositionVo getDepartPostByDepartId(@Param("departId") String departId); + + /** + * 根据父级部门id查询部门信息 + + * @param orgCode + * @return 部门岗位信息 + */ + List getDepartPostByOrgCode(@Param("orgCode") String orgCode); + + /** + * 根据部门id获取部门code + * @param idList + * @return + */ + List getDepCodeByDepIds(@Param("idList") List idList); + + /** + * 根据父级部门id和职务名称查找部门id + * + * @param parentId + * @param postName + * @return + */ + String getDepIdByDepIdAndPostName(@Param("parentId") String parentId, @Param("postName") String postName); + + /** + * 根据部门id 获取职级名称 + * + * @param depId + * @return + */ + String getPostNameByPostId(@Param("depId") String depId); } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserAgentMapper.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserAgentMapper.java deleted file mode 100644 index 346933b95..000000000 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserAgentMapper.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.jeecg.modules.system.mapper; - -import java.util.List; - -import org.apache.ibatis.annotations.Param; -import org.jeecg.modules.system.entity.SysUserAgent; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; - -/** - * @Description: 用户代理人设置 - * @Author: jeecg-boot - * @Date: 2019-04-17 - * @Version: V1.0 - */ -public interface SysUserAgentMapper extends BaseMapper { - -} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserDepPostMapper.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserDepPostMapper.java new file mode 100644 index 000000000..43b0282b1 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserDepPostMapper.java @@ -0,0 +1,25 @@ +package org.jeecg.modules.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.jeecg.modules.system.entity.SysUserDepPost; + +import java.util.List; + +/** + * @Description: 部门岗位用户关联表 Mapper + * @author: wangshuai + * @date: 2025/9/5 12:01 + */ +public interface SysUserDepPostMapper extends BaseMapper { + + /** + * 通过用户id查询部门岗位用户 + * + * @param userId + * @return + */ + @Select("select dep_id from sys_user_dep_post where user_id = #{userId}") + List getDepPostByUserId(@Param("userId") String userId); +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserMapper.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserMapper.java index 568e1f88c..2ac027187 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserMapper.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserMapper.java @@ -8,6 +8,7 @@ import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.jeecg.modules.system.entity.SysUser; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.jeecg.modules.system.model.SysUserSysDepPostModel; import org.jeecg.modules.system.model.SysUserSysDepartModel; import org.jeecg.modules.system.vo.SysUserDepVo; @@ -74,9 +75,10 @@ public interface SysUserMapper extends BaseMapper { * @param page * @param roleId 角色id * @param username 用户登录账户 + * @param realname 用户姓名 * @return */ - IPage getUserByRoleId(Page page, @Param("roleId") String roleId, @Param("username") String username); + IPage getUserByRoleId(Page page, @Param("roleId") String roleId, @Param("username") String username, @Param("realname") String realname); /** * 根据用户名设置部门ID @@ -222,4 +224,34 @@ public interface SysUserMapper extends BaseMapper { */ @Select("select id,phone from sys_user where phone = #{phone} and username = #{username}") SysUser getUserByNameAndPhone(@Param("phone") String phone, @Param("username") String username); + + /** + * 查询部门、岗位下的用户 包括子部门下的用户 + * + * @param page + * @param orgCode + * @param userParams + * @return + */ + List queryDepartPostUserByOrgCode(@Param("page") IPage page, @Param("orgCode") String orgCode, @Param("userParams") SysUser userParams); + + /** + * 根据部门id和用户名获取部门岗位用户分页列表 + * + * @param page + * @param userIdList + * @return + */ + IPage getDepPostListByIdUserName(@Param("page") Page page, @Param("userIdList") List userIdList, @Param("userId") String userId, @Param("userName") String userName, @Param("userNameList") List userNameList); + + /** + * 根据部门id、用户名和真实姓名获取部门岗位用户分页列表 + * + * @param page + * @param username + * @param realname + * @param orgCode + * @return + */ + IPage getDepartPostListByIdUserRealName(@Param("page") Page page, @Param("username") String username, @Param("realname") String realname, @Param("orgCode") String orgCode); } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysDepartMapper.xml b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysDepartMapper.xml index 853e5441c..39a00b0f9 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysDepartMapper.xml +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysDepartMapper.xml @@ -170,7 +170,7 @@ - SELECT sd.depart_name, sud.user_id, sd.id as deptId, sd.parent_id + SELECT sd.depart_name, sud.user_id, sd.id as deptId, sd.parent_id, sd.org_category FROM sys_depart sd RIGHT JOIN sys_user_depart sud on sd.id = sud.dep_id and sd.del_flag = 0 WHERE sud.user_id IN @@ -218,4 +218,54 @@ order by sd.org_code; + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserAgentMapper.xml b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserAgentMapper.xml deleted file mode 100644 index 8bc1b75b7..000000000 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserAgentMapper.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserMapper.xml b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserMapper.xml index 2472f7518..0f331da4c 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserMapper.xml +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserMapper.xml @@ -57,6 +57,9 @@ and username = #{username} + + and realname LIKE concat(concat('%',#{realname}),'%') + @@ -298,4 +301,125 @@ and sut.tenant_id=#{tenantId} and sut.status = '1' + + + + + WHERE + su.status = 1 + and su.del_flag = 0 + and username '_reserve_user_external' + + and su.id = #{userId} + + + + and su.username like #{bindUserName} + + + + #{idItem} + + + + + #{usernameItem} + + + + + + + + + + WHERE + su.status = 1 + and su.del_flag = 0 + and username '_reserve_user_external' + + + and su.id like #{bindRealname} + + + + and su.username like #{bindUserName} + + + + and sd.org_code like #{bindOrgCode} + + + + + + + + + WHERE + + + + + + + su.del_flag = 0 AND sd.org_code LIKE #{bindOrgCode} + + + + AND su.realname LIKE bindRealname + + + + AND su.work_no LIKE bindWorkNo + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/model/DepartIdModel.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/model/DepartIdModel.java index af1570069..5a5c7036e 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/model/DepartIdModel.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/model/DepartIdModel.java @@ -28,6 +28,10 @@ public class DepartIdModel implements Serializable { * 主键ID */ private String value; + /** + * 部门编码 + */ + private String code; /** * 部门名称 @@ -56,6 +60,7 @@ public class DepartIdModel implements Serializable { public DepartIdModel convertByUserDepart(SysDepart sysDepart) { this.key = sysDepart.getId(); this.value = sysDepart.getId(); + this.code = sysDepart.getOrgCode(); this.title = sysDepart.getDepartName(); return this; } @@ -95,4 +100,12 @@ public class DepartIdModel implements Serializable { public void setTitle(String title) { this.title = title; } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/model/SysDepartTreeModel.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/model/SysDepartTreeModel.java index b50832e3e..1fabfe14a 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/model/SysDepartTreeModel.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/model/SysDepartTreeModel.java @@ -80,6 +80,12 @@ public class SysDepartTreeModel implements Serializable{ private String directorUserIds; //update-end---author:wangshuai ---date:20200308 for:[JTC-119]在部门管理菜单下设置部门负责人,新增字段部门负责人ids + /**职务*/ + private String positionId; + + /**上级岗位id*/ + private String depPostParentId; + private List children = new ArrayList<>(); @@ -113,6 +119,8 @@ public class SysDepartTreeModel implements Serializable{ this.updateBy = sysDepart.getUpdateBy(); this.updateTime = sysDepart.getUpdateTime(); this.directorUserIds = sysDepart.getDirectorUserIds(); + this.positionId = sysDepart.getPositionId(); + this.depPostParentId = sysDepart.getDepPostParentId(); if(0 == sysDepart.getIzLeaf()){ this.isLeaf = false; }else{ @@ -351,6 +359,22 @@ public class SysDepartTreeModel implements Serializable{ this.directorUserIds = directorUserIds; } + public String getPositionId() { + return positionId; + } + + public void setPositionId(String positionId) { + this.positionId = positionId; + } + + public String getDepPostParentId() { + return depPostParentId; + } + + public void setDepPostParentId(String depPostParentId) { + this.depPostParentId = depPostParentId; + } + /** * 重写equals方法 */ @@ -385,6 +409,8 @@ public class SysDepartTreeModel implements Serializable{ Objects.equals(updateBy, model.updateBy) && Objects.equals(updateTime, model.updateTime) && Objects.equals(directorUserIds, model.directorUserIds) && + Objects.equals(positionId, model.positionId) && + Objects.equals(depPostParentId, model.depPostParentId) && Objects.equals(children, model.children); } @@ -397,7 +423,7 @@ public class SysDepartTreeModel implements Serializable{ return Objects.hash(id, parentId, departName, departNameEn, departNameAbbr, departOrder, description, orgCategory, orgType, orgCode, mobile, fax, address, memo, status, delFlag, qywxIdentifier, createBy, createTime, updateBy, updateTime, - children,directorUserIds); + children,directorUserIds, positionId, depPostParentId); } } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/model/SysUserSysDepPostModel.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/model/SysUserSysDepPostModel.java new file mode 100644 index 000000000..f4e3f219a --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/model/SysUserSysDepPostModel.java @@ -0,0 +1,139 @@ +package org.jeecg.modules.system.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.jeecg.common.aspect.annotation.Dict; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +/** + * @Description: 部门用户和部门岗位用户的Model + * @author: wangshuai + * @date: 2025/9/5 16:43 + */ +@Data +public class SysUserSysDepPostModel { + /** + * 用户ID + */ + private String id; + /* 真实姓名 */ + private String realname; + + /** + * 头像 + */ + @Excel(name = "头像", width = 15, type = 2) + private String avatar; + /** + * 生日 + */ + @Excel(name = "生日", width = 15, format = "yyyy-MM-dd") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date birthday; + + /** + * 性别(1:男 2:女) + */ + @Excel(name = "性别", width = 15, dicCode = "sex") + @Dict(dicCode = "sex") + private Integer sex; + + /** + * 电子邮件 + */ + @Excel(name = "电子邮件", width = 15) + private String email; + + /** + * 电话 + */ + @Excel(name = "电话", width = 15) + private String phone; + + /** + * 状态(1:正常 2:冻结 ) + */ + @Excel(name = "状态", width = 15, dicCode = "user_status") + @Dict(dicCode = "user_status") + private Integer status; + + /** + * 删除状态(0,正常,1已删除) + */ + @Excel(name = "删除状态", width = 15, dicCode = "del_flag") + @TableLogic + private Integer delFlag; + + /** + * 座机号 + */ + @Excel(name = "座机号", width = 15) + private String telephone; + + /** + * 身份(0 普通成员 1 上级) + */ + @Excel(name = "(1普通成员 2上级)", width = 15) + private Integer userIdentity; + + /** + * 负责部门 + */ + @Excel(name = "负责部门", width = 15, dictTable = "sys_depart", dicText = "depart_name", dicCode = "id") + @Dict(dictTable = "sys_depart", dicText = "depart_name", dicCode = "id") + private String departIds; + + /** + * 多租户ids临时用,不持久化数据库(数据库字段不存在) + */ + private String relTenantIds; + + /** + * 同步工作流引擎(1-同步 0-不同步) + */ + private String activitiSync; + /** + * 主岗位 + */ + @Excel(name = "主岗位", width = 15, dictTable = "sys_depart", dicText = "depart_name", dicCode = "id") + @Dict(dictTable = "sys_depart", dicText = "depart_name", dicCode = "id") + private String mainDepPostId; + + /** + * 兼职岗位 + */ + @Excel(name = "兼职岗位", width = 15, dictTable = "sys_depart", dicText = "depart_name", dicCode = "id") + @Dict(dictTable = "sys_depart", dicText = "depart_name", dicCode = "id") + @TableField(exist = false) + private String otherDepPostId; + + /** + * 部门名称 + */ + private String departName; + /** + * 主岗位 + */ + private String postName; + + /** + * 兼职岗位 + */ + private String otherPostName; + + /** + * 部门text + */ + private String orgCodeTxt; + + /** + * 职务 + */ + private String post; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysAnnouncementService.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysAnnouncementService.java index 7aed2aa05..c1f67b4d1 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysAnnouncementService.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysAnnouncementService.java @@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import org.jeecg.modules.system.entity.SysAnnouncement; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.util.Date; import java.util.List; @@ -98,4 +100,12 @@ public interface ISysAnnouncementService extends IService { * @param count */ void updateVisitsNum(String id, int count); + + /** + * 批量下载文件 + * @param id + * @param request + * @param response + */ + void downLoadFiles(String id, HttpServletRequest request, HttpServletResponse response); } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysDepartService.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysDepartService.java index 5944f9534..2ff279602 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysDepartService.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysDepartService.java @@ -5,13 +5,12 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import org.jeecg.modules.system.entity.SysDepart; -import org.jeecg.modules.system.entity.SysUserDepart; import org.jeecg.modules.system.model.DepartIdModel; import org.jeecg.modules.system.model.SysDepartTreeModel; import org.jeecg.modules.system.vo.SysDepartExportVo; +import org.jeecg.modules.system.vo.SysPositionSelectTreeVo; import org.jeecg.modules.system.vo.lowapp.ExportDepartVo; -import javax.servlet.http.HttpServletRequest; import java.util.List; /** @@ -75,12 +74,15 @@ public interface ISysDepartService extends IService{ /** * 根据关键字搜索相关的部门数据 + * * @param keyWord * @param myDeptSearch - * @param departIds 多个部门id + * @param departIds 多个部门id + * @param orgCategory + * @param depIds * @return */ - List searchByKeyWord(String keyWord,String myDeptSearch,String departIds); + List searchByKeyWord(String keyWord, String myDeptSearch, String departIds, String orgCategory, String depIds); /** * 根据部门id删除并删除其可能存在的子级部门 @@ -240,4 +242,40 @@ public interface ISysDepartService extends IService{ * @param errorMessageList */ void importSysDepart(List listSysDeparts, List errorMessageList); + + /** + * 根据部门id和职级id获取岗位信息 + * + * @param parentId + * @param departId + * @param positionId + */ + List getPositionByDepartId(String parentId, String departId, String positionId); + + /** + * 获取职级关系 + * @param departId + * @return + */ + List getRankRelation(String departId); + + /** + * 异步查询部门和岗位接口 + * + * @param parentId + * @param ids + * @param primaryKey + * @param departIds + * @return + */ + List queryDepartAndPostTreeSync(String parentId, String ids, String primaryKey, String departIds,String orgName); + + /** + * 根据部门code获取当前和上级部门名称 + * + * @param orgCode + * @param depId + * @return + */ + String getDepartPathNameByOrgCode(String orgCode, String depId); } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserAgentService.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserAgentService.java deleted file mode 100644 index 10e2e829e..000000000 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserAgentService.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.jeecg.modules.system.service; - -import org.jeecg.modules.system.entity.SysUserAgent; -import com.baomidou.mybatisplus.extension.service.IService; - -/** - * @Description: 用户代理人设置 - * @Author: jeecg-boot - * @Date: 2019-04-17 - * @Version: V1.0 - */ -public interface ISysUserAgentService extends IService { - -} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserDepPostService.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserDepPostService.java new file mode 100644 index 000000000..96184fd07 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserDepPostService.java @@ -0,0 +1,13 @@ +package org.jeecg.modules.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.modules.system.entity.SysUserDepPost; + +/** + * @Description: 部门岗位用户表 + * @author: wangshuai + * @date: 2025/9/5 11:45 + */ +public interface ISysUserDepPostService extends IService { + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserDepartService.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserDepartService.java index 197cd4844..7358b16a0 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserDepartService.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserDepartService.java @@ -86,4 +86,18 @@ public interface ISysUserDepartService extends IService { * @return */ List getUsersByDepartTenantId(String departId,Integer tenantId); + + /** + * 查询部门岗位下的用户 + * + * @param departId + * @param username + * @param realname + * @param pageSize + * @param pageNo + * @param id + * @param isMultiTranslate + * @return + */ + IPage queryDepartPostUserPageList(String departId, String username, String realname, Integer pageSize, Integer pageNo, String id, String isMultiTranslate); } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserService.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserService.java index 37f8453f8..6af469f54 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserService.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserService.java @@ -11,6 +11,7 @@ import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.system.vo.SysUserCacheInfo; import org.jeecg.modules.system.entity.SysRoleIndex; import org.jeecg.modules.system.entity.SysUser; +import org.jeecg.modules.system.model.SysUserSysDepPostModel; import org.jeecg.modules.system.model.SysUserSysDepartModel; import org.jeecg.modules.system.vo.SysUserExportVo; import org.jeecg.modules.system.vo.lowapp.DepartAndUserInfo; @@ -19,7 +20,6 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; -import java.io.IOException; import java.util.Collection; import java.util.List; import java.util.Map; @@ -176,10 +176,11 @@ public interface ISysUserService extends IService { * 根据角色Id查询 * @param page * @param roleId 角色id - * @param username 用户账户名称 + * @param username 用户账户 + * @param realname 用户姓名 * @return */ - public IPage getUserByRoleId(Page page,String roleId, String username); + public IPage getUserByRoleId(Page page,String roleId, String username, String realname); /** * 通过用户名获取用户角色集合 @@ -299,13 +300,15 @@ public interface ISysUserService extends IService { List queryByDepIds(List departIds, String username); /** - * 保存用户 - * @param user 用户 - * @param selectedRoles 选择的角色id,多个以逗号隔开 - * @param selectedDeparts 选择的部门id,多个以逗号隔开 - * @param relTenantIds 多个租户id - */ - void saveUser(SysUser user, String selectedRoles, String selectedDeparts, String relTenantIds); + * 保存用户 + * + * @param user 用户 + * @param selectedRoles 选择的角色id,多个以逗号隔开 + * @param selectedDeparts 选择的部门id,多个以逗号隔开 + * @param relTenantIds 多个租户id + * @param izSyncPack 是否需要同步租户套餐包 + */ + void saveUser(SysUser user, String selectedRoles, String selectedDeparts, String relTenantIds, boolean izSyncPack); /** * 编辑用户 @@ -482,4 +485,22 @@ public interface ISysUserService extends IService { * @param username */ void updatePasswordNotBindPhone(String oldPassword, String password, String username); + + /** + * 根据用户名称查询用户和部门信息 + * @param userName + * @return + */ + Map queryUserAndDeptByName(String userName); + + /** + * 查询部门、岗位下的用户 包括子部门下的用户 + * + * @param orgCode + * @param userParams + * @param page + * @return + */ + IPage queryDepartPostUserByOrgCode(String orgCode, SysUser userParams, IPage page); + } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java index 444561986..7802c6b06 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java @@ -17,11 +17,10 @@ import org.jeecg.common.config.TenantContext; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.FillRuleConstant; import org.jeecg.common.constant.SymbolConstant; +import org.jeecg.common.constant.enums.DepartCategoryEnum; +import org.jeecg.common.exception.JeecgBootBizTipException; import org.jeecg.common.system.vo.LoginUser; -import org.jeecg.common.util.FillRuleUtil; -import org.jeecg.common.util.ImportExcelUtil; -import org.jeecg.common.util.YouBianCodeUtil; -import org.jeecg.common.util.oConvertUtils; +import org.jeecg.common.util.*; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; import org.jeecg.modules.system.entity.*; import org.jeecg.modules.system.mapper.*; @@ -30,10 +29,13 @@ import org.jeecg.modules.system.model.SysDepartTreeModel; import org.jeecg.modules.system.service.ISysDepartService; import org.jeecg.modules.system.util.FindsDepartsChildrenUtil; import org.jeecg.modules.system.vo.SysDepartExportVo; +import org.jeecg.modules.system.vo.SysDepartPositionVo; +import org.jeecg.modules.system.vo.SysPositionSelectTreeVo; import org.jeecg.modules.system.vo.lowapp.ExportDepartVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; import java.util.*; import java.util.function.Consumer; @@ -64,7 +66,11 @@ public class SysDepartServiceImpl extends ServiceImpl queryMyDeptTreeList(String departIds) { //根据部门id获取所负责部门 @@ -79,7 +85,7 @@ public class SysDepartServiceImpl extends ServiceImpl list = this.list(query); //update-begin---author:wangshuai ---date:20220307 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理 @@ -135,6 +144,9 @@ public class SysDepartServiceImpl extends ServiceImpl listResult=new ArrayList<>(); LambdaQueryWrapper query = new LambdaQueryWrapper(); query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString()); + //update-begin---author:wangshuai---date:2025-08-18---for:【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门--- + query.ne(SysDepart::getOrgCategory,DepartCategoryEnum.DEPART_CATEGORY_POST.getValue()); + //update-end---author:wangshuai---date:2025-08-18---for:【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门--- if(oConvertUtils.isNotEmpty(ids)){ query.in(true,SysDepart::getId,ids.split(",")); } @@ -310,6 +322,8 @@ public class SysDepartServiceImpl extends ServiceImpl().lambda().eq(SysDepart::getParentId, sysDepart.getId())); + if (count > 0) { + throw new JeecgBootBizTipException("当前子公司/部门下存在子级,无法变更为岗位!"); + } + } + //如果是子公司的情况下,则上级不能为部门或者岗位 + if (oConvertUtils.isNotEmpty(sysDepart.getOrgCategory()) && DepartCategoryEnum.DEPART_CATEGORY_SUB_COMPANY.getValue().equals(sysDepart.getOrgCategory()) + && oConvertUtils.isNotEmpty(sysDepart.getParentId())) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysDepart::getId, sysDepart.getParentId()); + queryWrapper.in(SysDepart::getOrgCategory, DepartCategoryEnum.DEPART_CATEGORY_POST.getValue(), DepartCategoryEnum.DEPART_CATEGORY_DEPART.getValue()); + long count = this.count(queryWrapper); + if (count > 0) { + throw new JeecgBootBizTipException("当前父级为部门或岗位,无法变更为子公司!"); + } + } + //如果是部门的情况下,下级不能为子公司或者公司 + if (oConvertUtils.isNotEmpty(sysDepart.getOrgCategory()) && DepartCategoryEnum.DEPART_CATEGORY_DEPART.getValue().equals(sysDepart.getOrgCategory())) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysDepart::getParentId, sysDepart.getId()); + queryWrapper.in(SysDepart::getOrgCategory, DepartCategoryEnum.DEPART_CATEGORY_COMPANY.getValue(), DepartCategoryEnum.DEPART_CATEGORY_SUB_COMPANY.getValue()); + long count = this.count(queryWrapper); + if (count > 0) { + throw new JeecgBootBizTipException("当前子级存在子公司,无法变更为部门!"); + } + } + //update-end---author:wangshuai---date:2025-08-21---for: 当部门类型为岗位的时候,需要查看是否存在下级,存在下级无法变更为岗位--- + } + + @Override @Transactional(rollbackFor = Exception.class) public void deleteBatchWithChildren(List ids) { //存放子级的id @@ -390,7 +442,7 @@ public class SysDepartServiceImpl extends ServiceImpl */ @Override - public List searchByKeyWord(String keyWord,String myDeptSearch,String departIds) { + public List searchByKeyWord(String keyWord, String myDeptSearch, String departIds, String orgCategory, String depIds) { LambdaQueryWrapper query = new LambdaQueryWrapper(); List newList = new ArrayList<>(); //myDeptSearch不为空时为我的部门搜索,只搜索所负责部门 @@ -413,7 +465,26 @@ public class SysDepartServiceImpl extends ServiceImpl codeList = baseMapper.getDepCodeByDepIds(Arrays.asList(depIds.split(SymbolConstant.COMMA))); + if(CollectionUtil.isNotEmpty(codeList)){ + query.and(i -> { + for (String code : codeList) { + i.or().likeRight(SysDepart::getOrgCode,code); + } + }); + } + } + //update-end---author:wangshuai---date:2025-08-20---for:【QQYUN-13428】增加岗位选择组件--- + //update-begin--Author:huangzhilin Date:20140417 for:[bugfree号]组织机构搜索回显优化-------------------- SysDepartTreeModel model = new SysDepartTreeModel(); List departList = this.list(query); if(departList.size() > 0) { @@ -622,6 +693,9 @@ public class SysDepartServiceImpl extends ServiceImpl records = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { SysDepart depart = list.get(i); + //update-begin---author:wangshuai---date:2025-08-18---for:【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门--- + long count = getNoDepartPostCount(depart.getId()); + if(count == 0){ + depart.setIzLeaf(CommonConstant.IS_LEAF); + } + //update-end---author:wangshuai---date:2025-08-18---for:【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门--- SysDepartTreeModel treeModel = new SysDepartTreeModel(depart); //TODO 异步树加载key拼接__+时间戳,以便于每次展开节点会刷新数据 //treeModel.setKey(treeModel.getKey()+"__"+System.currentTimeMillis()); @@ -642,6 +722,85 @@ public class SysDepartServiceImpl extends ServiceImpl queryNoPosition = new LambdaQueryWrapper<>(); + queryNoPosition.ne(SysDepart::getOrgCategory,DepartCategoryEnum.DEPART_CATEGORY_POST.getValue()); + queryNoPosition.eq(SysDepart::getParentId,departId); + return this.count(queryNoPosition); + } + + /** + * 部门管理异步树 + * + * @param parentId + * @param ids + * @param primaryKey + * @param departIds + * @return + */ + @Override + public List queryDepartAndPostTreeSync(String parentId, String ids, String primaryKey, + String departIds, String orgName) { + Consumer> square = i -> { + if (oConvertUtils.isNotEmpty(ids)) { + if (CommonConstant.DEPART_KEY_ORG_CODE.equals(primaryKey)) { + i.in(SysDepart::getOrgCode, ids.split(SymbolConstant.COMMA)); + } else { + i.in(SysDepart::getId, ids.split(SymbolConstant.COMMA)); + } + } else { + if(oConvertUtils.isEmpty(parentId)){ + //update-begin---author:wangshuai---date:2025-08-20---for:如果前端传过来的部门id不为空的时候,说明是系统用户根据所属部门选择主岗位或者兼职岗位--- + if(oConvertUtils.isNotEmpty(departIds)){ + i.in(SysDepart::getId,Arrays.asList(departIds.split(SymbolConstant.COMMA))); + }else{ + if(oConvertUtils.isEmpty(orgName)){ + i.and(q->q.isNull(true,SysDepart::getParentId).or().eq(true,SysDepart::getParentId,"")); + }else{ + i.like(SysDepart::getDepartName, orgName); + } + } + //update-end---author:wangshuai---date:2025-08-20---for:如果前端传过来的部门id不为空的时候,说明是系统用户根据所属部门选择主岗位或者兼职岗位--- + }else{ + i.eq(true,SysDepart::getParentId,parentId); + } + } + }; + LambdaQueryWrapper lqw=new LambdaQueryWrapper<>(); + //是否开启系统管理模块的 SASS 控制 + if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){ + lqw.eq(SysDepart::getTenantId, oConvertUtils.getInt(TenantContext.getTenant(), 0)); + } + lqw.eq(true,SysDepart::getDelFlag,CommonConstant.DEL_FLAG_0.toString()); + lqw.func(square); + lqw.orderByAsc(SysDepart::getDepartOrder); + List list = list(lqw); + //设置用户id,让前台显示 + this.setUserIdsByDepList(list); + List departIdList = new ArrayList<>(); + //如果前端传过来的部门id不为空的时候,说明是系统用户根据所属部门选择主岗位或者兼职岗位 + if(oConvertUtils.isNotEmpty(departIds) && oConvertUtils.isEmpty(parentId)){ + departIdList = list.stream().map(SysDepart::getId).toList(); + } + List records = new ArrayList<>(); + for (int i = 0; i < list.size(); i++) { + SysDepart depart = list.get(i); + //如果部门id和父级部门id再同一列的时候,不用添加到树结构里面去了 + if(oConvertUtils.isNotEmpty(departIds) && oConvertUtils.isEmpty(parentId) + && departIdList.contains(depart.getParentId())){ + continue; + } + SysDepartTreeModel treeModel = new SysDepartTreeModel(depart); + records.add(treeModel); + } + return records; + } + @Override public JSONObject queryAllParentIdByDepartId(String departId) { JSONObject result = new JSONObject(); @@ -1339,6 +1498,7 @@ public class SysDepartServiceImpl extends ServiceImpl getPositionByDepartId(String parentId, String departId, String positionId) { + //step1 根据职级获取当前岗位的级别 + SysPosition sysPosition = sysPositionMapper.selectById(positionId); + if(null == sysPosition){ + return null; + } + Integer postLevel = sysPosition.getPostLevel(); + //先获取上级部门的信息 + SysDepart sysDepart = baseMapper.getDepartById(parentId); + //step2 如果是总公司 即数据为空的时候,则说明没有上级领导了 + if (null == sysDepart) { + return null; + } + + //可能是老数据 + if(null == postLevel){ + throw new JeecgBootBizTipException("当前选择职级的职务等级为空,请前往职务管理进行修改!"); + } + + //step3 查看是否为董事长 + if (1 == postLevel) { + //step4 如果是董事长查询上级子公司或者总公司下部门的所有的岗位 + return this.getChairmanDepartPosition(sysDepart, departId); + } else { + //step5 如果不是董事长组查询当前父级部门、公司和子公司的岗位 和当前部门下的岗位,但是必须比当前职务的级别高 + return this.getNotChairmanDepartPosition(sysDepart, postLevel, departId); + } + } + + /** + * 获取董事长职位 + * + * @param sysDepart + * @param id + * @return + */ + private List getChairmanDepartPosition(SysDepart sysDepart, String id) { + //step1 先递归获取为子公司或者总共司的id + String departId = getCompanyDepartId(sysDepart.getParentId()); + if (oConvertUtils.isNotEmpty(departId)) { + SysDepart depart = baseMapper.getDepartById(departId); + //如果当前上级部门就是子公司或者总公司的情况下 + if (DepartCategoryEnum.DEPART_CATEGORY_COMPANY.getValue().equals(sysDepart.getOrgCategory()) || DepartCategoryEnum.DEPART_CATEGORY_SUB_COMPANY.getValue().equals(sysDepart.getOrgCategory())) { + depart.setParentId(departId); + List departPosition = getDepartPosition(depart, null, id); + if (CollectionUtil.isNotEmpty(departPosition)) { + if (CollectionUtil.isNotEmpty(departPosition)) { + //父级id不为空并且当前部门不是子公司或者总公司,则需要寻上顶级公司 + return getSuperiorCompany(departPosition); + } + } + return departPosition; + } else { + //step2 获取上一个子公司或者总公司下的岗位 + String parentId = getCompanyDepartId(depart.getParentId()); + if (oConvertUtils.isNotEmpty(departId)) { + depart = baseMapper.getDepartById(parentId); + if (null != depart) { + depart.setParentId(parentId); + List departPosition = getDepartPosition(depart, null, id); + //step3 获取上级部门信息,一直获取到子公司或者总公司为止 + if (CollectionUtil.isNotEmpty(departPosition)) { + //父级id不为空并且当前部门不是子公司或者总公司,则需要寻上顶级公司 + return getSuperiorCompany(departPosition); + } + return departPosition; + } + } + } + + } + return null; + } + + /* + * 获取不是董事长的数据 + * + * @param sysDepart + * @param postLevel + * @param id + * @return + */ + private List getNotChairmanDepartPosition(SysDepart sysDepart, Integer postLevel, String id) { + //step1 先获取上级部门下的数据 + List departPosition = getDepartPosition(sysDepart, postLevel, id); + //step2 获取上级部门信息,一直获取到子公司或者总公司为止 + if (CollectionUtil.isNotEmpty(departPosition)) { + if (CollectionUtil.isNotEmpty(departPosition)) { + //父级id不为空并且当前部门不是子公司或者总公司,则需要寻上顶级公司 + return getSuperiorCompany(departPosition); + } + return departPosition; + } + return departPosition; + } + + /** + * 获取上级公司 + * + * @param departPosition + */ + private List getSuperiorCompany(List departPosition) { + String parentId = departPosition.get(0).getParentId(); + SysDepart depart = baseMapper.getDepartById(parentId); + if (null == depart) { + return departPosition; + } + List childrenList = new ArrayList<>(); + SysPositionSelectTreeVo childrenTreeModel = new SysPositionSelectTreeVo(depart); + childrenTreeModel.setChildren(departPosition); + childrenList.add(childrenTreeModel); + if (DepartCategoryEnum.DEPART_CATEGORY_COMPANY.getValue().equals(depart.getOrgCategory()) || DepartCategoryEnum.DEPART_CATEGORY_SUB_COMPANY.getValue().equals(depart.getOrgCategory())) { + return childrenList; + } else { + return this.getSuperiorCompany(childrenList); + } + } + + /** + * 获取部门职务 + * + * @param sysDepart + * @param postLevel + */ + private List getDepartPosition(SysDepart sysDepart, Integer postLevel, String id) { + //step1 获取部门下的所有部门 + String parentId = sysDepart.getParentId(); + List departList = baseMapper.getDepartByParentId(parentId); + List treeModels = new ArrayList<>(); + for (int i = 0; i < departList.size(); i++) { + SysDepart depart = departList.get(i); + //如果是叶子节点说明没有岗位直接跳出循环 + if (depart.getIzLeaf() == 1) { + if (DepartCategoryEnum.DEPART_CATEGORY_POST.getValue().equals(depart.getOrgCategory())) { + SysPositionSelectTreeVo sysDepartTreeModel = new SysPositionSelectTreeVo(depart); + treeModels.add(sysDepartTreeModel); + } + continue; + } + //step2 查找子部门下大于当前职别的数据 + List departParentPosition = baseMapper.getDepartPositionByParentId(depart.getId(), postLevel, id); + if (CollectionUtil.isNotEmpty(departParentPosition)) { + List sysDepartTreeModels = sysDepartToTreeModel(departParentPosition); + SysPositionSelectTreeVo parentDepartTree = new SysPositionSelectTreeVo(depart); + parentDepartTree.setChildren(sysDepartTreeModels); + treeModels.add(parentDepartTree); + } + } + return treeModels; + } + + /** + * 将SysDepart中的属性转到SysDepartTreeModel中 + * + * @return + */ + private List sysDepartToTreeModel(List sysDeparts) { + List records = new ArrayList<>(); + for (int i = 0; i < sysDeparts.size(); i++) { + SysDepart depart = sysDeparts.get(i); + SysPositionSelectTreeVo treeModel = new SysPositionSelectTreeVo(depart); + records.add(treeModel); + } + return records; + } + + /** + * 获取公司或者子公司的id + * + * @param parentDepartId + * @return + */ + private String getCompanyDepartId(String parentDepartId) { + SysDepart sysDepart = baseMapper.getDepartById(parentDepartId); + if (sysDepart != null) { + if (DepartCategoryEnum.DEPART_CATEGORY_COMPANY.getValue().equals(sysDepart.getOrgCategory()) || DepartCategoryEnum.DEPART_CATEGORY_SUB_COMPANY.getValue().equals(sysDepart.getOrgCategory())) { + return sysDepart.getId(); + } + //如果不是公司或者子公司的时候,需要递归查询 + if (oConvertUtils.isNotEmpty(sysDepart.getParentId())) { + return getCompanyDepartId(sysDepart.getParentId()); + } else { + return parentDepartId; + } + } else { + return ""; + } + } + + @Override + public List getRankRelation(String departId) { + //记录当前部门 key为部门id,value为部门名称 + Map departNameMap = new HashMap<>(5); + //step1 根据id查询部门信息 + SysDepartPositionVo sysDepartPosition = baseMapper.getDepartPostByDepartId(departId); + if (null == sysDepartPosition) { + throw new JeecgBootBizTipException("当前所选部门数据为空"); + } + List selectTreeVos = new ArrayList<>(); + //step2 查看是否有子级部门,存在递归查询职位 + if (!CommonConstant.IS_LEAF.equals(sysDepartPosition.getIzLeaf())) { + //获取子级职位根据部门编码 + this.getChildrenDepartPositionByOrgCode(selectTreeVos, departNameMap, sysDepartPosition); + return buildTree(selectTreeVos); + } + return new ArrayList<>(); + } + + /** + * 获取子级职位根据部门编码 + * + * @param selectTreeVos + * @param departNameMap + * @param sysDepartPosition + */ + private void getChildrenDepartPositionByOrgCode(List selectTreeVos, Map departNameMap, SysDepartPositionVo sysDepartPosition) { + String orgCode = sysDepartPosition.getOrgCode(); + //step1 根据父级id获取子级部门信息 + List positionList = baseMapper.getDepartPostByOrgCode(orgCode + "%"); + if (CollectionUtil.isNotEmpty(positionList)) { + for (SysDepartPositionVo position : positionList) { + //初始化map + if (departNameMap == null) { + departNameMap = new HashMap<>(5); + } + SysDepart depart = baseMapper.getDepartById(position.getParentId()); + if(null != depart){ + position.setDepartName(depart.getDepartName()); + } + if(oConvertUtils.isNotEmpty(position.getDepPostParentId())){ + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(SysDepart::getId,position.getDepPostParentId()); + query.likeRight(SysDepart::getOrgCode,orgCode); + Long count = baseMapper.selectCount(query); + if(null== count || count == 0){ + position.setDepPostParentId(null); + } + } + departNameMap.put(position.getParentId(), position.getPositionName()); + //查看是否为部门岗位,不是则不需要处理 + SysPositionSelectTreeVo treeVo = new SysPositionSelectTreeVo(position); + selectTreeVos.add(treeVo); + } + } + } + + + /** + * 构建树形结构,只返回没有父级的一级节点 + */ + public static List buildTree(List nodes) { + // 存储一级节点(没有父级的节点) + List rootNodes = new ArrayList<>(); + // 先找出所有一级节点(parentId为null或空) + for (SysPositionSelectTreeVo node : nodes) { + if (node.getParentId() == null || node.getParentId().trim().isEmpty()) { + rootNodes.add(node); + } + } + // 为每个一级节点递归设置子节点 + for (SysPositionSelectTreeVo root : rootNodes) { + setChildren(root, nodes); + } + return rootNodes; + } + + /** + * 递归为节点设置子节点 + */ + private static void setChildren(SysPositionSelectTreeVo parentNode, List allNodes) { + for (SysPositionSelectTreeVo node : allNodes) { + // 如果当前节点的父ID等于父节点的ID,则是子节点 + if (parentNode.getId().equals(node.getParentId())) { + // 递归为子节点设置它的子节点 + setChildren(node, allNodes); + // 将子节点添加到父节点的子节点列表 + parentNode.getChildren().add(node); + } + } + } + + //=========================end 部门岗位改造 ================================================================== + + @Override + public String getDepartPathNameByOrgCode(String orgCode, String depId) { + //部门id为空需要查询当前部门下的编码 + if(oConvertUtils.isNotEmpty(depId)){ + SysDepart departById = baseMapper.getDepartById(depId); + if(null != departById){ + orgCode = departById.getOrgCode(); + } + } + if(oConvertUtils.isEmpty(orgCode)){ + return ""; + } + //从redis 获取不为空直接返回 + Object departName = redisUtil.get(CommonConstant.DEPART_NAME_REDIS_KEY_PRE + orgCode); + if(null != departName){ + return String.valueOf(departName); + } + //获取长度 + int codeNum = YouBianCodeUtil.ZHANWEI_LENGTH; + List list = this.getCodeHierarchy(orgCode, codeNum); + //根据部门编码查询公司和子公司的数据 + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.in(SysDepart::getOrgCode, list); + query.orderByAsc(SysDepart::getOrgCode); + List sysDepartList = departMapper.selectList(query); + if(!CollectionUtils.isEmpty(sysDepartList)){ + //获取部门名称拼接返回给前台 + List departNameList = sysDepartList.stream().map(SysDepart::getDepartName).toList(); + String departNames = String.join("/", departNameList); + redisUtil.set(CommonConstant.DEPART_NAME_REDIS_KEY_PRE + orgCode,departNames); + return departNames; + } + return ""; + } + + /** + * 获取编码及其所有上级编码 + * + * @param code 完整编码,如 "A01A01A01" + * @param fixedLength 固定位数,如 3 + * @return 包含所有上级编码的列表,如 ['A01','A01A01','A01A01A01'] + */ + public List getCodeHierarchy(String code, int fixedLength) { + List hierarchy = new ArrayList<>(); + if (code == null || code.isEmpty() || fixedLength <= 0) { + return hierarchy; + } + // 检查编码长度是否能被固定位数整除 + if (code.length() % fixedLength != 0) { + throw new IllegalArgumentException("编码长度必须能被固定位数整除"); + } + // 按固定位数分割并生成所有上级编码 + for (int i = fixedLength; i <= code.length(); i += fixedLength) { + hierarchy.add(code.substring(0, i)); + } + return hierarchy; + } } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserAgentServiceImpl.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserAgentServiceImpl.java deleted file mode 100644 index d46c057f3..000000000 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserAgentServiceImpl.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.jeecg.modules.system.service.impl; - -import org.jeecg.modules.system.entity.SysUserAgent; -import org.jeecg.modules.system.mapper.SysUserAgentMapper; -import org.jeecg.modules.system.service.ISysUserAgentService; -import org.springframework.stereotype.Service; - -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; - -/** - * @Description: 用户代理人设置 - * @Author: jeecg-boot - * @Date: 2019-04-17 - * @Version: V1.0 - */ -@Service -public class SysUserAgentServiceImpl extends ServiceImpl implements ISysUserAgentService { - -} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepPostServiceImpl.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepPostServiceImpl.java new file mode 100644 index 000000000..c502cedc1 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepPostServiceImpl.java @@ -0,0 +1,16 @@ +package org.jeecg.modules.system.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.jeecg.modules.system.entity.SysUserDepPost; +import org.jeecg.modules.system.mapper.SysUserDepPostMapper; +import org.jeecg.modules.system.service.ISysUserDepPostService; +import org.springframework.stereotype.Service; + +/** + * @Description: 部门岗位用户实现类 + * @author: wangshuai + * @date: 2025/9/5 11:46 + */ +@Service +public class SysUserDepPostServiceImpl extends ServiceImpl implements ISysUserDepPostService { +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepartServiceImpl.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepartServiceImpl.java index 66049a194..4839c5980 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepartServiceImpl.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepartServiceImpl.java @@ -1,5 +1,6 @@ package org.jeecg.modules.system.service.impl; +import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -9,6 +10,7 @@ import org.apache.shiro.SecurityUtils; import org.jeecg.common.config.TenantContext; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.SymbolConstant; +import org.jeecg.common.constant.enums.DepartCategoryEnum; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; @@ -172,6 +174,19 @@ public class SysUserDepartServiceImpl extends ServiceImpl queryDepartPostUserPageList(String departId, String username, String realname, Integer pageSize, Integer pageNo, String id, String isMultiTranslate) { + Page page = new Page(pageNo, pageSize); + if (oConvertUtils.isEmpty(departId)) { + // 部门ID不存在 直接查询用户表即可 + return getDepPostListByIdUserName(username,id,isMultiTranslate,page); + } else { + // 有部门ID 需要走部门岗位用户查询 + return getDepartPostListByIdUserRealName(departId,username,realname,page); + } + } + + /** + * 根据部门id和用户名获取部门岗位用户分页列表 + * + * @param id + * @param username + * @param isMultiTranslate + * @param page + * @return + */ + private IPage getDepPostListByIdUserName(String username, String id, String isMultiTranslate, Page page) { + //需要查询部门下的用户,故将写成自定义sql,非Lambda表达式的用法 + List userIdList = new ArrayList<>(); + List userNameList = new ArrayList<>(); + String userId = ""; + String userName = ""; + if (oConvertUtils.isNotEmpty(username)) { + String COMMA = ","; + if (oConvertUtils.isNotEmpty(isMultiTranslate) && username.contains(COMMA)) { + String[] usernameArr = username.split(COMMA); + userNameList.addAll(Arrays.asList(usernameArr)); + } else { + userName = username; + } + } + if (oConvertUtils.isNotEmpty(id)) { + String COMMA = ","; + if (oConvertUtils.isNotEmpty(isMultiTranslate) && id.contains(COMMA)) { + String[] idArr = id.split(COMMA); + userIdList.addAll(Arrays.asList(idArr)); + } else { + userId = ""; + } + } + //------------------------------------------------------------------------------------------------ + //是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】 + if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) { + String tenantId = oConvertUtils.getString(TenantContext.getTenant(), "0"); + List userIdsList = userTenantMapper.getUserIdsByTenantId(Integer.valueOf(tenantId)); + if (null != userIdsList && !userIdsList.isEmpty()) { + userIdList.addAll(userIdsList); + } + } + //------------------------------------------------------------------------------------------------ + return sysUserMapper.getDepPostListByIdUserName(page,userIdList,userId,userName,userNameList); + } + + /** + * 根据部门id、用户名和真实姓名获取部门岗位用户分页列表 + * + * @param departId + * @param username + * @param realname + * @param page + * @return + */ + private IPage getDepartPostListByIdUserRealName(String departId, String username, String realname, Page page) { + SysDepart sysDepart = sysDepartService.getById(departId); + return sysUserMapper.getDepartPostListByIdUserRealName(page, username, realname, sysDepart.getOrgCode()); + } } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java index f1fffee9d..4b3e62412 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java @@ -7,6 +7,7 @@ import com.alibaba.fastjson.JSONObject; import com.aliyuncs.exceptions.ClientException; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; @@ -23,10 +24,8 @@ import org.jeecg.common.constant.CacheConstant; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.FillRuleConstant; import org.jeecg.common.constant.SymbolConstant; -import org.jeecg.common.constant.enums.DySmsEnum; -import org.jeecg.common.constant.enums.MessageTypeEnum; -import org.jeecg.common.constant.enums.RoleIndexConfigEnum; -import org.jeecg.common.constant.enums.SysAnnmentTypeEnum; +import org.jeecg.common.constant.PasswordConstant; +import org.jeecg.common.constant.enums.*; import org.jeecg.common.desensitization.annotation.SensitiveEncode; import org.jeecg.common.exception.JeecgBootBizTipException; import org.jeecg.common.exception.JeecgBootException; @@ -39,14 +38,11 @@ import org.jeecg.modules.jmreport.common.util.OkConvertUtils; import org.jeecg.modules.message.handle.impl.SystemSendMsgHandle; import org.jeecg.modules.system.entity.*; import org.jeecg.modules.system.mapper.*; +import org.jeecg.modules.system.model.SysUserSysDepPostModel; import org.jeecg.modules.system.model.SysUserSysDepartModel; -import org.jeecg.modules.system.service.ISysRoleIndexService; -import org.jeecg.modules.system.service.ISysThirdAccountService; -import org.jeecg.modules.system.service.ISysUserService; -import org.jeecg.modules.system.vo.SysUserDepVo; -import org.jeecg.modules.system.vo.SysUserExportVo; -import org.jeecg.modules.system.vo.SysUserPositionVo; -import org.jeecg.modules.system.vo.UserAvatar; +import org.jeecg.modules.system.service.*; +import org.jeecg.modules.system.util.ImportSysUserCache; +import org.jeecg.modules.system.vo.*; import org.jeecg.modules.system.vo.lowapp.AppExportUserVo; import org.jeecg.modules.system.vo.lowapp.DepartAndUserInfo; import org.jeecg.modules.system.vo.lowapp.DepartInfo; @@ -130,6 +126,12 @@ public class SysUserServiceImpl extends ServiceImpl impl private ISysThirdAccountService sysThirdAccountService; @Autowired private RedisUtil redisUtil; + + @Autowired + private SysTenantPackUserMapper packUserMapper; + + @Autowired + private SysUserDepPostMapper depPostMapper; @Override public Result> queryPageList(HttpServletRequest req, QueryWrapper queryWrapper, Integer pageSize, Integer pageNo) { @@ -226,7 +228,14 @@ public class SysUserServiceImpl extends ServiceImpl impl } } //update-end---author:wangshuai---date:2023-10-08---for:【QQYUN-6668】钉钉部门和用户同步,我怎么知道哪些用户是双向绑定成功的--- - }); + //update-begin---author:wangshuai---date:2025-09-06---for: 兼职岗位改造成中间表的方式--- + //查询部门的兼职岗位 + List depPostList = depPostMapper.getDepPostByUserId(item.getId()); + if(CollectionUtil.isNotEmpty(depPostList)){ + item.setOtherDepPostId(StringUtils.join(depPostList.toArray(), SymbolConstant.COMMA)); + } + //update-end---author:wangshuai---date:2025-09-06---for:兼职岗位改造成中间表的方式--- + }); } result.setSuccess(true); @@ -576,12 +585,13 @@ public class SysUserServiceImpl extends ServiceImpl impl * @param page * @param roleId 角色id * @param username 用户账户名称 + * @param realname 用户姓名 * @return */ @Override - public IPage getUserByRoleId(Page page, String roleId, String username) { + public IPage getUserByRoleId(Page page, String roleId, String username, String realname) { //update-begin---author:wangshuai ---date:20230220 for:[QQYUN-3980]组织管理中 职位功能 职位表加租户id 加职位-用户关联表------------ - IPage userRoleList = userMapper.getUserByRoleId(page, roleId, username); + IPage userRoleList = userMapper.getUserByRoleId(page, roleId, username,realname); List records = userRoleList.getRecords(); if (null != records && records.size() > 0) { List userIds = records.stream().map(SysUser::getId).collect(Collectors.toList()); @@ -777,11 +787,11 @@ public class SysUserServiceImpl extends ServiceImpl impl @Override @Transactional(rollbackFor = Exception.class) - public void saveUser(SysUser user, String selectedRoles, String selectedDeparts, String relTenantIds) { + public void saveUser(SysUser user, String selectedRoles, String selectedDeparts, String relTenantIds, boolean izSyncPack) { //step.1 保存用户 this.save(user); //获取用户保存前台传过来的租户id并添加到租户 - this.saveUserTenant(user.getId(),relTenantIds); + this.saveUserTenant(user.getId(),relTenantIds, izSyncPack); //step.2 保存角色 if(oConvertUtils.isNotEmpty(selectedRoles)) { String[] arr = selectedRoles.split(","); @@ -802,6 +812,8 @@ public class SysUserServiceImpl extends ServiceImpl impl //step.4 保存职位 this.saveUserPosition(user.getId(),user.getPost()); + //step5 保存兼职岗位 + this.saveUserOtherDepPost(user.getId(),user.getOtherDepPostId()); } @Override @@ -861,8 +873,32 @@ public class SysUserServiceImpl extends ServiceImpl impl //step.5 修改职位 this.editUserPosition(user.getId(),user.getPost()); + + //update-begin---author:wangshuai---date:2025-09-06---for:兼职岗位改造成中间表的方式--- + //step6 修改兼职岗位 + //先删后加 + depPostMapper.delete(new QueryWrapper().lambda().eq(SysUserDepPost::getUserId, user.getId())); + this.saveUserOtherDepPost(user.getId(),user.getOtherDepPostId()); + //update-end---author:wangshuai---date:2025-09-06---for:兼职岗位改造成中间表的方式--- } + + /** + * 保存兼职岗位 + * + * @param userId + * @param otherDepPostId + */ + private void saveUserOtherDepPost(String userId, String otherDepPostId) { + if (oConvertUtils.isNotEmpty(otherDepPostId)) { + String[] depPostId = otherDepPostId.split(SymbolConstant.COMMA); + for (String postId : depPostId) { + SysUserDepPost userPosition = new SysUserDepPost(userId, postId); + depPostMapper.insert(userPosition); + } + } + } + @Override public List userIdToUsername(Collection userIdList) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); @@ -915,6 +951,7 @@ public class SysUserServiceImpl extends ServiceImpl impl SysUserTenant userTenant = new SysUserTenant(); userTenant.setStatus(CommonConstant.USER_TENANT_QUIT); userTenantMapper.update(userTenant,query); + //update-end---author:wangshuai ---date:20230111 for:[QQYUN-3951]租户用户离职重构------------ } @Override @@ -1005,10 +1042,12 @@ public class SysUserServiceImpl extends ServiceImpl impl /** * 保存租户 + * * @param userId * @param relTenantIds + * @param izSyncPack 是否需要将用户同步当前产品包下 */ - private void saveUserTenant(String userId, String relTenantIds) { + private void saveUserTenant(String userId, String relTenantIds, boolean izSyncPack) { if (oConvertUtils.isNotEmpty(relTenantIds)) { String[] tenantIds = relTenantIds.split(SymbolConstant.COMMA); for (String tenantId : tenantIds) { @@ -1026,6 +1065,9 @@ public class SysUserServiceImpl extends ServiceImpl impl relationMapper.updateById(tenantPresent); }else{ relationMapper.insert(relation); + ISysTenantService currentService = SpringContextUtils.getApplicationContext().getBean(ISysTenantService.class); + //默认添加当前用户到租户套餐中 + currentService.addPackUser(userId,tenantId); } } }else{ @@ -1041,6 +1083,11 @@ public class SysUserServiceImpl extends ServiceImpl impl relation.setTenantId(Integer.parseInt(tenantId)); relation.setStatus(CommonConstant.STATUS_1); relationMapper.insert(relation); + if(izSyncPack){ + ISysTenantService currentService = SpringContextUtils.getApplicationContext().getBean(ISysTenantService.class); + //自动为用户,添加租户下所有套餐 + currentService.addPackUser(userId,tenantId); + } } } //update-end---author:wangshuai ---date:20230220 for:判断当前用户是否在当前租户里面,如果不存在在新增------------ @@ -1063,7 +1110,7 @@ public class SysUserServiceImpl extends ServiceImpl impl this.deleteTenantByUserId(userId, null); } else if (oConvertUtils.isNotEmpty(relTenantIds) && CollectionUtils.isEmpty(oldTenantIds)) { //如果传过来的租户id不为空但是数据库的租户id为空,那么就新增 - this.saveUserTenant(userId, relTenantIds); + this.saveUserTenant(userId, relTenantIds, false); } else { //都不为空,需要比较,进行添加或删除 if(oConvertUtils.isNotEmpty(relTenantIds) && CollectionUtils.isNotEmpty(oldTenantIds)){ @@ -1077,7 +1124,7 @@ public class SysUserServiceImpl extends ServiceImpl impl } //找到原来租户的用户id与新的租户id不同之处,进行新增 String tenantIds = relTenantIdList.stream().filter(item -> !oldTenantIds.contains(Integer.valueOf(item))).collect(Collectors.joining(",")); - this.saveUserTenant(userId, tenantIds); + this.saveUserTenant(userId, tenantIds, false); } } } @@ -1094,6 +1141,13 @@ public class SysUserServiceImpl extends ServiceImpl impl query.eq(SysUserTenant::getTenantId, tenantId); } relationMapper.delete(query); + //删除产品包用户关联 + LambdaQueryWrapper packUserQuery = new LambdaQueryWrapper<>(); + packUserQuery.eq(SysTenantPackUser::getUserId, userId); + if(oConvertUtils.isNotEmpty(tenantId)){ + packUserQuery.eq(SysTenantPackUser::getTenantId, tenantId); + } + packUserMapper.delete(packUserQuery); } @@ -1595,7 +1649,8 @@ public class SysUserServiceImpl extends ServiceImpl impl AppExportUserVo exportUserVo = new AppExportUserVo(); BeanUtils.copyProperties(sysUser, exportUserVo); //update-begin---author:wangshuai---date:2025-01-17---for:【QQYUN-10926】组织管理——用户导出时,部门没有导出上下级关系--- - StringBuilder departNames = this.getDepartNames(userDepVos,sysUser); + Map departMap = this.getDepartNamesAndCategory(userDepVos, sysUser); + String departNames = departMap.get("departNames"); exportUserVo.setDepart(departNames.toString()); //update-end---author:wangshuai---date:2025-01-17---for:【QQYUN-10926】组织管理——用户导出时,部门没有导出上下级关系--- String posNames = positionVos.stream().filter(item -> item.getUserId().equals(sysUser.getId())).map(SysUserPositionVo::getName).collect(Collectors.joining(SymbolConstant.SEMICOLON)); @@ -1618,14 +1673,14 @@ public class SysUserServiceImpl extends ServiceImpl impl } /** - * 获取部门名称 + * 获取部门名称和部门类型 * for:【QQYUN-10926】组织管理——用户导出时,部门没有导出上下级关系 * * @param userDepVos * @param sysUser * @return */ - private StringBuilder getDepartNames(List userDepVos, SysUser sysUser) { + private Map getDepartNamesAndCategory(List userDepVos, SysUser sysUser) { List SysUserDepVoList = userDepVos.stream().filter(item -> item.getUserId().equals(sysUser.getId())) .map(item -> { SysUserDepVo userDepVo = new SysUserDepVo(); @@ -1633,44 +1688,62 @@ public class SysUserServiceImpl extends ServiceImpl impl userDepVo.setDeptId(item.getDeptId()); userDepVo.setDepartName(item.getDepartName()); userDepVo.setParentId(item.getParentId()); + userDepVo.setOrgCategory(DepartCategoryEnum.getNameByValue(item.getOrgCategory())); return userDepVo; }).collect(Collectors.toList()); //循环SysUserDepVoList,如果存在父级id的情况下,需要将父级id的部门名称查询出来 StringBuilder departNames = new StringBuilder(); + StringBuilder departOrgCategorys = new StringBuilder(); for (SysUserDepVo sysUserDepVo : SysUserDepVoList) { if(oConvertUtils.isEmpty(sysUserDepVo.getDepartName())){ continue; } //用于查询父级的部门名称 List departNameList = new LinkedList<>(); + //用于查询父级的部门类型 + List departOrgCategoryList = new LinkedList<>(); departNameList.add(sysUserDepVo.getDepartName()); + departOrgCategoryList.add(sysUserDepVo.getOrgCategory()); if (StringUtils.isNotEmpty(sysUserDepVo.getParentId())) { //递归查询部门名称 - this.getDepartNameByParentId(sysUserDepVo.getParentId(), departNameList); + this.getDepartNameByParentId(sysUserDepVo.getParentId(), departNameList, departOrgCategoryList); } Collections.reverse(departNameList); + Collections.reverse(departOrgCategoryList); String departName = departNameList.stream().collect(Collectors.joining(SymbolConstant.SINGLE_SLASH)); if (StringUtils.isNotEmpty(departNames.toString())) { departNames.append(SymbolConstant.SEMICOLON); } departNames.append(departName); + String orgCatrgory = departOrgCategoryList.stream().collect(Collectors.joining(SymbolConstant.SINGLE_SLASH)); + if (StringUtils.isNotEmpty(departOrgCategorys.toString())) { + departOrgCategorys.append(SymbolConstant.SEMICOLON); + } + departOrgCategorys.append(orgCatrgory); } - return departNames; + //update-begin---author:wangshuai---date:2025-08-27---for:【QQYUN-13617】导入时 部门添加层级不对了--- + Map map = new HashMap<>(); + map.put("departNames", departNames.toString()); + map.put("departOrgCategorys",departOrgCategorys.toString()); + return map; + //update-end---author:wangshuai---date:2025-08-27---for:【QQYUN-13617】导入时 部门添加层级不对了--- } /** - * 根据父级id查询父级的部门名称 + * 根据父级id查询父级的部门名称和部门类型 * for:【QQYUN-10926】组织管理——用户导出时,部门没有导出上下级关系 * * @param parentId * @param departNameList + * @param departOrgCategoryList */ - private void getDepartNameByParentId(String parentId, List departNameList) { + private void getDepartNameByParentId(String parentId, List departNameList, List departOrgCategoryList) { SysDepart parentDepartId = sysDepartMapper.getDepartById(parentId); if (null != parentDepartId) { departNameList.add(parentDepartId.getDepartName()); + departOrgCategoryList.add(DepartCategoryEnum.getNameByValue(parentDepartId.getOrgCategory())); if (StringUtils.isNotEmpty(parentDepartId.getParentId())) { - this.getDepartNameByParentId(parentDepartId.getParentId(), departNameList); + this.getDepartNameByParentId(parentDepartId.getParentId(), departNameList, departOrgCategoryList); } } } @@ -2158,22 +2231,44 @@ public class SysUserServiceImpl extends ServiceImpl impl if (CollectionUtil.isNotEmpty(userList)) { //获取部门 List userDepVos = sysDepartMapper.getUserDepartByUserId(userList); - //获取职位 + //获取角色 List sysRoles = sysRoleMapper.getUserRoleByUserId(userList); + //存放职位名称的map,key:主岗位的id value: 职级的名称 + Map postNameMap = new HashMap<>(); //组装数据并返回 for (SysUser sysUser : userList) { SysUserExportVo userExportVo = new SysUserExportVo(); BeanUtils.copyProperties(sysUser, userExportVo); - StringBuilder departNames = this.getDepartNames(userDepVos, sysUser); - userExportVo.setDepartNames(departNames.toString()); + //update-begin---author:wangshuai---date:2025-08-27---for:【QQYUN-13617】导入时 部门添加层级不对了--- + Map departMap = this.getDepartNamesAndCategory(userDepVos, sysUser); + String departNames = departMap.get("departNames"); + userExportVo.setDepartNames(departNames); + userExportVo.setOrgCategorys(departMap.get("departOrgCategorys")); + //update-end---author:wangshuai---date:2025-08-27---for:【QQYUN-13617】导入时 部门添加层级不对了--- String departIds = sysUser.getDepartIds(); if (oConvertUtils.isNotEmpty(departIds)) { List depVoList = sysDepartMapper.getDepartByIds(Arrays.asList(departIds.split(","))); - StringBuilder names = this.getDepartNames(userDepVos, sysUser); - userExportVo.setDepartIds(names.toString()); + Map departMaps = this.getDepartNamesAndCategory(userDepVos, sysUser); + userExportVo.setDepartIds(departMaps.get("departNames")); } String posNames = sysRoles.stream().filter(item -> item.getUserId().equals(sysUser.getId())).map(SysUserPositionVo::getName).collect(Collectors.joining(SymbolConstant.SEMICOLON)); userExportVo.setRoleNames(posNames); + if (null != sysUser.getMainDepPostId()) { + String postName = ""; + if (null != postNameMap && postNameMap.containsKey(sysUser.getMainDepPostId())) { + postName = postNameMap.get(sysUser.getMainDepPostId()); + } else { + postName = sysDepartMapper.getPostNameByPostId(sysUser.getMainDepPostId()); + } + userExportVo.setPostName(postName); + postNameMap.put(sysUser.getMainDepPostId(), postName); + } + //update-begin---author:wangshuai---date:2025-09-06---for:兼职岗位改造成中间表的方式--- + List depPost = depPostMapper.getDepPostByUserId(sysUser.getId()); + if(CollectionUtil.isNotEmpty(depPost)){ + userExportVo.setOtherDepPostId(String.join(SymbolConstant.COMMA, depPost)); + } + //update-end---author:wangshuai---date:2025-09-06---for:兼职岗位改造成中间表的方式--- list.add(userExportVo); } } @@ -2183,13 +2278,17 @@ public class SysUserServiceImpl extends ServiceImpl impl @Override public Result importSysUser(HttpServletRequest request) { MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + String fileKey = multipartRequest.getParameter("fileKey"); Map fileMap = multipartRequest.getFileMap(); // 错误信息 List errorMessage = new ArrayList<>(); int successLines = 0, errorLines = 0; //存放部门的map;key为名称 value为SysDepart对象。避免多次导入和查询 Map departMap = new HashMap<>(); + //职级map key: 职级名称 value: 职级id Map positionMap = new HashMap<>(); + //岗位map key:岗位名称 + 部门id value:岗位(部门id) + Map postMap = new HashMap<>(); String tenantId = TokenUtils.getTenantIdByRequest(request); for (Map.Entry entity : fileMap.entrySet()) { MultipartFile file = entity.getValue();// 获取上传文件对象 @@ -2198,9 +2297,10 @@ public class SysUserServiceImpl extends ServiceImpl impl params.setHeadRows(1); params.setNeedSave(true); try { - List listSysUsers = ExcelImportUtil.importExcel(file.getInputStream(), SysUserExportVo.class, params); + List listSysUsers = ExcelImportUtil.importExcel(file.getInputStream(), SysUserImportVo.class, params); + ImportSysUserCache.setImportSysUserMap(fileKey,0,listSysUsers.size(),"user"); for (int i = 0; i < listSysUsers.size(); i++) { - SysUserExportVo sysUserExcel = listSysUsers.get(i); + SysUserImportVo sysUserExcel = listSysUsers.get(i); SysUser sysUser = new SysUser(); BeanUtils.copyProperties(sysUserExcel, sysUser); if (OkConvertUtils.isEmpty(sysUser.getUsername())) { @@ -2220,30 +2320,32 @@ public class SysUserServiceImpl extends ServiceImpl impl continue; } else { // 密码默认为 “123456” - sysUser.setPassword("123456"); + sysUser.setPassword(PasswordConstant.DEFAULT_PASSWORD); // 密码加密加盐 String salt = oConvertUtils.randomGen(8); sysUser.setSalt(salt); String passwordEncode = PasswordUtil.encrypt(sysUserExcel.getUsername(), sysUser.getPassword(), salt); sysUser.setPassword(passwordEncode); + sysUser.setActivitiSync(CommonConstant.ACT_SYNC_1); this.save(sysUser); } //添加部门 String departNames = sysUserExcel.getDepartNames(); + String orgCategorys = sysUserExcel.getOrgCategorys(); //新增或编辑部门 - Integer tenantIdInt = null; + Integer tenantIdInt = 0; if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) { tenantIdInt = OkConvertUtils.getInt(tenantId, 0); } - this.addOrEditDepart(sysUser.getId(), departNames, tenantIdInt, departMap); + this.lowAddOrEditDepart(sysUser.getId(), departNames, tenantIdInt, departMap, orgCategorys, sysUserExcel.getPostName(), sysUserExcel.getMainDepPostId(),postMap,positionMap); //新增或编辑角色 String roleNames = sysUserExcel.getRoleNames(); this.saveOrEditRole(sysUser.getId(), roleNames, tenantIdInt); //新增或编辑职位 - String position = sysUserExcel.getPost(); + /* String position = sysUserExcel.getPost(); if (oConvertUtils.isNotEmpty(position)) { this.addOrEditPosition(sysUser.getId(), position, false, tenantIdInt, positionMap); - } + }*/ //添加负责部门 this.saveChargeDepart(sysUser, sysUserExcel.getDepartIds(), departMap); successLines++; @@ -2267,14 +2369,17 @@ public class SysUserServiceImpl extends ServiceImpl impl log.error(e.getMessage(), e); } } + ImportSysUserCache.setImportSysUserMap(fileKey,i,listSysUsers.size(),"user"); } } catch (Exception e) { + ImportSysUserCache.removeImportLowAppMap(fileKey); errorMessage.add("发生异常:" + e.getMessage()); log.error(e.getMessage(), e); } finally { try { file.getInputStream().close(); } catch (IOException e) { + ImportSysUserCache.removeImportLowAppMap(fileKey); log.error(e.getMessage(), e); } } @@ -2282,12 +2387,201 @@ public class SysUserServiceImpl extends ServiceImpl impl try { departMap.clear(); departMap = null; + //最终导入完成 + ImportSysUserCache.setImportSysUserMap(fileKey,1,1,"user"); return ImportExcelUtil.imporReturnRes(errorLines, successLines, errorMessage); } catch (IOException e) { + ImportSysUserCache.removeImportLowAppMap(fileKey); throw new RuntimeException(e); } } + //================================================================ begin 【用户导入】导入时 部门添加层级不对了====================================================================== + /** + * 低代码下添加部门和用户 + * + * @Description 和敲敲云分割处理,原因:因低代码岗位等改造,有级别,故添加部门分开处理 + * @param userId 用户id + * @param depart 部门名称 + * @param tenantId 租户id + * @param departMap 存放部门的map;key为名称 value为SysDepart对象。 + * @param orgCategorys 部门类型 + * @param postName 职级名称 + * @param mainDepPostName 岗位名称 + * @param postMap key: 岗位名称 + 部门id value:岗位(部门id) + * @param positionMap key: 职级名称 value: 职级id + */ + private void lowAddOrEditDepart(String userId, String depart, Integer tenantId, Map departMap, String orgCategorys, String postName, String mainDepPostName, Map postMap, Map positionMap) { + //批量将部门和用户信息建立关联关系 + if (StringUtils.isNotEmpty(depart)) { + Page page = new Page<>(1, 1); + //多个部门分离开 + String[] departNames = depart.split(SymbolConstant.SEMICOLON); + List departNameList = Arrays.asList(departNames); + //部门类型 + List categoryList = new ArrayList<>(); + if (oConvertUtils.isNotEmpty(orgCategorys)) { + categoryList = Arrays.asList(orgCategorys.split(SymbolConstant.SEMICOLON)); + } + departNameList = departNameList.stream().distinct().collect(Collectors.toList()); + //当下部门循环下标 + int index = 0; + for (String departName : departNameList) { + //部门id + String parentId = ""; + String[] names = departName.split(SymbolConstant.SINGLE_SLASH); + //部门名称拼接 + String nameStr = ""; + //部门类型 + String[] orgCategory = null; + if (categoryList != null && categoryList.size() > index) { + orgCategory = categoryList.get(index).split(SymbolConstant.SINGLE_SLASH); + } + for (int i = 0; i < names.length; i++) { + String name = names[i]; + //拼接name + if (oConvertUtils.isNotEmpty(nameStr)) { + nameStr = nameStr + SymbolConstant.SINGLE_SLASH + name; + } else { + nameStr = name; + } + SysDepart sysDepart = null; + //默认部门 + String category = DepartCategoryEnum.DEPART_CATEGORY_DEPART.getValue(); + if (null != orgCategory && orgCategory.length > i) { + category = orgCategory[i]; + } + //判断map中是否存在该部门名称 + if (departMap.containsKey(nameStr)) { + sysDepart = departMap.get(nameStr); + parentId = sysDepart.getId(); + } else { + //不存在需要去查询 + List departPageByName = sysDepartMapper.getDepartPageByName(page, name, tenantId, parentId); + //部门为空需要新增部门 + if (CollectionUtil.isEmpty(departPageByName)) { + JSONObject formData = new JSONObject(); + formData.put("parentId", parentId); + String[] codeArray = (String[]) FillRuleUtil.executeRule(FillRuleConstant.DEPART, formData); + sysDepart = new SysDepart(); + sysDepart.setParentId(parentId); + sysDepart.setOrgCode(codeArray[0]); + sysDepart.setOrgType(codeArray[1]); + sysDepart.setTenantId(tenantId); + sysDepart.setDepartName(name); + sysDepart.setIzLeaf(CommonConstant.IS_LEAF); + sysDepart.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0)); + sysDepart.setStatus(CommonConstant.STATUS_1); + sysDepart.setOrgCategory(DepartCategoryEnum.getValueByName(category)); + sysDepartMapper.insert(sysDepart); + } else { + sysDepart = departPageByName.get(0); + } + //父级id不为空那么就将父级部门改成不是叶子节点 + if (oConvertUtils.isNotEmpty(parentId)) { + sysDepartMapper.setMainLeaf(parentId, CommonConstant.NOT_LEAF); + } + parentId = sysDepart.getId(); + departMap.put(nameStr, sysDepart); + } + //最后一位新增部门用户关系表 + if (i == names.length - 1) { + Long count = sysUserDepartMapper.getCountByDepartIdAndUserId(userId, sysDepart.getId()); + if (count == 0) { + SysUserDepart userDepart = new SysUserDepart(userId, sysDepart.getId()); + sysUserDepartMapper.insert(userDepart); + } + //添加岗位 + if (oConvertUtils.isNotEmpty(mainDepPostName)) { + this.insertDepartPost(userId, parentId ,postName, mainDepPostName, postMap, tenantId, positionMap); + } + } + } + index++; + } + } + } + + /** + * 添加部门岗位 + * + * @param mainDepPost 岗位名称 + * @param userId 用户id + * @param departId 部门id【上级部门id】 + * @param postName 职级名称 + * @param mainDepPostName 岗位名称 + * @param postMap 岗位map key:岗位名称 + 部门id value:岗位(部门id) + * @param tenantId 租户id + * @param postionMap 职级map key: 职级名称 value: 职级id + */ + private void insertDepartPost(String userId, String depId, String postName, String mainDepPostName, Map postMap, Integer tenantId, Map postionMap) { + if(mainDepPostName.contains(SymbolConstant.COMMA)){ + mainDepPostName = mainDepPostName.split(SymbolConstant.COMMA)[0]; + } + //当前部门下已经存在岗位就不需要再次添加岗位了 + if (null == postMap || !postMap.containsKey(mainDepPostName + depId)) { + //根据父级部门id和职务名称查找岗位id + String departId = sysDepartMapper.getDepIdByDepIdAndPostName(depId, postName); + //不存在新增岗位 + if (oConvertUtils.isEmpty(departId) ) { + //新增岗位 + SysDepart sysDepart = new SysDepart(); + JSONObject formData = new JSONObject(); + formData.put("parentId", depId); + String[] codeArray = (String[]) FillRuleUtil.executeRule(FillRuleConstant.DEPART, formData); + sysDepart.setParentId(depId); + sysDepart.setOrgCode(codeArray[0]); + sysDepart.setOrgType(codeArray[1]); + sysDepart.setTenantId(tenantId); + sysDepart.setDepartName(mainDepPostName); + sysDepart.setIzLeaf(CommonConstant.IS_LEAF); + sysDepart.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0)); + sysDepart.setStatus(CommonConstant.STATUS_1); + sysDepart.setOrgCategory(DepartCategoryEnum.DEPART_CATEGORY_POST.getValue()); + //获取职级id + String positionId = ""; + if(postionMap.containsKey(postName)){ + positionId = postionMap.get(postName); + } else { + //根据租户id和职级名称获取职级id + positionId = this.getSysPosition(tenantId, postName); + } + sysDepart.setPositionId(positionId); + postionMap.put(postName, positionId); + sysDepartMapper.insert(sysDepart); + sysDepartMapper.setMainLeaf(depId, CommonConstant.NOT_LEAF); + postMap.put(mainDepPostName + depId, sysDepart.getId()); + //需要将用户表的主岗位进行关联 + departId = sysDepart.getId(); + } + if(oConvertUtils.isNotEmpty(departId)){ + //更新用户主岗位 + SysUser user = new SysUser(); + user.setId(userId); + user.setMainDepPostId(departId); + userMapper.updateById(user); + } + } + } + + /** + * 获取职务信息 + * + * @param tenantId + * @param postName + * @return + */ + private String getSysPosition(Integer tenantId, String postName) { + tenantId = oConvertUtils.getInt(tenantId,0); + Page page = new Page<>(1, 1); + List namePage = sysPositionMapper.getPositionIdByName(postName, tenantId, page); + if (CollectionUtil.isNotEmpty(namePage)) { + return namePage.get(0); + } + return ""; + } + //================================================================ end 【用户导入】导入时 部门添加层级不对了====================================================================== + private void saveChargeDepart(SysUser sysUser, String departIds, Map departMap) { //判断那些部门没有,即没有加入到部门,则不能成为负责部门人员 if (OkConvertUtils.isEmpty(departIds)) { @@ -2307,8 +2601,10 @@ public class SysUserServiceImpl extends ServiceImpl impl if (departIdBulider.length() > 0 && departIdBulider.charAt(departIdBulider.length() - 1) == ',') { departIdBulider.deleteCharAt(departIdBulider.length() - 1); } - sysUser.setDepartIds(departIdBulider.toString()); - this.updateById(sysUser); + SysUser user = new SysUser(); + user.setId(sysUser.getId()); + user.setDepartIds(departIdBulider.toString()); + this.updateById(user); } /** @@ -2382,4 +2678,82 @@ public class SysUserServiceImpl extends ServiceImpl impl String newPassWord = PasswordUtil.encrypt(username, password, user.getSalt()); this.userMapper.update(new SysUser().setPassword(newPassWord), new LambdaQueryWrapper().eq(SysUser::getId, user.getId())); } + + /** + * + * @param userName + * @return + */ + @Override + public Map queryUserAndDeptByName(String userName) { + // 返回用户和部门信息(根据需求调整) + Map result = new HashMap<>(); + SysUser user = this.getUserByName(userName); + result.put("userId", user.getId()); + result.put("username", user.getUsername()); + //用户的部门信息 + String orgCode = user.getOrgCode(); + if (oConvertUtils.isEmpty(orgCode)) { + return result; + } + + // 查询公司部门 + String companyName = Optional.ofNullable(sysDepartMapper.queryCompByOrgCode(orgCode)) + .map(SysDepart::getDepartName) + .orElse(""); + + // 查询用户部门并匹配 + String userDeptName = sysDepartMapper.queryDepartsByUsername(userName).stream() + .filter(depart -> orgCode.equals(depart.getOrgCode())) + .findFirst() + .map(SysDepart::getDepartName) + .orElse(""); + + // 设置部门显示文本 + String compDepart; + if (StringUtils.isNotEmpty(companyName) && StringUtils.isNotEmpty(userDeptName)) { + compDepart = companyName.equals(userDeptName) + ? companyName + : companyName + "-" + userDeptName; + } else { + compDepart = StringUtils.isNotEmpty(companyName) ? companyName : userDeptName; + } + result.put("compDepart", compDepart); + return result; + } + + /** + * 查询部门、岗位下的用户 包括子部门下的用户 + * + * @param orgCode + * @param userParams + * @param page + * @return + */ + @Override + public IPage queryDepartPostUserByOrgCode(String orgCode, SysUser userParams, IPage page) { + List sysDepartModels = baseMapper.queryDepartPostUserByOrgCode(page, orgCode, userParams); + if(CollectionUtil.isNotEmpty(sysDepartModels)){ + List userIds = sysDepartModels.stream().map(SysUserSysDepPostModel::getId).toList(); + //获取部门名称 + Map useDepNames = this.getDepNamesByUserIds(userIds); + sysDepartModels.forEach(item -> { + List positionList = sysUserPositionMapper.getPositionIdByUserId(item.getId()); + item.setPost(CommonUtils.getSplitText(positionList,SymbolConstant.COMMA)); + item.setOrgCodeTxt(useDepNames.get(item.getId())); + //查询用户的租户ids + List list = userTenantMapper.getTenantIdsByUserId(item.getId()); + if (oConvertUtils.isNotEmpty(list)) { + item.setRelTenantIds(StringUtils.join(list.toArray(), SymbolConstant.COMMA)); + } else { + item.setRelTenantIds(""); + } + Integer posTenantId = null; + if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) { + posTenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);; + } + }); + } + return page.setRecords(sysDepartModels); + } } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/util/ImportSysUserCache.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/util/ImportSysUserCache.java new file mode 100644 index 000000000..c07da36fc --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/util/ImportSysUserCache.java @@ -0,0 +1,53 @@ +package org.jeecg.modules.system.util; + +import java.util.HashMap; +import java.util.Map; + +/** + * @Description: 导入缓存类,为了前台显示进度 + * @author: wangshuai + * @date: 2025/9/6 14:09 + */ +public class ImportSysUserCache { + + private static final Map importSysUserMap = new HashMap<>(); + + /** + * 获取导入的列 + * + * @param key + * @param type user 用户 可扩展 + * @return + */ + public static Double getImportSysUserMap(String key, String type) { + if (importSysUserMap.containsKey(key + "__" + type)) { + return importSysUserMap.get(key + "__" + type); + } + return 0.0; + } + + /** + * 设置导入缓存 + * + * @param key 前村传过来的随机key + * @param num 导入行数 + * @param length 总长度 + * @param type 导入类型 user 用户列表 + */ + public static void setImportSysUserMap(String key, int num, int length, String type) { + double percent = (num * 100.0) / length; + if(num == length){ + percent = 100; + } + importSysUserMap.put(key + "__" + type, percent); + } + + /** + * 移除导入缓存 + * + * @param key + */ + public static void removeImportLowAppMap(String key) { + importSysUserMap.remove(key); + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysDepartExportVo.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysDepartExportVo.java index d647697db..0fc81eebe 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysDepartExportVo.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysDepartExportVo.java @@ -28,6 +28,9 @@ public class SysDepartExportVo { /**机构类别 1=公司,2=组织机构,3=岗位*/ @Excel(name="机构类别",width=15,dicCode="org_category") private String orgCategory; + /** 职级id */ + @Excel(name="职级",width=15,dictTable = "sys_position", dicCode = "id", dicText = "name") + private String positionId; /**机构编码*/ @Excel(name="机构编码",width=15) private String orgCode; diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysDepartPositionVo.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysDepartPositionVo.java new file mode 100644 index 000000000..97014df19 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysDepartPositionVo.java @@ -0,0 +1,53 @@ +package org.jeecg.modules.system.vo; + +import lombok.Data; + +/** +* @Description: 部门职务 +* +* @author: wangshuai +* @date: 2025/8/18 10:11 +*/ +@Data +public class SysDepartPositionVo { + + /** + * 部门id + */ + private String id; + + /** + * 是否为叶子节点(数据返回) + */ + private Integer izLeaf; + + /** + * 部门名称 + */ + private String departName; + + /** + * 职务名称 + */ + private String positionName; + + /** + * 父级id + */ + private String parentId; + + /** + * 部门编码 + */ + private String orgCode; + + /** + * 机构类型 + */ + private String orgCategory; + + /** + * 上级岗位id + */ + private String depPostParentId; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysPositionSelectTreeVo.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysPositionSelectTreeVo.java new file mode 100644 index 000000000..a487f6200 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysPositionSelectTreeVo.java @@ -0,0 +1,83 @@ +package org.jeecg.modules.system.vo; + +import lombok.Data; +import org.jeecg.common.constant.enums.DepartCategoryEnum; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.system.entity.SysDepart; + +import java.util.ArrayList; +import java.util.List; + +/** +* @Description: 岗位下拉选择树 +* +* @author: wangshuai +* @date: 2025/8/18 9:40 +*/ +@Data +public class SysPositionSelectTreeVo { + /** 对应SysDepart中的id字段,前端数据树中的value*/ + private String value; + + /** 对应depart_name字段,前端数据树中的title*/ + private String title; + private boolean isLeaf; + /** 是否显示复选框 */ + private boolean checkable; + /** 是否禁用 */ + private boolean disabled; + // 以下所有字段均与SysDepart相同 + private String id; + /**父级id*/ + private String parentId; + /**部门类别*/ + private String orgCategory; + /**部门编码*/ + private String orgCode; + + private List children = new ArrayList<>(); + + /** + * 将SysDepart对象转换成SysDepartTreeModel对象 + * @param sysDepart + */ + public SysPositionSelectTreeVo(SysDepart sysDepart) { + this.value = sysDepart.getId(); + this.title = sysDepart.getDepartName(); + this.id = sysDepart.getId(); + this.parentId = sysDepart.getParentId(); + this.orgCategory = sysDepart.getOrgCategory(); + this.orgCode = sysDepart.getOrgCode(); + if(0 == sysDepart.getIzLeaf()){ + this.isLeaf = false; + }else{ + this.isLeaf = true; + } + if(DepartCategoryEnum.DEPART_CATEGORY_POST.getValue().equals(sysDepart.getOrgCategory())){ + this.checkable = true; + this.disabled = false; + }else{ + this.checkable = false; + this.disabled = true; + } + } + + public SysPositionSelectTreeVo(SysDepartPositionVo position) { + this.value = position.getId(); + if(oConvertUtils.isNotEmpty(position.getDepartName())){ + this.title = position.getPositionName() + "("+position.getDepartName()+")"; + }else{ + this.title = position.getPositionName(); + } + this.id = position.getId(); + this.parentId = position.getDepPostParentId(); + this.orgCategory = "3"; + if(0 == position.getIzLeaf()){ + this.isLeaf = false; + }else{ + this.isLeaf = true; + } + this.checkable = true; + this.disabled = false; + } +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserDepVo.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserDepVo.java index 913d7ed80..2e09a9163 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserDepVo.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserDepVo.java @@ -21,4 +21,14 @@ public class SysUserDepVo { * 部门的父级id */ private String parentId; + + /** + * 部门类型 + */ + private String orgCategory; + + /** + * 职级 + */ + private String positionId; } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserExportVo.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserExportVo.java index 2b9dcb963..3ce72c184 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserExportVo.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserExportVo.java @@ -1,8 +1,8 @@ package org.jeecg.modules.system.vo; -import com.baomidou.mybatisplus.annotation.TableField; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; +import org.jeecg.common.aspect.annotation.Dict; import org.jeecgframework.poi.excel.annotation.Excel; import org.springframework.format.annotation.DateTimeFormat; @@ -77,13 +77,26 @@ public class SysUserExportVo { */ @Excel(name = "工号", width = 15) private String workNo; + + /** + * 主岗位 + */ + @Excel(name="主岗位",width = 15,dictTable ="sys_depart",dicText = "depart_name",dicCode = "id") + @Dict(dictTable ="sys_depart",dicText = "depart_name",dicCode = "id") + private String mainDepPostId; /** - * 职务,关联职务表 + * 职级 */ - @Excel(name = "职务", width = 15) - @TableField(exist = false) - private String post; + @Excel(name="职级", width = 15) + private String postName; + + /** + * 兼职岗位 + */ + @Excel(name="兼职岗位",width = 15,dictTable ="sys_depart",dicText = "depart_name",dicCode = "id") + @Dict(dictTable ="sys_depart",dicText = "depart_name",dicCode = "id") + private String otherDepPostId; /** * 座机号 @@ -110,10 +123,22 @@ public class SysUserExportVo { @Excel(name = "所属部门", width = 15) private String departNames; + /** + * 机构类型 + * 公司(1)、部门(2)、岗位(3)、子公司(4) + */ + @Excel(name = "部门类型(1-公司,2-部门,3-岗位,4-子公司)",width = 15) + private String orgCategorys; + /** * 负责部门 */ @Excel(name = "负责部门", width = 15) private String departIds; + /** + * 职务 + */ + @Excel(name="职务", dicCode = "user_position") + private String positionType; } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserImportVo.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserImportVo.java new file mode 100644 index 000000000..fc1234363 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserImportVo.java @@ -0,0 +1,129 @@ +package org.jeecg.modules.system.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +/** + * @Description: 低代码用户导入 + * @author: wangshuai + * @date: 2025/8/27 11:58 + */ +@Data +public class SysUserImportVo { + + /** + * 登录账号 + */ + @Excel(name = "登录账号", width = 15) + private String username; + + /** + * 真实姓名 + */ + @Excel(name = "真实姓名", width = 15) + private String realname; + + /** + * 头像 + */ + @Excel(name = "头像", width = 15, type = 2) + private String avatar; + + /** + * 生日 + */ + @Excel(name = "生日", width = 15, format = "yyyy-MM-dd") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date birthday; + + /** + * 性别(1:男 2:女) + */ + @Excel(name = "性别", width = 15, dicCode = "sex") + private Integer sex; + + /** + * 电子邮件 + */ + @Excel(name = "电子邮件", width = 15) + private String email; + + /** + * 电话 + */ + @Excel(name = "电话", width = 15) + private String phone; + + /** + * 状态(1:正常 2:冻结 ) + */ + @Excel(name = "状态", width = 15, dicCode = "user_status") + private Integer status; + + /** + * 删除状态(0,正常,1已删除) + */ + @Excel(name = "删除状态", width = 15, dicCode = "del_flag") + private Integer delFlag; + + /** + * 工号,唯一键 + */ + @Excel(name = "工号", width = 15) + private String workNo; + + /** + * 主岗位 + */ + @Excel(name="主岗位",width = 15) + private String mainDepPostId; + + /** + * 职级 + */ + @Excel(name="职级", width = 15) + private String postName; + + /** + * 身份(0 普通成员 1 上级) + */ + @Excel(name = "(1普通成员 2上级)", width = 15) + private Integer userIdentity; + + /** + * 角色名称 + */ + @Excel(name = "角色", width = 15) + private String roleNames; + + /** + * 部门名称 + */ + @Excel(name = "所属部门", width = 15) + private String departNames; + + /** + * 机构类型 + * 公司(1)、部门(2)、岗位(3)、子公司(4) + */ + @Excel(name = "部门类型(1-公司,2-部门,3-岗位,4-子公司)",width = 15) + private String orgCategorys; + + /** + * 负责部门 + */ + @Excel(name = "负责部门", width = 15) + private String departIds; + + /** + * 职务 + */ + @Excel(name="职务", dicCode = "user_position") + private String positionType; + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserTenantVo.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserTenantVo.java index d5393c7c4..2d34fbcfb 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserTenantVo.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysUserTenantVo.java @@ -1,7 +1,11 @@ package org.jeecg.modules.system.vo; +import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import org.jeecg.common.aspect.annotation.Dict; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; /** * @Description: 用户租户类(用户数据租户数据) @@ -44,7 +48,14 @@ public class SysUserTenantVo { /** * 头像 */ - private String avatar; + private String avatar; + + /** + * 创建日期 + */ + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + private Date createTime; /** * 职位 diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/system/test/SysUserApiTest.java b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/system/test/SysUserApiTest.java index bb3d51669..699579eeb 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/system/test/SysUserApiTest.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/test/java/org/jeecg/modules/system/test/SysUserApiTest.java @@ -63,9 +63,6 @@ public class SysUserApiTest { @MockBean private BaseCommonService baseCommonService; - @MockBean - private ISysUserAgentService sysUserAgentService; - @MockBean private ISysPositionService sysPositionService;