增加团队管理增删改差

This commit is contained in:
dengqichen 2025-10-28 17:56:10 +08:00
parent 24eab092da
commit edf4e9f998
26 changed files with 879 additions and 2 deletions

View File

@ -0,0 +1,34 @@
package com.qqchen.deploy.backend.deploy.api;
import com.qqchen.deploy.backend.deploy.dto.TeamDTO;
import com.qqchen.deploy.backend.deploy.entity.Team;
import com.qqchen.deploy.backend.deploy.query.TeamQuery;
import com.qqchen.deploy.backend.deploy.service.ITeamService;
import com.qqchen.deploy.backend.framework.controller.BaseController;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 团队API控制器
*/
@Slf4j
@RestController
@RequestMapping("/api/v1/teams")
@Tag(name = "团队管理", description = "团队的增删改查接口")
public class TeamApiController extends BaseController<Team, TeamDTO, Long, TeamQuery> {
@Resource
private ITeamService teamService;
@Override
protected void exportData(HttpServletResponse response, List<TeamDTO> data) {
// TODO: 实现导出功能
}
}

View File

@ -0,0 +1,34 @@
package com.qqchen.deploy.backend.deploy.api;
import com.qqchen.deploy.backend.deploy.dto.TeamApplicationDTO;
import com.qqchen.deploy.backend.deploy.entity.TeamApplication;
import com.qqchen.deploy.backend.deploy.query.TeamApplicationQuery;
import com.qqchen.deploy.backend.deploy.service.ITeamApplicationService;
import com.qqchen.deploy.backend.framework.controller.BaseController;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 团队应用关联API控制器
*/
@Slf4j
@RestController
@RequestMapping("/api/v1/team-applications")
@Tag(name = "团队应用关联管理", description = "团队应用关联的增删改查接口")
public class TeamApplicationApiController extends BaseController<TeamApplication, TeamApplicationDTO, Long, TeamApplicationQuery> {
@Resource
private ITeamApplicationService teamApplicationService;
@Override
protected void exportData(HttpServletResponse response, List<TeamApplicationDTO> data) {
// TODO: 实现导出功能
}
}

View File

@ -0,0 +1,34 @@
package com.qqchen.deploy.backend.deploy.api;
import com.qqchen.deploy.backend.deploy.dto.TeamMemberDTO;
import com.qqchen.deploy.backend.deploy.entity.TeamMember;
import com.qqchen.deploy.backend.deploy.query.TeamMemberQuery;
import com.qqchen.deploy.backend.deploy.service.ITeamMemberService;
import com.qqchen.deploy.backend.framework.controller.BaseController;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 团队成员API控制器
*/
@Slf4j
@RestController
@RequestMapping("/api/v1/team-members")
@Tag(name = "团队成员管理", description = "团队成员的增删改查接口")
public class TeamMemberApiController extends BaseController<TeamMember, TeamMemberDTO, Long, TeamMemberQuery> {
@Resource
private ITeamMemberService teamMemberService;
@Override
protected void exportData(HttpServletResponse response, List<TeamMemberDTO> data) {
// TODO: 实现导出功能
}
}

View File

@ -0,0 +1,11 @@
package com.qqchen.deploy.backend.deploy.converter;
import com.qqchen.deploy.backend.deploy.dto.TeamApplicationDTO;
import com.qqchen.deploy.backend.deploy.entity.TeamApplication;
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
import org.mapstruct.Mapper;
@Mapper(config = BaseConverter.class)
public interface TeamApplicationConverter extends BaseConverter<TeamApplication, TeamApplicationDTO> {
}

View File

@ -0,0 +1,11 @@
package com.qqchen.deploy.backend.deploy.converter;
import com.qqchen.deploy.backend.deploy.dto.TeamDTO;
import com.qqchen.deploy.backend.deploy.entity.Team;
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
import org.mapstruct.Mapper;
@Mapper(config = BaseConverter.class)
public interface TeamConverter extends BaseConverter<Team, TeamDTO> {
}

View File

@ -0,0 +1,11 @@
package com.qqchen.deploy.backend.deploy.converter;
import com.qqchen.deploy.backend.deploy.dto.TeamMemberDTO;
import com.qqchen.deploy.backend.deploy.entity.TeamMember;
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
import org.mapstruct.Mapper;
@Mapper(config = BaseConverter.class)
public interface TeamMemberConverter extends BaseConverter<TeamMember, TeamMemberDTO> {
}

