From 4f914f0008f04ccd7c1129b9fcb92a0ca7f10880 Mon Sep 17 00:00:00 2001 From: luoweijian <1329394916@qq.com> Date: Mon, 26 Jan 2026 17:16:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=B9=E9=87=8F=E6=9B=B4=E6=96=B0=E5=91=98?= =?UTF-8?q?=E5=B7=A5=E9=83=A8=E9=97=A8=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InsertBatchOnDuplicateKeyUpdate.java | 56 ++++++++++++++++++ .../base/config/MybatisPlusConfig.java | 20 +++++++ .../base/mapper/BatchUpsertMapper.java | 12 ++++ .../ding/controller/DepartmentController.java | 5 +- .../ding/controller/SyncController.java | 25 ++++++++ .../ding/domain/dto/DepartmentDTO.java | 8 +++ .../project/ding/domain/dto/DingUserDTO.java | 12 ++++ .../com/project/ding/domain/dto/UserDTO.java | 8 +++ .../ding/domain/entity/DepartmentEntity.java | 17 +++++- .../ding/domain/entity/UserEntity.java | 32 +++++++++- .../domain/service/DepartmentBaseService.java | 8 +++ .../impl/DepartmentBaseServiceImpl.java | 11 ++++ .../project/ding/mapper/DepartmentMapper.java | 4 +- .../com/project/ding/mapper/UserMapper.java | 3 +- .../project/ding/utils/DingUserSyncUtil.java | 56 +++++++++++++++--- .../java/com/project/ding/utils/DingUtil.java | 39 ++++++++++-- src/main/resources/application.yml | 17 +++++- src/main/resources/static/favicon.ico | Bin 0 -> 15406 bytes 18 files changed, 313 insertions(+), 20 deletions(-) create mode 100644 src/main/java/com/project/base/config/InsertBatchOnDuplicateKeyUpdate.java create mode 100644 src/main/java/com/project/base/config/MybatisPlusConfig.java create mode 100644 src/main/java/com/project/base/mapper/BatchUpsertMapper.java create mode 100644 src/main/java/com/project/ding/controller/SyncController.java create mode 100644 src/main/java/com/project/ding/domain/service/DepartmentBaseService.java create mode 100644 src/main/java/com/project/ding/domain/service/impl/DepartmentBaseServiceImpl.java create mode 100644 src/main/resources/static/favicon.ico diff --git a/src/main/java/com/project/base/config/InsertBatchOnDuplicateKeyUpdate.java b/src/main/java/com/project/base/config/InsertBatchOnDuplicateKeyUpdate.java new file mode 100644 index 0000000..97f07bb --- /dev/null +++ b/src/main/java/com/project/base/config/InsertBatchOnDuplicateKeyUpdate.java @@ -0,0 +1,56 @@ +package com.project.base.config; + +import com.baomidou.mybatisplus.core.injector.AbstractMethod; +import com.baomidou.mybatisplus.core.metadata.TableInfo; +import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; +import org.apache.ibatis.executor.keygen.NoKeyGenerator; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.SqlSource; + +import java.util.stream.Collectors; + +/** + * 自定义选装件:MySQL 批量 Upsert + */ +public class InsertBatchOnDuplicateKeyUpdate extends AbstractMethod { + + protected InsertBatchOnDuplicateKeyUpdate() { + super("batchUpsert"); // 方法名 + } + + @Override + public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { + final String methodName = "batchUpsert"; + + // 1. 准备 INSERT 字段 + String columnScript = "(" + tableInfo.getKeyColumn() + "," + + tableInfo.getFieldList().stream() + .map(TableFieldInfo::getColumn) + .collect(Collectors.joining(",")) + ")"; + + // 2. 准备 VALUES 部分 (修复重点!) + String valuesScript = "(#{item." + tableInfo.getKeyProperty() + "}," + + tableInfo.getFieldList().stream() + .map(i -> { + // 【核心修复】检查该字段是否有 TypeHandler (如 JacksonTypeHandler) + if (i.getTypeHandler() != null) { + // 生成格式如:#{item.depIdPath,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler} + return "#{item." + i.getProperty() + ",typeHandler=" + i.getTypeHandler().getName() + "}"; + } + return "#{item." + i.getProperty() + "}"; + }) + .collect(Collectors.joining(",")) + ")"; + + // 3. 准备 ON DUPLICATE KEY UPDATE 部分 + String updateScript = tableInfo.getFieldList().stream() + .filter(i -> !i.getColumn().equals("create_time")) + .map(i -> i.getColumn() + " = VALUES(" + i.getColumn() + ")") + .collect(Collectors.joining(",")) + ", update_time = NOW()"; + + String sql = String.format("", + tableInfo.getTableName(), columnScript, valuesScript, updateScript); + + SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); + return this.addInsertMappedStatement(mapperClass, modelClass, methodName, sqlSource, new NoKeyGenerator(), null, null); + } +} \ No newline at end of file diff --git a/src/main/java/com/project/base/config/MybatisPlusConfig.java b/src/main/java/com/project/base/config/MybatisPlusConfig.java new file mode 100644 index 0000000..f2218d6 --- /dev/null +++ b/src/main/java/com/project/base/config/MybatisPlusConfig.java @@ -0,0 +1,20 @@ +package com.project.base.config; + +import com.baomidou.mybatisplus.core.injector.AbstractMethod; +import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; +import com.baomidou.mybatisplus.core.metadata.TableInfo; +import org.springframework.context.annotation.Configuration; + +import java.util.List; + +@Configuration +public class MybatisPlusConfig extends DefaultSqlInjector { + + @Override + public List getMethodList(Class mapperClass, TableInfo tableInfo) { + List methodList = super.getMethodList(mapperClass, tableInfo); + methodList.add(new InsertBatchOnDuplicateKeyUpdate()); // 确保这里添加了你的自定义方法 + return methodList; + } + +} \ No newline at end of file diff --git a/src/main/java/com/project/base/mapper/BatchUpsertMapper.java b/src/main/java/com/project/base/mapper/BatchUpsertMapper.java new file mode 100644 index 0000000..e7e745f --- /dev/null +++ b/src/main/java/com/project/base/mapper/BatchUpsertMapper.java @@ -0,0 +1,12 @@ +package com.project.base.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import java.util.List; + +public interface BatchUpsertMapper extends BaseMapper { + /** + * 自定义全局批量 Upsert + */ + int batchUpsert(@Param("list") List list); +} \ No newline at end of file diff --git a/src/main/java/com/project/ding/controller/DepartmentController.java b/src/main/java/com/project/ding/controller/DepartmentController.java index 48fe01a..211e211 100644 --- a/src/main/java/com/project/ding/controller/DepartmentController.java +++ b/src/main/java/com/project/ding/controller/DepartmentController.java @@ -2,8 +2,7 @@ package com.project.ding.controller; import com.github.tingyugetc520.ali.dingtalk.api.DtService; -import com.github.tingyugetc520.ali.dingtalk.bean.department.DtDepart; -import com.github.tingyugetc520.ali.dingtalk.bean.user.DtUser; +import com.project.ding.domain.dto.DepartmentDTO; import com.project.ding.domain.dto.DingUserDTO; import com.project.ding.utils.DingUtil; import jakarta.servlet.http.HttpServletResponse; @@ -25,7 +24,7 @@ public class DepartmentController { private DtService dtService; @GetMapping("/test") public void test(HttpServletResponse response) throws Exception { - List list = dingUtil.getAllDepartment(); + List list = dingUtil.getAllDepartment(); List userList = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { diff --git a/src/main/java/com/project/ding/controller/SyncController.java b/src/main/java/com/project/ding/controller/SyncController.java new file mode 100644 index 0000000..7c7ea5c --- /dev/null +++ b/src/main/java/com/project/ding/controller/SyncController.java @@ -0,0 +1,25 @@ +package com.project.ding.controller; + + +import com.project.ding.utils.DingUserSyncUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/ding") +public class SyncController { + @Autowired + private DingUserSyncUtil dingUserSyncUtil; + + /** + * 手动触发同步接口 + * 强刷:/sync/all?force=true + */ + @GetMapping("/sync") + public String triggerSync(@RequestParam(defaultValue = "false") boolean force) { + return dingUserSyncUtil.triggerSync(force); + } +} diff --git a/src/main/java/com/project/ding/domain/dto/DepartmentDTO.java b/src/main/java/com/project/ding/domain/dto/DepartmentDTO.java index d58f4ab..ef09bc9 100644 --- a/src/main/java/com/project/ding/domain/dto/DepartmentDTO.java +++ b/src/main/java/com/project/ding/domain/dto/DepartmentDTO.java @@ -4,10 +4,18 @@ package com.project.ding.domain.dto; import com.project.base.domain.dto.BaseDTO; import lombok.Data; +import java.util.List; + @Data public class DepartmentDTO extends BaseDTO { private String name; private Long parentId; + private List childrenList; + + private Boolean leaf = Boolean.TRUE; + + private List deptIdPath; + } diff --git a/src/main/java/com/project/ding/domain/dto/DingUserDTO.java b/src/main/java/com/project/ding/domain/dto/DingUserDTO.java index b548454..e8d2685 100644 --- a/src/main/java/com/project/ding/domain/dto/DingUserDTO.java +++ b/src/main/java/com/project/ding/domain/dto/DingUserDTO.java @@ -64,4 +64,16 @@ public class DingUserDTO { @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") private Date hiredDate; + @JsonProperty("active") + private Boolean active; + + @JsonProperty("admin") + private Boolean admin; + + @JsonProperty("boss") + private Boolean boss; + + @JsonProperty("leader") + private Boolean leader; + } diff --git a/src/main/java/com/project/ding/domain/dto/UserDTO.java b/src/main/java/com/project/ding/domain/dto/UserDTO.java index 895ddb1..16979d7 100644 --- a/src/main/java/com/project/ding/domain/dto/UserDTO.java +++ b/src/main/java/com/project/ding/domain/dto/UserDTO.java @@ -32,6 +32,14 @@ public class UserDTO extends BaseDTO { @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") private Date hiredDate; + private Boolean active; + + private Boolean admin; + + private Boolean boss; + + private Boolean leader; + /** * 需要参与考试任务数 */ diff --git a/src/main/java/com/project/ding/domain/entity/DepartmentEntity.java b/src/main/java/com/project/ding/domain/entity/DepartmentEntity.java index 02364e2..39b9e63 100644 --- a/src/main/java/com/project/ding/domain/entity/DepartmentEntity.java +++ b/src/main/java/com/project/ding/domain/entity/DepartmentEntity.java @@ -1,7 +1,10 @@ package com.project.ding.domain.entity; +import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import com.project.base.domain.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -9,14 +12,20 @@ import jakarta.persistence.Index; import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; + +import java.util.List; @Data @Table(name = "evaluator_department" , indexes = {@Index(name = "Idx_parentId", columnList = "parent_id")}) @Entity -@TableName("evaluator_department") +@TableName(value = "evaluator_department" , autoResultMap = true) @EqualsAndHashCode(callSuper = true) public class DepartmentEntity extends BaseEntity { + @TableId(type = IdType.INPUT) + private Long id; @Column(name = "name" , columnDefinition="varchar(255) comment '部门名称'") private String name; @@ -24,4 +33,10 @@ public class DepartmentEntity extends BaseEntity { @TableField("parent_id") @Column(name = "parent_id" , columnDefinition="bigint(20) comment '父部门id'") private Long parentId; + + + @TableField(typeHandler = JacksonTypeHandler.class) + @Column(name = "dept_id_path", columnDefinition = "json comment '部门ID全路径'") + @JdbcTypeCode(SqlTypes.JSON) + private List deptIdPath; } diff --git a/src/main/java/com/project/ding/domain/entity/UserEntity.java b/src/main/java/com/project/ding/domain/entity/UserEntity.java index 7579615..ae5b829 100644 --- a/src/main/java/com/project/ding/domain/entity/UserEntity.java +++ b/src/main/java/com/project/ding/domain/entity/UserEntity.java @@ -1,6 +1,10 @@ package com.project.ding.domain.entity; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import com.project.base.domain.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -8,16 +12,22 @@ import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; import org.hibernate.annotations.Comment; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; import java.util.Date; +import java.util.List; @Data @Table(name = "evaluator_user" ) @Entity -@TableName("evaluator_user") +@TableName(value = "evaluator_user", autoResultMap = true) // 必须开启 autoResultMap 才能让 TypeHandler 生效 @EqualsAndHashCode(callSuper = true) public class UserEntity extends BaseEntity { + @TableId(type = IdType.INPUT) + private Long id; + @Column(name = "union_id" , columnDefinition="varchar(255) comment '企业架构内唯一标识'") private String unionId; @@ -39,7 +49,27 @@ public class UserEntity extends BaseEntity { @Column(name = "dept_id_str" , columnDefinition="varchar(2000) comment '部门id集合'") private String deptIdStr; + /** + * 存储为 JSON 数组: [1, 10, 101] + */ + @TableField(typeHandler = JacksonTypeHandler.class) + @Column(name = "dept_id_list", columnDefinition = "json comment '部门ID列表'") + @JdbcTypeCode(SqlTypes.JSON) + private List deptIdList; + @Column(name = "hired_date") @Comment("入职时间") private Date hiredDate; + + @Column(name = "active", columnDefinition = "tinyint(1) default 1 comment '是否激活钉钉: 1-已激活, 0-未激活'") + private Boolean active; + + @Column(name = "admin", columnDefinition = "tinyint(1) default 0 comment '是否为企业管理员: 1-是, 0-不是'") + private Boolean admin; + + @Column(name = "boss", columnDefinition = "tinyint(1) default 0 comment '是否为企业老板: 1-是, 0-不是'") + private Boolean boss; + + @Column(name = "leader", columnDefinition = "tinyint(1) default 0 comment '是否为部门主管: 1-是, 0-不是'") + private Boolean leader; } diff --git a/src/main/java/com/project/ding/domain/service/DepartmentBaseService.java b/src/main/java/com/project/ding/domain/service/DepartmentBaseService.java new file mode 100644 index 0000000..256ad5c --- /dev/null +++ b/src/main/java/com/project/ding/domain/service/DepartmentBaseService.java @@ -0,0 +1,8 @@ +package com.project.ding.domain.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.project.ding.domain.entity.DepartmentEntity; +import com.project.ding.domain.entity.UserEntity; + +public interface DepartmentBaseService extends IService { +} diff --git a/src/main/java/com/project/ding/domain/service/impl/DepartmentBaseServiceImpl.java b/src/main/java/com/project/ding/domain/service/impl/DepartmentBaseServiceImpl.java new file mode 100644 index 0000000..691eab0 --- /dev/null +++ b/src/main/java/com/project/ding/domain/service/impl/DepartmentBaseServiceImpl.java @@ -0,0 +1,11 @@ +package com.project.ding.domain.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.project.ding.domain.entity.DepartmentEntity; +import com.project.ding.domain.service.DepartmentBaseService; +import com.project.ding.mapper.DepartmentMapper; +import org.springframework.stereotype.Service; + +@Service +public class DepartmentBaseServiceImpl extends ServiceImpl implements DepartmentBaseService { +} diff --git a/src/main/java/com/project/ding/mapper/DepartmentMapper.java b/src/main/java/com/project/ding/mapper/DepartmentMapper.java index 4dffc03..d54a027 100644 --- a/src/main/java/com/project/ding/mapper/DepartmentMapper.java +++ b/src/main/java/com/project/ding/mapper/DepartmentMapper.java @@ -1,9 +1,11 @@ package com.project.ding.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.project.base.mapper.BatchUpsertMapper; import com.project.ding.domain.entity.DepartmentEntity; import org.apache.ibatis.annotations.Mapper; @Mapper -public interface DepartmentMapper extends BaseMapper { +public interface DepartmentMapper extends BaseMapper, BatchUpsertMapper { + } diff --git a/src/main/java/com/project/ding/mapper/UserMapper.java b/src/main/java/com/project/ding/mapper/UserMapper.java index b7757c1..3d29053 100644 --- a/src/main/java/com/project/ding/mapper/UserMapper.java +++ b/src/main/java/com/project/ding/mapper/UserMapper.java @@ -1,7 +1,8 @@ package com.project.ding.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.project.base.mapper.BatchUpsertMapper; import com.project.ding.domain.entity.UserEntity; -public interface UserMapper extends BaseMapper { +public interface UserMapper extends BaseMapper , BatchUpsertMapper { } diff --git a/src/main/java/com/project/ding/utils/DingUserSyncUtil.java b/src/main/java/com/project/ding/utils/DingUserSyncUtil.java index 34b46e1..cae104b 100644 --- a/src/main/java/com/project/ding/utils/DingUserSyncUtil.java +++ b/src/main/java/com/project/ding/utils/DingUserSyncUtil.java @@ -1,19 +1,24 @@ package com.project.ding.utils; +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.StrUtil; +import com.project.base.domain.utils.TreeUtils; +import com.project.ding.domain.dto.DepartmentDTO; import com.project.ding.domain.dto.UserDTO; +import com.project.ding.domain.entity.DepartmentEntity; import com.project.ding.domain.entity.SyncLogEntity; import com.project.ding.domain.entity.UserEntity; -import com.project.ding.domain.service.UserBaseService; +import com.project.ding.mapper.DepartmentMapper; import com.project.ding.mapper.SyncLogMapper; +import com.project.ding.mapper.UserMapper; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; -import java.util.Date; -import java.util.List; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; @@ -29,7 +34,10 @@ public class DingUserSyncUtil { private StringRedisTemplate redisTemplate; @Autowired - private UserBaseService userBaseService; + private UserMapper userMapper; + + @Autowired + private DepartmentMapper departmentMapper; @Autowired private DingUtil dingUtil; @@ -85,10 +93,44 @@ public class DingUserSyncUtil { // 开始同步 try { + List allDepartment = dingUtil.getAllDepartment(); + allDepartment.forEach(dto -> dto.setDeptIdPath(new ArrayList<>(Collections.singletonList(dto.getId())))); + // 转树 + List departmentDTOtreeList = TreeUtils.buildLongTree(allDepartment, DepartmentDTO::getId, DepartmentDTO::getParentId, (parentDTO, childrenList) -> { + parentDTO.setChildrenList(childrenList); + parentDTO.setLeaf(Boolean.FALSE); + childrenList.forEach(childDTO -> childDTO.getDeptIdPath().addAll(0, parentDTO.getDeptIdPath())); + }); + // 树转回列表 + List departmentDTOList = TreeUtils.tree2List(departmentDTOtreeList, DepartmentDTO::getChildrenList); + Map> depIdPathMap = new HashMap<>(); + departmentDTOList.forEach(dto -> depIdPathMap.put(dto.getId().toString() , dto.getDeptIdPath())); + + + List> departmentPartitions = ListUtil.partition(departmentDTOList, 300); + for (List batch : departmentPartitions) { + departmentMapper.batchUpsert(batch.stream() + .map(dto -> dto.toEntity(DepartmentEntity::new)) + .collect(Collectors.toList())); + } + List allUserDTOList = dingUtil.getAllUserDTO(); - userBaseService.saveOrUpdateBatch(allUserDTOList.stream() - .map(dto -> dto.toEntity(UserEntity::new)) - .collect(Collectors.toList()) , 300); + allUserDTOList.forEach(user -> { + Set depIdPathSet = new HashSet<>(); + if (StrUtil.isNotBlank(user.getDeptIdStr())) { + for (String idStr : user.getDeptIdStr().split(",")) { + depIdPathSet.addAll(depIdPathMap.get(idStr)); + } + } + user.setDeptIdList(depIdPathSet.stream().toList()); + }); + List> userPartitions = ListUtil.partition(allUserDTOList, 300); + for (List batch : userPartitions) { + userMapper.batchUpsert(batch.stream() + .map(dto -> dto.toEntity(UserEntity::new)) + .collect(Collectors.toList())); + } + syncLogEntity.setStatus(1); syncLogEntity.setEndTime(new Date()); syncLogMapper.updateById(syncLogEntity); diff --git a/src/main/java/com/project/ding/utils/DingUtil.java b/src/main/java/com/project/ding/utils/DingUtil.java index f4326ad..1fbb217 100644 --- a/src/main/java/com/project/ding/utils/DingUtil.java +++ b/src/main/java/com/project/ding/utils/DingUtil.java @@ -1,5 +1,6 @@ package com.project.ding.utils; +import cn.hutool.core.bean.BeanUtil; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.tingyugetc520.ali.dingtalk.api.DtService; @@ -7,6 +8,7 @@ import com.github.tingyugetc520.ali.dingtalk.bean.department.DtDepart; import com.google.gson.JsonObject; import com.jayway.jsonpath.JsonPath; +import com.project.ding.domain.dto.DepartmentDTO; import com.project.ding.domain.dto.DingUserDTO; import com.project.ding.domain.dto.UserDTO; import io.vavr.control.Try; @@ -14,7 +16,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; @Component @@ -24,12 +28,19 @@ public class DingUtil { - public List getAllDepartment() throws Exception { - return dtService.getDepartmentService().list(null , true); + public List getAllDepartment() throws Exception { + List list = dtService.getDepartmentService().list(null, true); + List res = new ArrayList<>(); + for (DtDepart dtDepart : list) { + DepartmentDTO departmentDTO = new DepartmentDTO(); + BeanUtil.copyProperties(dtDepart , departmentDTO); + res.add(departmentDTO); + } + return res; } public List getAllDingUserDTO() throws Exception { - List list = getAllDepartment(); + List list = getAllDepartment(); List userList = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { @@ -40,16 +51,34 @@ public class DingUtil { } public List getAllUserDTO() throws Exception { - List list = getAllDepartment(); + List list = getAllDepartment(); List userList = new ArrayList<>(); + for (int i = 0; i < list.size(); i++) { List userInDepartment = getUserIdInDepartment(list.get(i).getId()); userList.addAll(userInDepartment.stream() .map(UserDTO::fromDingUserDTO) .collect(Collectors.toList())); } - return userList; + return userList.stream() + .collect(Collectors.toMap( + UserDTO::getId, + u -> u, + this::mergeUser + )) + .values() + .stream() + .toList(); + } + + /** + * 定义合并规则:处理权限“或”逻辑 + */ + private UserDTO mergeUser(UserDTO u1, UserDTO u2) { + // 权限合并:只要其中一个是 true,结果就是 true + u1.setLeader(Boolean.logicalOr(Boolean.TRUE.equals(u1.getLeader()), Boolean.TRUE.equals(u2.getLeader()))); + return u1; } public List getUserIdInDepartment(Long id) throws Exception { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 414c3f3..e8f41f4 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,5 +1,6 @@ server: port: 7088 + spring: datasource: dynamic: @@ -8,8 +9,22 @@ spring: master: driverClassName: com.mysql.cj.jdbc.Driver password: Itc@123456 - url: jdbc:mysql://172.16.204.50:3306/proposal_workshop?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true + url: jdbc:mysql://172.16.204.50:3306/ai_evaluator?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true username: root + # Redis + data: + redis: + host: 172.16.204.50 + port: 6379 + password: 123456 + database: 3 + timeout: 5000ms + lettuce: + pool: + max-active: 8 + max-idle: 30 + max-wait: 10000 + min-idle: 10 jpa: hibernate: ddl-auto: update diff --git a/src/main/resources/static/favicon.ico b/src/main/resources/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..0cd33975b554d94cd9519b4da6531ca282bb4e82 GIT binary patch literal 15406 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