合并development代码到master #1

Merged
cuizhibin merged 21 commits from development into master 2025-08-11 09:25:53 +08:00
7 changed files with 190 additions and 61 deletions
Showing only changes of commit 386561125e - Show all commits

View File

@ -1,5 +1,6 @@
package com.dite.znpt.domain.vo; package com.dite.znpt.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -45,8 +46,34 @@ public class ProjectMemberResp {
@ApiModelProperty("用户ID") @ApiModelProperty("用户ID")
private String userId; private String userId;
@ApiModelProperty("用户姓名") // ========================== 前端需要的字段 ==========================
private String userName;
@ApiModelProperty("姓名")
private String name;
@ApiModelProperty("联系电话")
private String phone;
@ApiModelProperty("邮箱")
private String email;
@ApiModelProperty("项目岗位")
private String position;
@ApiModelProperty("状态")
private String status;
@ApiModelProperty("技能标签")
private String skills;
@ApiModelProperty("入职日期")
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate joinDate;
@ApiModelProperty("备注")
private String remark;
// ========================== 保留的原有字段用于内部处理 ==========================
@ApiModelProperty("用户账号") @ApiModelProperty("用户账号")
private String userAccount; private String userAccount;
@ -69,15 +96,10 @@ public class ProjectMemberResp {
@ApiModelProperty("岗位描述") @ApiModelProperty("岗位描述")
private String jobDesc; private String jobDesc;
@ApiModelProperty("加入时间")
private LocalDate joinDate;
@ApiModelProperty("离开时间") @ApiModelProperty("离开时间")
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate leaveDate; private LocalDate leaveDate;
@ApiModelProperty("状态") @ApiModelProperty("状态描述")
private String status; private String statusDesc;
@ApiModelProperty("备注")
private String remark;
} }

View File

@ -0,0 +1,39 @@
package com.dite.znpt.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author wangna
* @date 2025/08/05
* @Description: 团队成员查询参数支持筛选分页搜索
*/
@Data
@ApiModel(value="TeamMemberQuery对象", description="团队成员查询参数")
public class TeamMemberQuery {
@ApiModelProperty("项目ID")
private String projectId;
@ApiModelProperty("姓名搜索")
private String name;
@ApiModelProperty("岗位筛选")
private String position;
@ApiModelProperty("状态筛选")
private String status;
@ApiModelProperty("当前页码")
private Integer pageNum = 1;
@ApiModelProperty("每页大小")
private Integer pageSize = 10;
@ApiModelProperty("排序列")
private String orderByColumn;
@ApiModelProperty("排序方向")
private String isAsc = "asc";
}

View File

@ -3,8 +3,8 @@ package com.dite.znpt.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dite.znpt.domain.entity.ProjectMemberEntity; import com.dite.znpt.domain.entity.ProjectMemberEntity;
import com.dite.znpt.domain.vo.ProjectMemberResp; import com.dite.znpt.domain.vo.ProjectMemberResp;
import com.dite.znpt.domain.vo.TeamMemberQuery;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
@ -17,7 +17,7 @@ import java.util.List;
public interface ProjectMemberMapper extends BaseMapper<ProjectMemberEntity> { public interface ProjectMemberMapper extends BaseMapper<ProjectMemberEntity> {
/** /**
* 根据项目ID查询项目人员列表 * 获取项目团队成员列表支持筛选分页搜索
*/ */
List<ProjectMemberResp> queryByProjectId(@Param("projectId") String projectId); List<ProjectMemberResp> queryTeamMembers(TeamMemberQuery query);
} }

View File