View File

@ -0,0 +1,31 @@
package com.qqchen.deploy.backend.deploy.dto;
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "团队应用关联信息")
public class TeamApplicationDTO extends BaseDTO {
@Schema(description = "团队ID", required = true)
@NotNull(message = "团队ID不能为空")
private Long teamId;
@Schema(description = "应用ID", required = true)
@NotNull(message = "应用ID不能为空")
private Long applicationId;
@Schema(description = "团队名称")
private String teamName;
@Schema(description = "应用名称")
private String applicationName;
@Schema(description = "应用编码")
private String applicationCode;
}

View File

@ -0,0 +1,46 @@
package com.qqchen.deploy.backend.deploy.dto;
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "团队信息")
public class TeamDTO extends BaseDTO {
@Schema(description = "团队编码", example = "PLATFORM_TEAM")
@NotBlank(message = "团队编码不能为空")
private String teamCode;
@Schema(description = "团队名称", example = "平台研发团队")
@NotBlank(message = "团队名称不能为空")
private String teamName;
@Schema(description = "团队描述")
private String description;
@Schema(description = "团队负责人ID")
private Long ownerId;
@Schema(description = "团队负责人姓名")
private String ownerName;
@Schema(description = "是否启用")
@NotNull(message = "启用状态不能为空")
private Boolean enabled;
@Schema(description = "排序号")
@NotNull(message = "排序号不能为空")
private Integer sort;
@Schema(description = "成员数量")
private Long memberCount;
@Schema(description = "应用数量")
private Long applicationCount;
}

View File

@ -0,0 +1,38 @@
package com.qqchen.deploy.backend.deploy.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "团队成员信息")
public class TeamMemberDTO extends BaseDTO {
@Schema(description = "团队ID", required = true)
@NotNull(message = "团队ID不能为空")
private Long teamId;
@Schema(description = "用户ID", required = true)
@NotNull(message = "用户ID不能为空")
private Long userId;
@Schema(description = "用户名")
private String userName;
@Schema(description = "团队角色", example = "开发")
private String roleInTeam;
@Schema(description = "加入时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime joinTime;
@Schema(description = "团队名称")
private String teamName;
}

View File

@ -0,0 +1,39 @@
package com.qqchen.deploy.backend.deploy.entity;
import com.qqchen.deploy.backend.framework.domain.Entity;
import jakarta.persistence.Column;
import jakarta.persistence.Table;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 团队实体
*/
@Data
@EqualsAndHashCode(callSuper = true)
@jakarta.persistence.Entity
@Table(name = "deploy_team")
public class Team extends Entity<Long> {
@Column(name = "team_code", nullable = false, length = 50)
private String teamCode;
@Column(name = "team_name", nullable = false, length = 100)
private String teamName;
@Column(name = "description", length = 500)
private String description;
@Column(name = "owner_id")
private Long ownerId;
@Column(name = "owner_name", length = 50)
private String ownerName;
@Column(name = "enabled", nullable = false)
private Boolean enabled = true;
@Column(name = "sort", nullable = false)
private Integer sort = 0;
}

View File

@ -0,0 +1,24 @@
package com.qqchen.deploy.backend.deploy.entity;
import com.qqchen.deploy.backend.framework.domain.Entity;
import jakarta.persistence.Column;
import jakarta.persistence.Table;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 团队应用关联实体
*/
@Data
@EqualsAndHashCode(callSuper = true)
@jakarta.persistence.Entity
@Table(name = "deploy_team_application")
public class TeamApplication extends Entity<Long> {
@Column(name = "team_id", nullable = false)
private Long teamId;
@Column(name = "application_id", nullable = false)
private Long applicationId;
}

View File

@ -0,0 +1,35 @@
package com.qqchen.deploy.backend.deploy.entity;
import com.qqchen.deploy.backend.framework.domain.Entity;
import jakarta.persistence.Column;
import jakarta.persistence.Table;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* 团队成员实体
*/
@Data
@EqualsAndHashCode(callSuper = true)
@jakarta.persistence.Entity
@Table(name = "deploy_team_member")
public class TeamMember extends Entity<Long> {
@Column(name = "team_id", nullable = false)
private Long teamId;
@Column(name = "user_id", nullable = false)
private Long userId;
@Column(name = "user_name", length = 50)
private String userName;
@Column(name = "role_in_team", length = 50)
private String roleInTeam;
@Column(name = "join_time")
private LocalDateTime joinTime;
}

View File

@ -0,0 +1,25 @@
package com.qqchen.deploy.backend.deploy.query;
import com.qqchen.deploy.backend.framework.annotation.QueryField;
import com.qqchen.deploy.backend.framework.query.BaseQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 团队应用关联查询条件
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "团队应用关联查询条件")
public class TeamApplicationQuery extends BaseQuery {
@QueryField(field = "teamId")
@Schema(description = "团队ID")
private Long teamId;
@QueryField(field = "applicationId")
@Schema(description = "应用ID")
private Long applicationId;
}

