人员关联团队功能

This commit is contained in:
LHD_HY 2026-01-08 10:09:07 +08:00
parent eb0fb8eadc
commit 91f7c00913
5 changed files with 289 additions and 24 deletions

View File

@ -1,8 +1,12 @@
package com.bonus.common.core.domain.entity;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.constraints.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.bonus.common.annotation.Excel;
@ -105,6 +109,12 @@ public class SysUser extends BaseEntity
/**用户密钥*/
private String secret;
/** 临时字段接收数据库GROUP_CONCAT拼接的团队ID字符串如 "1,2,3" */
private String teamIdsStr;
/**团队ID列表通过teamIdsStr动态转换无独立成员变量*/
private List<Long> teamIds;
/** 角色名称 */
private String roleName;
@ -342,29 +352,87 @@ public class SysUser extends BaseEntity
this.roleName = roleName;
}
/**
* 获取团队ID列表核心改造从teamIdsStr动态转换兼容空值
* @return 团队ID列表空值返回空数组避免NullPointerException
*/
public List<Long> getTeamIds()
{
// 优先使用手动设置的teamIds兼容原有业务逻辑
if (this.teamIds != null) {
return this.teamIds;
}
// 空值处理teamIdsStr为空时返回空数组
if (StringUtils.isBlank(teamIdsStr)) {
return new ArrayList<>();
}
// 将逗号分隔的字符串转换为Long类型的List
return Arrays.stream(teamIdsStr.split(","))
.map(String::trim) // 去除空格兼容"1, 2,3"格式
.map(Long::valueOf) // 转换为Long类型
.collect(Collectors.toList());
}
/**
* 设置团队ID列表同时同步更新teamIdsStr保证数据一致性
* @param teamIds 团队ID列表
*/
public void setTeamIds(List<Long> teamIds)
{
this.teamIds = teamIds;
// 同步更新teamIdsStrList转逗号分隔的字符串
if (teamIds == null || teamIds.isEmpty()) {
this.teamIdsStr = "";
} else {
this.teamIdsStr = teamIds.stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
}
}
/**
* 获取数据库映射的团队ID字符串
* @return 逗号分隔的团队ID字符串
*/
public String getTeamIdsStr() {
return teamIdsStr;
}
/**
* 设置数据库映射的团队ID字符串
* @param teamIdsStr 逗号分隔的团队ID字符串
*/
public void setTeamIdsStr(String teamIdsStr) {
this.teamIdsStr = teamIdsStr;
// 清空手动设置的teamIds确保getTeamIds()优先使用转换后的值
this.teamIds = null;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("userId", getUserId())
.append("deptId", getDeptId())
.append("userName", getUserName())
.append("nickName", getNickName())
.append("email", getEmail())
.append("phonenumber", getPhonenumber())
.append("sex", getSex())
.append("avatar", getAvatar())
.append("password", getPassword())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("loginIp", getLoginIp())
.append("loginDate", getLoginDate())
.append("pwdUpdateDate", getPwdUpdateDate())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.append("dept", getDept())
.toString();
.append("userId", getUserId())
.append("deptId", getDeptId())
.append("userName", getUserName())
.append("nickName", getNickName())
.append("email", getEmail())
.append("phonenumber", getPhonenumber())
.append("sex", getSex())
.append("avatar", getAvatar())
.append("password", getPassword())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("loginIp", getLoginIp())
.append("loginDate", getLoginDate())
.append("pwdUpdateDate", getPwdUpdateDate())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.append("dept", getDept())
.append("teamIdsStr", getTeamIdsStr())
.append("teamIds", getTeamIds())
.toString();
}
}

View File

@ -0,0 +1,62 @@
package com.bonus.common.core.domain.entity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.io.Serializable;
/**
* 用户和团队关联表 sys_user_team_association
*
* @author bonus
*/
public class SysUserTeam implements Serializable
{
private static final long serialVersionUID = 1L;
/** 用户ID联合主键 */
private Long userId;
/** 团队ID联合主键 */
private Long teamId;
/** 空参构造方法 */
public SysUserTeam()
{
}
/** 含参构造方法:快速创建用户-团队关联对象 */
public SysUserTeam(Long userId, Long teamId)
{
this.userId = userId;
this.teamId = teamId;
}
public Long getUserId()
{
return userId;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public Long getTeamId()
{
return teamId;
}
public void setTeamId(Long teamId)
{
this.teamId = teamId;
}
/** 重写toString方法便于日志打印和调试 */
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("userId", getUserId())
.append("teamId", getTeamId())
.toString();
}
}

View File

@ -1,6 +1,8 @@
package com.bonus.system.mapper;
import java.util.List;
import com.bonus.common.core.domain.entity.SysUserTeam;
import org.apache.ibatis.annotations.Param;
import com.bonus.common.core.domain.entity.SysUser;
@ -126,4 +128,19 @@ public interface SysUserMapper
public SysUser checkEmailUnique(String email);
String getPassWord();
/**
* 批量插入用户-团队关联
*/
int batchUserTeam(List<SysUserTeam> list);
/**
* 根据用户ID查询关联的团队ID列表
*/
List<Long> selectTeamIdsByUserId(Long userId);
/**
* 批量删除用户-团队关联
*/
int batchDeleteUserTeam(@Param("userId") Long userId, @Param("teamIds") List<Long> teamIds);
}

View File