@ -1,11 +1,10 @@
package com.dite.znpt.service; package com.dite.znpt.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.dite.znpt.domain.PageResult;
import com.dite.znpt.domain.entity.ProjectMemberEntity; import com.dite.znpt.domain.entity.ProjectMemberEntity;
import com.dite.znpt.domain.vo.*; import com.dite.znpt.domain.vo.*;
import java.util.List;
/** /**
* @author wangna * @author wangna
* @date 2025/08/05 * @date 2025/08/05
@ -14,9 +13,9 @@ import java.util.List;
public interface ProjectMemberService extends IService<ProjectMemberEntity> { public interface ProjectMemberService extends IService<ProjectMemberEntity> {
/** /**
* 根据项目ID查询项目人员列表看板功能需要 * 获取项目团队成员列表支持筛选分页搜索
*/ */
List<ProjectMemberResp> selectByProjectId(String projectId); PageResult<ProjectMemberResp> getProjectTeamMembers(TeamMemberQuery query);
// ========================== 项目看板相关方法 ========================== // ========================== 项目看板相关方法 ==========================

View File

@ -5,16 +5,19 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dite.znpt.constant.Message; import com.dite.znpt.constant.Message;
import com.dite.znpt.domain.PageResult;
import com.dite.znpt.domain.entity.*; import com.dite.znpt.domain.entity.*;
import com.dite.znpt.domain.vo.ProjectDetailResp; import com.dite.znpt.domain.vo.ProjectDetailResp;
import com.dite.znpt.domain.vo.ProjectKanbanDataResp; import com.dite.znpt.domain.vo.ProjectKanbanDataResp;
import com.dite.znpt.domain.vo.ProjectKanbanStatsResp; import com.dite.znpt.domain.vo.ProjectKanbanStatsResp;
import com.dite.znpt.domain.vo.ProjectMemberResp; import com.dite.znpt.domain.vo.ProjectMemberResp;
import com.dite.znpt.domain.vo.TeamMemberQuery;
import com.dite.znpt.enums.ProjectStatusEnum; import com.dite.znpt.enums.ProjectStatusEnum;
import com.dite.znpt.enums.ProjectTaskStateEnum; import com.dite.znpt.enums.ProjectTaskStateEnum;
import com.dite.znpt.exception.ServiceException; import com.dite.znpt.exception.ServiceException;
import com.dite.znpt.mapper.ProjectMemberMapper; import com.dite.znpt.mapper.ProjectMemberMapper;
import com.dite.znpt.service.*; import com.dite.znpt.service.*;
import com.dite.znpt.util.PageUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -43,10 +46,18 @@ public class ProjectMemberServiceImpl extends ServiceImpl<ProjectMemberMapper, P
private final ProjectDailyReportService projectDailyReportService; private final ProjectDailyReportService projectDailyReportService;
@Override @Override
public List<ProjectMemberResp> selectByProjectId(String projectId) { public PageResult<ProjectMemberResp> getProjectTeamMembers(TeamMemberQuery query) {
List<ProjectMemberResp> list = this.baseMapper.queryByProjectId(projectId); // 设置分页参数
PageUtil.startPage();
// 查询团队成员列表
List<ProjectMemberResp> list = this.baseMapper.queryTeamMembers(query);
// 丰富成员信息
enrichMemberInfo(list); enrichMemberInfo(list);
return list;
// 返回分页结果
return PageResult.ok(list);
} }
/** /**
@ -77,9 +88,47 @@ public class ProjectMemberServiceImpl extends ServiceImpl<ProjectMemberMapper, P
list.forEach(member -> { list.forEach(member -> {
UserEntity user = userMap.get(member.getUserId()); UserEntity user = userMap.get(member.getUserId());
if (user != null) { if (user != null) {
member.setUserName(user.getName()); // 映射前端需要的字段
member.setName(user.getName());
member.setPhone(user.getMobile());
member.setEmail(user.getEmail());
// 保留原有字段用于内部处理
member.setUserAccount(user.getAccount());
member.setUserAvatar(user.getAvatar()); member.setUserAvatar(user.getAvatar());
} }
// 映射岗位信息 - 使用角色类型描述作为岗位
member.setPosition(member.getRoleTypeDesc());
// 映射技能标签 - 暂时设为空因为数据库中没有这个字段
member.setSkills("");
// 设置状态描述
if ("ACTIVE".equals(member.getStatus())) {
member.setStatusDesc("在职");
} else if ("INACTIVE".equals(member.getStatus())) {
member.setStatusDesc("离职");
} else if ("PENDING".equals(member.getStatus())) {
member.setStatusDesc("待入职");
} else {
member.setStatusDesc("未知");
}
// 设置角色类型描述
if ("PROJECT_MANAGER".equals(member.getRoleType())) {
member.setRoleTypeDesc("项目经理");
} else if ("SAFETY_OFFICER".equals(member.getRoleType())) {
member.setRoleTypeDesc("安全员");
} else if ("QUALITY_OFFICER".equals(member.getRoleType())) {
member.setRoleTypeDesc("质量员");
} else if ("CONSTRUCTOR".equals(member.getRoleType())) {
member.setRoleTypeDesc("施工员");
} else if ("TEAM_LEADER".equals(member.getRoleType())) {
member.setRoleTypeDesc("施工组长");
} else {
member.setRoleTypeDesc("其他");
}
}); });
} }
@ -148,8 +197,11 @@ public class ProjectMemberServiceImpl extends ServiceImpl<ProjectMemberMapper, P
BeanUtil.copyProperties(project, resp); BeanUtil.copyProperties(project, resp);
resp.setStatusLabel(ProjectStatusEnum.getDescByCode(resp.getStatus())); resp.setStatusLabel(ProjectStatusEnum.getDescByCode(resp.getStatus()));
// 获取项目人员信息 // 获取项目人员信息 - 使用新的查询方法
List<ProjectMemberResp> projectMembers = selectByProjectId(projectId); TeamMemberQuery query = new TeamMemberQuery();
query.setProjectId(projectId);
PageResult<ProjectMemberResp> memberResult = getProjectTeamMembers(query);
List<ProjectMemberResp> projectMembers = memberResult.getRows();
resp.setProjectMembers(projectMembers); resp.setProjectMembers(projectMembers);
// 计算团队规模 // 计算团队规模
@ -158,7 +210,7 @@ public class ProjectMemberServiceImpl extends ServiceImpl<ProjectMemberMapper, P
// 获取项目经理信息 // 获取项目经理信息
String managerName = projectMembers.stream() String managerName = projectMembers.stream()
.filter(member -> "PROJECT_MANAGER".equals(member.getRoleType())) .filter(member -> "PROJECT_MANAGER".equals(member.getRoleType()))
.map(ProjectMemberResp::getUserName) .map(ProjectMemberResp::getName)
.findFirst() .findFirst()
.orElse(""); .orElse("");
resp.setManager(managerName); resp.setManager(managerName);
@ -253,15 +305,18 @@ public class ProjectMemberServiceImpl extends ServiceImpl<ProjectMemberMapper, P
BeanUtil.copyProperties(project, item); BeanUtil.copyProperties(project, item);
item.setStatusLabel(ProjectStatusEnum.getDescByCode(item.getStatus())); item.setStatusLabel(ProjectStatusEnum.getDescByCode(item.getStatus()));
// 获取项目人员信息 // 获取项目人员信息 - 使用新的查询方法
List<ProjectMemberResp> members = selectByProjectId(project.getProjectId()); TeamMemberQuery query = new TeamMemberQuery();
query.setProjectId(project.getProjectId());
PageResult<ProjectMemberResp> memberResult = getProjectTeamMembers(query);
List<ProjectMemberResp> members = memberResult.getRows();
// 按角色类型分组并去重用户名 // 按角色类型分组并去重用户名
Map<String, String> memberNames = members.stream() Map<String, String> memberNames = members.stream()
.collect(Collectors.groupingBy( .collect(Collectors.groupingBy(
ProjectMemberResp::getRoleType, ProjectMemberResp::getRoleType,
Collectors.mapping( Collectors.mapping(
ProjectMemberResp::getUserName, ProjectMemberResp::getName,
Collectors.collectingAndThen( Collectors.collectingAndThen(
Collectors.toSet(), // 使用Set去重 Collectors.toSet(), // 使用Set去重
set -> String.join(",", set) set -> String.join(",", set)

View File

@ -2,35 +2,9 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dite.znpt.mapper.ProjectMemberMapper"> <mapper namespace="com.dite.znpt.mapper.ProjectMemberMapper">
<!-- 基础结果映射 --> <!-- 获取项目团队成员列表(支持筛选、分页、搜索) -->
<resultMap id="BaseResultMap" type="com.dite.znpt.domain.vo.ProjectMemberResp"> <select id="queryTeamMembers" resultType="com.dite.znpt.domain.vo.ProjectMemberResp">
<id column="member_id" property="memberId" jdbcType="VARCHAR"/> SELECT DISTINCT
<result column="project_id" property="projectId" jdbcType="VARCHAR"/>
<result column="project_name" property="projectName" jdbcType="VARCHAR"/>
<result column="turbine_id" property="turbineId" jdbcType="VARCHAR"/>
<result column="turbine_name" property="turbineName" jdbcType="VARCHAR"/>
<result column="task_group_id" property="taskGroupId" jdbcType="VARCHAR"/>
<result column="task_group_name" property="taskGroupName" jdbcType="VARCHAR"/>
<result column="task_id" property="taskId" jdbcType="VARCHAR"/>
<result column="task_name" property="taskName" jdbcType="VARCHAR"/>
<result column="user_id" property="userId" jdbcType="VARCHAR"/>
<result column="user_name" property="userName" jdbcType="VARCHAR"/>
<result column="user_account" property="userAccount" jdbcType="VARCHAR"/>
<result column="user_avatar" property="userAvatar" jdbcType="VARCHAR"/>
<result column="role_type" property="roleType" jdbcType="VARCHAR"/>
<result column="role_type_desc" property="roleTypeDesc" jdbcType="VARCHAR"/>
<result column="job_code" property="jobCode" jdbcType="VARCHAR"/>
<result column="job_code_desc" property="jobCodeDesc" jdbcType="VARCHAR"/>
<result column="job_desc" property="jobDesc" jdbcType="VARCHAR"/>
<result column="join_date" property="joinDate" jdbcType="DATE"/>
<result column="leave_date" property="leaveDate" jdbcType="DATE"/>
<result column="status" property="status" jdbcType="VARCHAR"/>
<result column="remark" property="remark" jdbcType="VARCHAR"/>
</resultMap>
<!-- 根据项目ID查询项目人员列表 -->
<select id="queryByProjectId" resultMap="BaseResultMap">
SELECT
pm.member_id, pm.member_id,
pm.project_id, pm.project_id,
p.project_name, p.project_name,
@ -41,26 +15,54 @@
pm.task_id, pm.task_id,
pt.task_name, pt.task_name,
pm.user_id, pm.user_id,
u.name as user_name, u.name as name,
u.account as user_account, u.account as user_account,
u.avatar as user_avatar, u.avatar as user_avatar,
u.mobile as phone,
u.email as email,
pm.role_type, pm.role_type,
pm.role_type as role_type_desc, CASE
WHEN pm.role_type = 'PROJECT_MANAGER' THEN '项目经理'
WHEN pm.role_type = 'SAFETY_OFFICER' THEN '安全员'
WHEN pm.role_type = 'QUALITY_OFFICER' THEN '质量员'
WHEN pm.role_type = 'CONSTRUCTOR' THEN '施工员'
WHEN pm.role_type = 'TEAM_LEADER' THEN '施工组长'
ELSE '其他'
END as role_type_desc,
pm.job_code, pm.job_code,
pm.job_code as job_code_desc, pm.job_code as job_code_desc,
pm.job_desc, pm.job_desc,
pm.join_date, pm.join_date,
pm.leave_date, pm.leave_date,
pm.status, pm.status,
pm.remark CASE
WHEN pm.status = 'ACTIVE' THEN '在职'
WHEN pm.status = 'INACTIVE' THEN '离职'
WHEN pm.status = 'PENDING' THEN '待入职'
ELSE '未知'
END as status_desc,
pm.remark,
pm.create_time
FROM project_member pm FROM project_member pm
LEFT JOIN project p ON pm.project_id COLLATE utf8mb4_general_ci = p.project_id COLLATE utf8mb4_general_ci LEFT JOIN project p ON pm.project_id COLLATE utf8mb4_general_ci = p.project_id COLLATE utf8mb4_general_ci
LEFT JOIN turbine t ON pm.turbine_id COLLATE utf8mb4_general_ci = t.turbine_id COLLATE utf8mb4_general_ci LEFT JOIN turbine t ON pm.turbine_id COLLATE utf8mb4_general_ci = t.turbine_id COLLATE utf8mb4_general_ci
LEFT JOIN project_task_group ptg ON pm.task_group_id COLLATE utf8mb4_general_ci = ptg.group_id COLLATE utf8mb4_general_ci LEFT JOIN project_task_group ptg ON pm.task_group_id COLLATE utf8mb4_general_ci = ptg.group_id COLLATE utf8mb4_general_ci
LEFT JOIN project_task pt ON pm.task_id COLLATE utf8mb4_general_ci = pt.task_id COLLATE utf8mb4_general_ci LEFT JOIN project_task pt ON pm.task_id COLLATE utf8mb4_general_ci = pt.task_id COLLATE utf8mb4_general_ci
LEFT JOIN user u ON pm.user_id COLLATE utf8mb4_general_ci = u.user_id COLLATE utf8mb4_general_ci LEFT JOIN user u ON pm.user_id COLLATE utf8mb4_general_ci = u.user_id COLLATE utf8mb4_general_ci
WHERE pm.project_id = #{projectId} <where>
AND pm.status = 'ACTIVE' <if test="projectId != null and projectId != ''">
AND pm.project_id = #{projectId}
</if>
<if test="name != null and name != ''">
AND u.name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="position != null and position != ''">
AND pm.role_type = #{position}
</if>
<if test="status != null and status != ''">
AND pm.status = #{status}
</if>
</where>
ORDER BY pm.create_time DESC ORDER BY pm.create_time DESC
</select> </select>

View File

@ -1,9 +1,12 @@
package com.dite.znpt.web.controller; package com.dite.znpt.web.controller;
import com.dite.znpt.domain.PageResult;
import com.dite.znpt.domain.Result; import com.dite.znpt.domain.Result;
import com.dite.znpt.domain.vo.ProjectDetailResp; import com.dite.znpt.domain.vo.ProjectDetailResp;
import com.dite.znpt.domain.vo.ProjectKanbanDataResp; import com.dite.znpt.domain.vo.ProjectKanbanDataResp;
import com.dite.znpt.domain.vo.ProjectKanbanStatsResp; import com.dite.znpt.domain.vo.ProjectKanbanStatsResp;
import com.dite.znpt.domain.vo.ProjectMemberResp;
import com.dite.znpt.domain.vo.TeamMemberQuery;
import com.dite.znpt.service.ProjectMemberService; import com.dite.znpt.service.ProjectMemberService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@ -28,6 +31,15 @@ public class ProjectMemberController {
@Resource @Resource
private ProjectMemberService projectMemberService; private ProjectMemberService projectMemberService;
@ApiOperation(value = "获取项目团队成员列表(支持筛选、分页、搜索)", httpMethod = "GET")
@GetMapping("/project/{projectId}/team-members")
public PageResult<ProjectMemberResp> getProjectTeamMembers(
@PathVariable String projectId,
TeamMemberQuery query) {
query.setProjectId(projectId);
return projectMemberService.getProjectTeamMembers(query);
}
// ========================== 项目看板相关接口 ========================== // ========================== 项目看板相关接口 ==========================
@ApiOperation(value = "获取项目看板统计数据", httpMethod = "GET") @ApiOperation(value = "获取项目看板统计数据", httpMethod = "GET")