View File

@ -0,0 +1,34 @@
package com.qqchen.deploy.backend.deploy.query;
import com.qqchen.deploy.backend.framework.annotation.QueryField;
import com.qqchen.deploy.backend.framework.enums.QueryType;
import com.qqchen.deploy.backend.framework.query.BaseQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 团队成员查询条件
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "团队成员查询条件")
public class TeamMemberQuery extends BaseQuery {
@QueryField(field = "teamId")
@Schema(description = "团队ID")
private Long teamId;
@QueryField(field = "userId")
@Schema(description = "用户ID")
private Long userId;
@QueryField(field = "userName", type = QueryType.LIKE)
@Schema(description = "用户名(模糊查询)")
private String userName;
@QueryField(field = "roleInTeam", type = QueryType.LIKE)
@Schema(description = "团队角色(模糊查询)")
private String roleInTeam;
}

View File

@ -0,0 +1,34 @@
package com.qqchen.deploy.backend.deploy.query;
import com.qqchen.deploy.backend.framework.annotation.QueryField;
import com.qqchen.deploy.backend.framework.enums.QueryType;
import com.qqchen.deploy.backend.framework.query.BaseQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 团队查询条件
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "团队查询条件")
public class TeamQuery extends BaseQuery {
@QueryField(field = "teamName", type = QueryType.LIKE)
@Schema(description = "团队名称(模糊查询)")
private String teamName;
@QueryField(field = "teamCode", type = QueryType.LIKE)
@Schema(description = "团队编码(模糊查询)")
private String teamCode;
@QueryField(field = "enabled")
@Schema(description = "是否启用")
private Boolean enabled;
@QueryField(field = "ownerId")
@Schema(description = "负责人ID")
private Long ownerId;
}

View File

@ -0,0 +1,32 @@
package com.qqchen.deploy.backend.deploy.repository;
import com.qqchen.deploy.backend.deploy.entity.TeamApplication;
import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface ITeamApplicationRepository extends IBaseRepository<TeamApplication, Long> {
/**
* 统计团队关联的应用数量
*/
Long countByTeamIdAndDeletedFalse(Long teamId);
/**
* 统计应用被哪些团队关联
*/
Long countByApplicationIdAndDeletedFalse(Long applicationId);
/**
* 检查团队是否已关联该应用
*/
boolean existsByTeamIdAndApplicationIdAndDeletedFalse(Long teamId, Long applicationId);
/**
* 根据团队ID和应用ID查询
*/
Optional<TeamApplication> findByTeamIdAndApplicationIdAndDeletedFalse(Long teamId, Long applicationId);
}

View File

@ -0,0 +1,27 @@
package com.qqchen.deploy.backend.deploy.repository;
import com.qqchen.deploy.backend.deploy.entity.TeamMember;
import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface ITeamMemberRepository extends IBaseRepository<TeamMember, Long> {
/**
* 统计团队成员数量
*/
Long countByTeamIdAndDeletedFalse(Long teamId);
/**
* 检查成员是否已加入团队
*/
boolean existsByTeamIdAndUserIdAndDeletedFalse(Long teamId, Long userId);
/**
* 根据团队ID和用户ID查询
*/
Optional<TeamMember> findByTeamIdAndUserIdAndDeletedFalse(Long teamId, Long userId);
}

View File