@ -1,10 +1,13 @@
package com.bonus.system.service.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Validator;
import com.bonus.common.core.domain.entity.SysUserTeam;
import com.bonus.common.utils.DesensitizedUtil;
import com.bonus.common.utils.GenerateUtil;
import com.bonus.common.utils.encryption.Sm4Utils;
@ -254,6 +257,8 @@ public class SysUserServiceImpl implements ISysUserService {
insertUserPost(user);
// 新增用户与角色管理
insertUserRole(user);
// 批量插入用户-团队关联
insertUserTeam(user);
return rows;
}
@ -286,6 +291,8 @@ public class SysUserServiceImpl implements ISysUserService {
userPostMapper.deleteUserPostByUserId(userId);
// 新增用户与岗位管理
insertUserPost(user);
// 用户-团队关联
syncUserTeam(user);
return userMapper.updateUser(user);
}
@ -521,4 +528,80 @@ public class SysUserServiceImpl implements ISysUserService {
public String getPassWord() {
return userMapper.getPassWord();
}
/**
* 新增用户-团队关联信息
* @param user 用户对象
*/
public void insertUserTeam(SysUser user) {
if (user == null || user.getUserId() == null) {
return;
}
List<Long> teamIds = user.getTeamIds();
// 空值校验
if (CollectionUtils.isEmpty(teamIds)) {
return;
}
// 批量插入用户-团队关联
List<SysUserTeam> list = new ArrayList<>(teamIds.size());
for (Long teamId : teamIds) {
// 过滤空值
if (teamId == null) {
continue;
}
SysUserTeam ut = new SysUserTeam();
ut.setUserId(user.getUserId());
ut.setTeamId(teamId);
list.add(ut);
}
if (!list.isEmpty()) {
userMapper.batchUserTeam(list);
}
}
/**
* 同步用户-团队关联
* @param user 用户对象
*/
public void syncUserTeam(SysUser user) {
if (user == null || user.getUserId() == null) {
return;
}
Long userId = user.getUserId();
// 1. 查询该用户当前已关联的团队ID列表直接初始化时完成空值处理避免后续重新赋值
List<Long> existTeamIds = userMapper.selectTeamIdsByUserId(userId) == null
? Collections.emptyList()
: userMapper.selectTeamIdsByUserId(userId);
// 2. 前端传递的新团队ID列表直接初始化时完成空值处理避免后续重新赋值
List<Long> newTeamIds = user.getTeamIds() == null
? Collections.emptyList()
: user.getTeamIds();
// 3. 需要新增的团队新选 - 现有
List<Long> addTeamIds = newTeamIds.stream()
.filter(teamId -> teamId != null && !existTeamIds.contains(teamId))
.collect(Collectors.toList());
// 4. 需要移除的团队现有 - 新选
List<Long> removeTeamIds = existTeamIds.stream()
.filter(teamId -> !newTeamIds.contains(teamId))
.collect(Collectors.toList());
// 5. 执行新增团队关联
if (!addTeamIds.isEmpty()) {
List<SysUserTeam> addList = new ArrayList<>(addTeamIds.size());
for (Long teamId : addTeamIds) {
SysUserTeam ut = new SysUserTeam();
ut.setUserId(userId);
ut.setTeamId(teamId);
addList.add(ut);
}
userMapper.batchUserTeam(addList);
}
// 6. 执行移除团队关联
if (!removeTeamIds.isEmpty()) {
userMapper.batchDeleteUserTeam(userId, removeTeamIds);
}
}
}

View File

@ -25,6 +25,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
<result property="secret" column="secret" />
<result property="teamIdsStr" column="teamIds" />
<association property="dept" javaType="SysDept" resultMap="deptResult" />
<collection property="roles" javaType="java.util.List" resultMap="RoleResult" />
</resultMap>
@ -58,14 +59,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
left join sys_role r on r.role_id = ur.role_id
</sql>
<select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
<select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex,
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name,
d.leader ,dksr.role_id,dksr.role_name
u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name,
d.leader ,dksr.role_id,dksr.role_name,
GROUP_CONCAT(t.team_id) as teamIds
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
left join sys_user_role dksur on u.user_id = dksur.user_id
left join sys_role dksr on dksr.role_id = dksur.role_id
left join sys_user_team_association t on u.user_id = t.user_id
where u.del_flag = '0'
<if test="userId != null and userId != 0">
AND u.user_id = #{userId}
@ -91,6 +94,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="deptId != null and deptId != 0">
AND (u.dept_id = #{deptId} OR u.dept_id IN ( SELECT t.dept_id FROM sys_dept t WHERE find_in_set(#{deptId}, ancestors) ))
</if>
GROUP BY u.user_id
<!-- 数据范围过滤 -->
${params.dataScope}
</select>
@ -238,4 +242,35 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</foreach>
</delete>
<sql id="selectUserTeamVo">
select user_id, team_id from sys_user_team_association
</sql>
<!-- 批量插入用户-团队关联 -->
<insert id="batchUserTeam">
INSERT INTO sys_user_team_association (user_id, team_id)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.userId}, #{item.teamId})
</foreach>
</insert>
<!-- 根据用户ID查询关联的团队ID列表 -->
<select id="selectTeamIdsByUserId" resultType="java.lang.Long">
SELECT team_id
FROM sys_user_team_association
WHERE user_id = #{userId}
</select>
<!-- 批量删除用户-团队关联 -->
<delete id="batchDeleteUserTeam">
DELETE FROM sys_user_team_association
WHERE user_id = #{userId}
AND team_id IN
<foreach collection="teamIds" item="teamId" open="(" separator="," close=")">
#{teamId}
</foreach>
</delete>
</mapper>