feat(sip): 新增项目 poc 测试信息功能

- 添加 ProjectPocInfo 模型类- 实现 IProjectPocInfoService 接口及其实现类
- 在 ProjectInfo 中添加项目 poc 信息字段
- 更新 ProjectInfoServiceImpl 中的项目信息获取和保存逻辑
- 添加 poc 信息的比较和日志记录功能
master
chenhao 2025-06-09 11:43:15 +08:00
parent 63bd43b4b8
commit 76801aca85
7 changed files with 480 additions and 5 deletions

View File

@ -139,5 +139,6 @@ public class ProjectInfo extends BaseEntity
private List<ProjectOperateLog> projectOperateLogList;
/** 项目工作进度信息 */
private List<ProjectWorkProgress> projectWorkProgressList;
private ProjectPocInfo projectPocInfo;
}

View File

@ -0,0 +1,58 @@
package com.ruoyi.sip.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.ToString;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* poc project_poc_info
*
* @author ruoyi
* @date 2025-06-09
*/
@Data
@ToString
public class ProjectPocInfo extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** */
private Long id;
/** 项目id */
@Excel(name = "项目id")
private Long projectId;
/** 测试环境 */
@Excel(name = "测试环境")
private String testEnvironment;
/** 测试进展 */
@Excel(name = "测试进展")
private String testProgress;
/** 项目成员信息 */
@Excel(name = "项目成员信息")
private String projectUserInfo;
/** 启动日期 */
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "启动日期", width = 30, dateFormat = "yyyy-MM-dd")
private Date startDate;
/** 预计完成时间 */
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "预计完成时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date planFinishTime;
/** 实际完成时间 */
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "实际完成时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date realFinishTime;
}

View File

@ -0,0 +1,66 @@
package com.ruoyi.sip.mapper;
import java.util.List;
import com.ruoyi.sip.domain.ProjectPocInfo;
/**
* pocMapper
*
* @author ruoyi
* @date 2025-06-09
*/
public interface ProjectPocInfoMapper
{
/**
* poc
*
* @param id poc
* @return poc
*/
public ProjectPocInfo selectProjectPocInfoById(Long id);
/**
* poc
*
* @param projectPocInfo poc
* @return poc
*/
public List<ProjectPocInfo> selectProjectPocInfoList(ProjectPocInfo projectPocInfo);
/**
* poc
*
* @param projectPocInfo poc
* @return
*/
public int insertProjectPocInfo(ProjectPocInfo projectPocInfo);
/**
* poc
*
* @param projectPocInfo poc
* @return
*/
public int updateProjectPocInfo(ProjectPocInfo projectPocInfo);
/**
* poc
*
* @param id poc
* @return
*/
public int deleteProjectPocInfoById(Long id);
/**
* poc
*
* @param ids
* @return
*/
public int deleteProjectPocInfoByIds(String[] ids);
List<ProjectPocInfo> listByProjectId(List<Long> projectId);
void insertBatch(List<ProjectPocInfo> addList);
void updateBatch(List<ProjectPocInfo> addList);
}

View File

@ -0,0 +1,67 @@
package com.ruoyi.sip.service;
import java.util.List;
import com.ruoyi.sip.domain.ProjectPocInfo;
/**
* pocService
*
* @author ruoyi
* @date 2025-06-09
*/
public interface IProjectPocInfoService
{
/**
* poc
*
* @param id poc
* @return poc
*/
public ProjectPocInfo selectProjectPocInfoById(Long id);
/**
* poc
*
* @param projectPocInfo poc
* @return poc
*/
public List<ProjectPocInfo> selectProjectPocInfoList(ProjectPocInfo projectPocInfo);
/**
* poc
*
* @param projectPocInfo poc
* @return
*/
public int insertProjectPocInfo(ProjectPocInfo projectPocInfo);
/**
* poc
*
* @param projectPocInfo poc
* @return
*/
public int updateProjectPocInfo(ProjectPocInfo projectPocInfo);
/**
* poc
*
* @param ids poc
* @return
*/
public int deleteProjectPocInfoByIds(String ids);
/**
* poc
*
* @param id poc
* @return
*/
public int deleteProjectPocInfoById(Long id);
List<ProjectPocInfo> listByProjectId(List<Long> projectId);
void saveBatch(List<ProjectPocInfo> projectPocInfos);
}