@ -0,0 +1,22 @@
package com.qqchen.deploy.backend.deploy.repository;
import com.qqchen.deploy.backend.deploy.entity.Team;
import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface ITeamRepository extends IBaseRepository<Team, Long> {
/**
* 根据团队编码查询忽略已删除
*/
Optional<Team> findByTeamCodeAndDeletedFalse(String teamCode);
/**
* 检查团队编码是否存在
*/
boolean existsByTeamCodeAndDeletedFalse(String teamCode);
}

View File

@ -0,0 +1,10 @@
package com.qqchen.deploy.backend.deploy.service;
import com.qqchen.deploy.backend.deploy.dto.TeamApplicationDTO;
import com.qqchen.deploy.backend.deploy.entity.TeamApplication;
import com.qqchen.deploy.backend.deploy.query.TeamApplicationQuery;
import com.qqchen.deploy.backend.framework.service.IBaseService;
public interface ITeamApplicationService extends IBaseService<TeamApplication, TeamApplicationDTO, TeamApplicationQuery, Long> {
}

View File

@ -0,0 +1,10 @@
package com.qqchen.deploy.backend.deploy.service;
import com.qqchen.deploy.backend.deploy.dto.TeamMemberDTO;
import com.qqchen.deploy.backend.deploy.entity.TeamMember;
import com.qqchen.deploy.backend.deploy.query.TeamMemberQuery;
import com.qqchen.deploy.backend.framework.service.IBaseService;
public interface ITeamMemberService extends IBaseService<TeamMember, TeamMemberDTO, TeamMemberQuery, Long> {
}

View File

@ -0,0 +1,10 @@
package com.qqchen.deploy.backend.deploy.service;
import com.qqchen.deploy.backend.deploy.dto.TeamDTO;
import com.qqchen.deploy.backend.deploy.entity.Team;
import com.qqchen.deploy.backend.deploy.query.TeamQuery;
import com.qqchen.deploy.backend.framework.service.IBaseService;
public interface ITeamService extends IBaseService<Team, TeamDTO, TeamQuery, Long> {
}

View File

@ -0,0 +1,74 @@
package com.qqchen.deploy.backend.deploy.service.impl;
import com.qqchen.deploy.backend.deploy.converter.TeamApplicationConverter;
import com.qqchen.deploy.backend.deploy.dto.TeamApplicationDTO;
import com.qqchen.deploy.backend.deploy.entity.Application;
import com.qqchen.deploy.backend.deploy.entity.Team;
import com.qqchen.deploy.backend.deploy.entity.TeamApplication;
import com.qqchen.deploy.backend.deploy.query.TeamApplicationQuery;
import com.qqchen.deploy.backend.deploy.repository.IApplicationRepository;
import com.qqchen.deploy.backend.deploy.repository.ITeamApplicationRepository;
import com.qqchen.deploy.backend.deploy.repository.ITeamRepository;
import com.qqchen.deploy.backend.deploy.service.ITeamApplicationService;
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@Slf4j
@Service
public class TeamApplicationServiceImpl extends BaseServiceImpl<TeamApplication, TeamApplicationDTO, TeamApplicationQuery, Long>
implements ITeamApplicationService {
@Resource
private ITeamApplicationRepository teamApplicationRepository;
@Resource
private ITeamRepository teamRepository;
@Resource
private IApplicationRepository applicationRepository;
@Resource
private TeamApplicationConverter teamApplicationConverter;
@Override
@Transactional
public TeamApplicationDTO create(TeamApplicationDTO dto) {
// 检查是否已关联
if (teamApplicationRepository.existsByTeamIdAndApplicationIdAndDeletedFalse(dto.getTeamId(), dto.getApplicationId())) {
throw new RuntimeException("该应用已关联到此团队");
}
return super.create(dto);
}
@Override
public Page<TeamApplicationDTO> page(TeamApplicationQuery query) {
Page<TeamApplicationDTO> page = super.page(query);
// 填充团队名称和应用信息
List<TeamApplicationDTO> content = page.getContent().stream()
.peek(teamApp -> {
Optional<Team> teamOptional = teamRepository.findById(teamApp.getTeamId());
teamOptional.ifPresent(team -> teamApp.setTeamName(team.getTeamName()));
Optional<Application> appOptional = applicationRepository.findById(teamApp.getApplicationId());
appOptional.ifPresent(app -> {
teamApp.setApplicationName(app.getAppName());
teamApp.setApplicationCode(app.getAppCode());
});
})
.collect(Collectors.toList());
return new PageImpl<>(content, page.getPageable(), page.getTotalElements());
}
}

View File

@ -0,0 +1,79 @@
package com.qqchen.deploy.backend.deploy.service.impl;
import com.qqchen.deploy.backend.deploy.converter.TeamMemberConverter;
import com.qqchen.deploy.backend.deploy.dto.TeamMemberDTO;
import com.qqchen.deploy.backend.deploy.entity.Team;
import com.qqchen.deploy.backend.deploy.entity.TeamMember;
import com.qqchen.deploy.backend.deploy.query.TeamMemberQuery;
import com.qqchen.deploy.backend.deploy.repository.ITeamMemberRepository;
import com.qqchen.deploy.backend.deploy.repository.ITeamRepository;
import com.qqchen.deploy.backend.deploy.service.ITeamMemberService;
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
import com.qqchen.deploy.backend.system.entity.User;
import com.qqchen.deploy.backend.system.repository.IUserRepository;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@Slf4j
@Service
public class TeamMemberServiceImpl extends BaseServiceImpl<TeamMember, TeamMemberDTO, TeamMemberQuery, Long>
implements ITeamMemberService {
@Resource
private ITeamMemberRepository teamMemberRepository;
@Resource
private ITeamRepository teamRepository;
@Resource
private IUserRepository userRepository;
@Resource
private TeamMemberConverter teamMemberConverter;
@Override
@Transactional
public TeamMemberDTO create(TeamMemberDTO dto) {
// 检查成员是否已加入团队
if (teamMemberRepository.existsByTeamIdAndUserIdAndDeletedFalse(dto.getTeamId(), dto.getUserId())) {
throw new RuntimeException("该用户已是团队成员");
}
// 自动填充用户名和加入时间
if (dto.getUserName() == null && dto.getUserId() != null) {
Optional<User> userOptional = userRepository.findById(dto.getUserId());
userOptional.ifPresent(user -> dto.setUserName(user.getUsername()));
}
if (dto.getJoinTime() == null) {
dto.setJoinTime(LocalDateTime.now());
}
return super.create(dto);
}
@Override
public Page<TeamMemberDTO> page(TeamMemberQuery query) {
Page<TeamMemberDTO> page = super.page(query);
// 填充团队名称
List<TeamMemberDTO> content = page.getContent().stream()
.peek(member -> {
Optional<Team> teamOptional = teamRepository.findById(member.getTeamId());
teamOptional.ifPresent(team -> member.setTeamName(team.getTeamName()));
})
.collect(Collectors.toList());
return new PageImpl<>(content, page.getPageable(), page.getTotalElements());
}
}

View File

@ -0,0 +1,85 @@
package com.qqchen.deploy.backend.deploy.service.impl;
import com.qqchen.deploy.backend.deploy.converter.TeamConverter;
import com.qqchen.deploy.backend.deploy.dto.TeamDTO;
import com.qqchen.deploy.backend.deploy.entity.Team;
import com.qqchen.deploy.backend.deploy.query.TeamQuery;
import com.qqchen.deploy.backend.deploy.repository.ITeamApplicationRepository;
import com.qqchen.deploy.backend.deploy.repository.ITeamMemberRepository;
import com.qqchen.deploy.backend.deploy.repository.ITeamRepository;
import com.qqchen.deploy.backend.deploy.service.ITeamService;
import com.qqchen.deploy.backend.framework.exception.BusinessException;
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
public class TeamServiceImpl extends BaseServiceImpl<Team, TeamDTO, TeamQuery, Long>
implements ITeamService {
@Resource
private ITeamRepository teamRepository;
@Resource
private ITeamMemberRepository teamMemberRepository;
@Resource
private ITeamApplicationRepository teamApplicationRepository;
@Resource
private TeamConverter teamConverter;
@Override
@Transactional
public TeamDTO create(TeamDTO dto) {
// 检查编码唯一性
if (teamRepository.existsByTeamCodeAndDeletedFalse(dto.getTeamCode())) {
throw new RuntimeException("团队编码已存在: " + dto.getTeamCode());
}
return super.create(dto);
}
@Override
@Transactional
public void delete(Long id) {
// 检查是否有成员
Long memberCount = teamMemberRepository.countByTeamIdAndDeletedFalse(id);
if (memberCount > 0) {
throw new RuntimeException("该团队下存在成员,无法删除");
}
// 检查是否有关联应用
Long applicationCount = teamApplicationRepository.countByTeamIdAndDeletedFalse(id);
if (applicationCount > 0) {
throw new RuntimeException("该团队下存在关联应用,无法删除");
}
super.delete(id);
}
@Override
public Page<TeamDTO> page(TeamQuery query) {
Page<TeamDTO> page = super.page(query);
// 统计每个团队的成员数量和应用数量
List<TeamDTO> content = page.getContent().stream()
.peek(team -> {
Long memberCount = teamMemberRepository.countByTeamIdAndDeletedFalse(team.getId());
Long applicationCount = teamApplicationRepository.countByTeamIdAndDeletedFalse(team.getId());
team.setMemberCount(memberCount);
team.setApplicationCount(applicationCount);
})
.collect(Collectors.toList());
return new PageImpl<>(content, page.getPageable(), page.getTotalElements());
}
}