View File

@ -17,7 +17,6 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;
@ -45,7 +44,8 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
private IProjectWorkProgressService workProgressService;
@Autowired
private IProjectOperateLogService operateLogService;
@Autowired
private IProjectPocInfoService pocInfoService;
@Autowired
private IProjectOrderInfoService orderInfoService;
@ -90,6 +90,10 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
return ProjectOperateLog.LogTypeEnum.BRIEF.getValue().equals(item.getLogType());
}).collect(Collectors.toList());
projectInfo.setProjectOperateLogList(projectOperateLogs);
List<ProjectPocInfo> projectPocInfos = pocInfoService.listByProjectId(Collections.singletonList(projectInfo.getId()));
if (CollUtil.isNotEmpty(projectPocInfos)) {
projectInfo.setProjectPocInfo(projectPocInfos.get(0));
}
return projectInfo;
}
@ -175,6 +179,13 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
}
workProgressService.insertIgnoreBatch(projectWorkProgressList);
}
//保存poc信息
ProjectPocInfo projectPocInfo = projectInfo1.getProjectPocInfo();
if (projectPocInfo != null) {
projectPocInfo.setProjectId(projectInfo1.getId());
pocInfoService.saveBatch(Collections.singletonList(projectPocInfo));
}
}
@ -221,7 +232,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
private void recordOperationLogs(ProjectInfo projectInfo, ProjectInfo oldProjectInfo) {
StringBuilder logContent = new StringBuilder();
//简略信息变更
StringBuilder logSimpleContent = new StringBuilder();
StringJoiner logSimpleContent = new StringJoiner("\n");
int logSimpleIndex = 1;
int logIndex = 1;
// 比较项目信息字段差异
@ -257,7 +268,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
logIndex = compareField(logContent, logIndex, "项目简述", oldProjectInfo.getProjectDesc(), projectInfo.getProjectDesc());
if (logIndex > 1) {
logSimpleIndex = logIndex;
logSimpleContent.append("1.项目信息发生变更\n");
logSimpleContent.add("1.项目信息发生变更");
}
// 配置信息变更
List<ProjectProductInfo> oldSoftWareProductList = oldProjectInfo.getSoftwareProjectProductInfoList();
@ -281,9 +292,18 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
logIndex = compareProductInfoList(logContent, logIndex, "配置硬件信息", oldMaintenanceProductList, newMaintenanceProductList);
if (logSimpleIndex != logIndex) {
logSimpleContent.append(StringUtils.isNotEmpty(logSimpleContent)?"1.":"2.").append("配置信息发生变更");
logSimpleContent.add(StringUtils.format("{}.配置信息发生变更", logSimpleContent.length() + 1));
logSimpleIndex = logIndex;
}
//记录poc信息变更
logIndex = comparePocInfo(oldProjectInfo.getProjectPocInfo(), projectInfo.getProjectPocInfo(), logIndex, logContent);
if (logSimpleIndex != logIndex) {
logSimpleContent.add(StringUtils.format("{}.poc信息发生变更", logSimpleContent.length() + 1));
logSimpleIndex = logIndex;
}
// 插入操作日志
if (logContent.length() > 0) {
ProjectOperateLog operateLog = new ProjectOperateLog();
@ -306,6 +326,26 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
}
}
private int comparePocInfo(ProjectPocInfo oldInfo, ProjectPocInfo info, int index, StringBuilder logContent) {
if (oldInfo == null && info != null) {
logContent.append(index).append(".poc新增");
return ++index;
}
if (oldInfo != null && info == null) {
logContent.append(index).append(".poc删除");
return ++index;
}
if (oldInfo != null) {
index=compareField(logContent, index, "测试环境", oldInfo.getTestEnvironment(), info.getTestEnvironment());
index=compareField(logContent, index, "测试进展", oldInfo.getTestProgress(), info.getTestProgress());
index=compareField(logContent, index, "项目成员信息", oldInfo.getProjectUserInfo(), info.getProjectUserInfo());
index=compareField(logContent, index, "启动日期", formatterDate(oldInfo.getStartDate()), formatterDate(info.getStartDate()));
index=compareField(logContent, index, "预计完成日期", formatterDate(oldInfo.getPlanFinishTime()), formatterDate(info.getPlanFinishTime()));
index=compareField(logContent, index, "实际完成日期", formatterDate(oldInfo.getRealFinishTime()), formatterDate(info.getRealFinishTime()));
}
return index;
}
private String formatterDate(Date date) {
if (date == null) {
return null;

View File

@ -0,0 +1,120 @@
package com.ruoyi.sip.service.impl;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import cn.hutool.core.collection.CollUtil;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.sip.mapper.ProjectPocInfoMapper;
import com.ruoyi.sip.domain.ProjectPocInfo;
import com.ruoyi.sip.service.IProjectPocInfoService;
import com.ruoyi.common.core.text.Convert;
/**
* pocService
*
* @author ruoyi
* @date 2025-06-09
*/
@Service
public class ProjectPocInfoServiceImpl implements IProjectPocInfoService
{
@Autowired
private ProjectPocInfoMapper projectPocInfoMapper;
/**
* poc
*
* @param id poc
* @return poc
*/
@Override
public ProjectPocInfo selectProjectPocInfoById(Long id)
{
return projectPocInfoMapper.selectProjectPocInfoById(id);
}
/**
* poc
*
* @param projectPocInfo poc
* @return poc
*/
@Override
public List<ProjectPocInfo> selectProjectPocInfoList(ProjectPocInfo projectPocInfo)
{
return projectPocInfoMapper.selectProjectPocInfoList(projectPocInfo);
}
/**
* poc
*
* @param projectPocInfo poc
* @return
*/
@Override
public int insertProjectPocInfo(ProjectPocInfo projectPocInfo)
{
projectPocInfo.setCreateTime(DateUtils.getNowDate());
return projectPocInfoMapper.insertProjectPocInfo(projectPocInfo);
}
/**
* poc
*
* @param projectPocInfo poc
* @return
*/
@Override
public int updateProjectPocInfo(ProjectPocInfo projectPocInfo)
{
return projectPocInfoMapper.updateProjectPocInfo(projectPocInfo);
}
/**
* poc
*
* @param ids poc
* @return
*/
@Override
public int deleteProjectPocInfoByIds(String ids)
{
return projectPocInfoMapper.deleteProjectPocInfoByIds(Convert.toStrArray(ids));
}
/**
* poc
*
* @param id poc
* @return
*/
@Override
public int deleteProjectPocInfoById(Long id)
{
return projectPocInfoMapper.deleteProjectPocInfoById(id);
}
@Override
public List<ProjectPocInfo> listByProjectId(List<Long> projectId) {
return projectPocInfoMapper.listByProjectId(projectId);
}
@Override
public void saveBatch(List<ProjectPocInfo> projectPocInfos) {
if (CollUtil.isEmpty(projectPocInfos)){
return;
}
List<ProjectPocInfo> addList = projectPocInfos.stream().filter(projectPocInfo -> projectPocInfo.getId() == null).collect(Collectors.toList());
List<ProjectPocInfo> updateList = projectPocInfos.stream().filter(projectPocInfo -> projectPocInfo.getId() != null).collect(Collectors.toList());
if (CollUtil.isEmpty(addList)){
projectPocInfoMapper.insertBatch(addList);
}
if (CollUtil.isEmpty(updateList)){
projectPocInfoMapper.updateBatch(updateList);
}
}
}

View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.sip.mapper.ProjectPocInfoMapper">
<resultMap type="ProjectPocInfo" id="ProjectPocInfoResult">
<result property="id" column="id" />
<result property="projectId" column="project_id" />
<result property="testEnvironment" column="test_environment" />
<result property="testProgress" column="test_progress" />
<result property="projectUserInfo" column="project_user_info" />
<result property="startDate" column="start_date" />
<result property="planFinishTime" column="plan_finish_time" />
<result property="realFinishTime" column="real_finish_time" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
</resultMap>
<sql id="selectProjectPocInfoVo">
select id, project_id, test_environment, test_progress, project_user_info, start_date, plan_finish_time, real_finish_time, create_by, create_time from project_poc_info
</sql>
<select id="selectProjectPocInfoList" parameterType="ProjectPocInfo" resultMap="ProjectPocInfoResult">
<include refid="selectProjectPocInfoVo"/>
<where>
<if test="projectId != null "> and project_id = #{projectId}</if>
<if test="testEnvironment != null and testEnvironment != ''"> and test_environment = #{testEnvironment}</if>
<if test="testProgress != null and testProgress != ''"> and test_progress = #{testProgress}</if>
<if test="projectUserInfo != null and projectUserInfo != ''"> and project_user_info = #{projectUserInfo}</if>
<if test="startDate != null "> and start_date = #{startDate}</if>
<if test="planFinishTime != null "> and plan_finish_time = #{planFinishTime}</if>
<if test="realFinishTime != null "> and real_finish_time = #{realFinishTime}</if>
</where>
</select>
<select id="selectProjectPocInfoById" parameterType="Long" resultMap="ProjectPocInfoResult">
<include refid="selectProjectPocInfoVo"/>
where id = #{id}
</select>
<select id="listByProjectId" resultType="com.ruoyi.sip.domain.ProjectPocInfo">
<include refid="selectProjectPocInfoVo"/>
where project_id in (
<foreach item="projectId" collection="list" separator=",">
#{projectId}
</foreach>
)
</select>
<insert id="insertProjectPocInfo" parameterType="ProjectPocInfo" useGeneratedKeys="true" keyProperty="id">
insert into project_poc_info
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="projectId != null">project_id,</if>
<if test="testEnvironment != null">test_environment,</if>
<if test="testProgress != null">test_progress,</if>
<if test="projectUserInfo != null">project_user_info,</if>
<if test="startDate != null">start_date,</if>
<if test="planFinishTime != null">plan_finish_time,</if>
<if test="realFinishTime != null">real_finish_time,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="projectId != null">#{projectId},</if>
<if test="testEnvironment != null">#{testEnvironment},</if>
<if test="testProgress != null">#{testProgress},</if>
<if test="projectUserInfo != null">#{projectUserInfo},</if>
<if test="startDate != null">#{startDate},</if>
<if test="planFinishTime != null">#{planFinishTime},</if>
<if test="realFinishTime != null">#{realFinishTime},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
</trim>
</insert>
<insert id="insertBatch">
insert into project_poc_info (project_id, test_environment, test_progress, project_user_info, start_date, plan_finish_time, real_finish_time, create_by, create_time) values
<foreach item="item" index="index" collection="list" separator=",">
(#{item.projectId}, #{item.testEnvironment}, #{item.testProgress}, #{item.projectUserInfo}, #{item.startDate}, #{item.planFinishTime}, #{item.realFinishTime}, #{item.createBy},now())
</foreach>
</insert>
<update id="updateProjectPocInfo" parameterType="ProjectPocInfo">
update project_poc_info
<trim prefix="SET" suffixOverrides=",">
<if test="projectId != null">project_id = #{projectId},</if>
<if test="testEnvironment != null">test_environment = #{testEnvironment},</if>
<if test="testProgress != null">test_progress = #{testProgress},</if>
<if test="projectUserInfo != null">project_user_info = #{projectUserInfo},</if>
<if test="startDate != null">start_date = #{startDate},</if>
<if test="planFinishTime != null">plan_finish_time = #{planFinishTime},</if>
<if test="realFinishTime != null">real_finish_time = #{realFinishTime},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
</trim>
where id = #{id}
</update>
<update id="updateBatch">
<foreach collection="list" item="item" index="index" separator=";">
update project_poc_info
<trim prefix="SET" suffixOverrides=",">
<if test="item.testEnvironment != null">test_environment = #{item.testEnvironment},</if>
<if test="item.testProgress != null">test_progress = #{item.testProgress},</if>
<if test="item.projectUserInfo != null">project_user_info = #{item.projectUserInfo},</if>
<if test="item.startDate != null">start_date = #{item.startDate},</if>
<if test="item.planFinishTime != null">plan_finish_time = #{item.planFinishTime},</if>
<if test="item.realFinishTime != null">real_finish_time = #{item.realFinishTime},</if>
</trim>
where id = #{item.id}
</foreach>
</update>
<delete id="deleteProjectPocInfoById" parameterType="Long">
delete from project_poc_info where id = #{id}
</delete>
<delete id="deleteProjectPocInfoByIds" parameterType="String">
delete from project_poc_info where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>