View File

@ -64,8 +64,8 @@ VALUES
-- 运维管理 -- 运维管理
(200, '运维管理', '/deploy', 'Layout', 'DeploymentUnitOutlined', 1, NULL, 2, FALSE, TRUE, 'system', '2024-01-01 00:00:00', 0, FALSE), (200, '运维管理', '/deploy', 'Layout', 'DeploymentUnitOutlined', 1, NULL, 2, FALSE, TRUE, 'system', '2024-01-01 00:00:00', 0, FALSE),
-- 项目组管理 -- 团队管理
(201, '项目组管理', '/deploy/project-group', '/src/pages/Deploy/ProjectGroup/List/index', 'ProjectOutlined', 2, 200, 1, FALSE, TRUE, 'system', '2024-01-01 00:00:00', 0, FALSE), (201, '团队管理', '/deploy/teams', '/src/pages/Deploy/Team/List/index', 'TeamOutlined', 2, 200, 1, FALSE, TRUE, 'system', '2024-01-01 00:00:00', 0, FALSE),
-- 应用管理 -- 应用管理
(202, '应用管理', '/deploy/applications', '/src/pages/Deploy/Application/List/index', 'AppstoreOutlined', 2, 200, 2, FALSE, TRUE, 'system', '2024-01-01 00:00:00', 0, FALSE), (202, '应用管理', '/deploy/applications', '/src/pages/Deploy/Application/List/index', 'AppstoreOutlined', 2, 200, 2, FALSE, TRUE, 'system', '2024-01-01 00:00:00', 0, FALSE),
@ -853,3 +853,23 @@ VALUES
('数据采集', 'DATA_COLLECTION', '用于数据采集的表单', 'DatabaseOutlined', 2, 1, 'system', NOW(), 'system', NOW(), 0, 0), ('数据采集', 'DATA_COLLECTION', '用于数据采集的表单', 'DatabaseOutlined', 2, 1, 'system', NOW(), 'system', NOW(), 0, 0),
('问卷调查', 'SURVEY', '用于问卷调查的表单', 'FormOutlined', 3, 1, 'system', NOW(), 'system', NOW(), 0, 0), ('问卷调查', 'SURVEY', '用于问卷调查的表单', 'FormOutlined', 3, 1, 'system', NOW(), 'system', NOW(), 0, 0),
('其他', 'OTHER', '其他类型的表单', 'FileOutlined', 99, 1, 'system', NOW(), 'system', NOW(), 0, 0); ('其他', 'OTHER', '其他类型的表单', 'FileOutlined', 99, 1, 'system', NOW(), 'system', NOW(), 0, 0);
-- --------------------------------------------------------------------------------------
-- 初始化团队管理数据
-- --------------------------------------------------------------------------------------
-- 初始化团队数据
INSERT INTO deploy_team (id, team_code, team_name, description, owner_id, owner_name, enabled, sort, create_by, create_time, update_by, update_time, version, deleted)
VALUES
(1, 'PLATFORM_TEAM', '平台研发团队', '负责基础平台和框架的开发维护', 1, '超级管理员', 1, 1, 'admin', NOW(), 'admin', NOW(), 1, 0),
(2, 'DEVOPS_TEAM', 'DevOps团队', '负责CI/CD和运维自动化', 4, '运维经理', 1, 2, 'admin', NOW(), 'admin', NOW(), 1, 0);
-- 初始化团队成员数据
INSERT INTO deploy_team_member (team_id, user_id, user_name, role_in_team, join_time, create_by, create_time, update_by, update_time, version, deleted)
VALUES
-- 平台研发团队成员
(1, 1, 'admin', '负责人', NOW(), 'admin', NOW(), 'admin', NOW(), 1, 0),
(1, 3, 'dev_manager', '开发', NOW(), 'admin', NOW(), 'admin', NOW(), 1, 0),
-- DevOps团队成员
(2, 4, 'ops_manager', '负责人', NOW(), 'admin', NOW(), 'admin', NOW(), 1, 0),
(2, 2, 'it_manager', '运维', NOW(), 'admin', NOW(), 'admin', NOW(), 1, 0);

View File

@ -755,6 +755,73 @@ CREATE TABLE deploy_environment
-- 索引 -- 索引
UNIQUE INDEX uk_env_code (env_code) COMMENT '环境编码唯一' UNIQUE INDEX uk_env_code (env_code) COMMENT '环境编码唯一'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='环境表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='环境表';
-- 团队表
CREATE TABLE deploy_team
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(100) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间',
update_by VARCHAR(100) NULL COMMENT '更新人',
update_time DATETIME(6) NULL COMMENT '更新时间',
version INT NOT NULL DEFAULT 1 COMMENT '版本号',
deleted BIT NOT NULL DEFAULT 0 COMMENT '是否删除',
team_code VARCHAR(50) NOT NULL COMMENT '团队编码',
team_name VARCHAR(100) NOT NULL COMMENT '团队名称',
description VARCHAR(500) NULL COMMENT '团队描述',
owner_id BIGINT NULL COMMENT '团队负责人用户ID',
owner_name VARCHAR(50) NULL COMMENT '团队负责人姓名(冗余)',
enabled BIT NOT NULL DEFAULT 1 COMMENT '是否启用',
sort INT NOT NULL DEFAULT 0 COMMENT '排序号',
UNIQUE INDEX uk_team_code (team_code),
INDEX idx_owner (owner_id),
CONSTRAINT fk_team_owner FOREIGN KEY (owner_id) REFERENCES sys_user(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='团队表';
-- 团队成员表
CREATE TABLE deploy_team_member
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(100) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间',
update_by VARCHAR(100) NULL COMMENT '更新人',
update_time DATETIME(6) NULL COMMENT '更新时间',
version INT NOT NULL DEFAULT 1 COMMENT '版本号',
deleted BIT NOT NULL DEFAULT 0 COMMENT '是否删除',
team_id BIGINT NOT NULL COMMENT '团队ID',
user_id BIGINT NOT NULL COMMENT '用户ID',
user_name VARCHAR(50) NULL COMMENT '用户名(冗余)',
role_in_team VARCHAR(50) NULL COMMENT '团队角色(如:开发、测试、运维、负责人)',
join_time DATETIME(6) NULL COMMENT '加入时间',
UNIQUE INDEX uk_team_user (team_id, user_id),
INDEX idx_user (user_id),
CONSTRAINT fk_team_member_team FOREIGN KEY (team_id) REFERENCES deploy_team(id),
CONSTRAINT fk_team_member_user FOREIGN KEY (user_id) REFERENCES sys_user(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='团队成员表';
-- 团队应用关联表
CREATE TABLE deploy_team_application
(
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
create_by VARCHAR(100) NULL COMMENT '创建人',
create_time DATETIME(6) NULL COMMENT '创建时间',
update_by VARCHAR(100) NULL COMMENT '更新人',
update_time DATETIME(6) NULL COMMENT '更新时间',
version INT NOT NULL DEFAULT 1 COMMENT '版本号',
deleted BIT NOT NULL DEFAULT 0 COMMENT '是否删除',
team_id BIGINT NOT NULL COMMENT '团队ID',
application_id BIGINT NOT NULL COMMENT '应用ID',
UNIQUE INDEX uk_team_app (team_id, application_id),
INDEX idx_application (application_id),
CONSTRAINT fk_team_app_team FOREIGN KEY (team_id) REFERENCES deploy_team(id),
CONSTRAINT fk_team_app_application FOREIGN KEY (application_id) REFERENCES deploy_application(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='团队应用关联表';
CREATE TABLE deploy_log CREATE TABLE deploy_log
( (
-- 基础字段 -- 基础字段