buhuazhen
3 天以前 8512de3e8e887ad13c941e60fbb9a3b48a43e9b1
feat(projectManagement): 增加项目阶段相关功能及接口支持

- 新增 InfoStage 实体及其Mapper和XML配置
- 新增 InfoStageDto、InfoStageVo 和 SaveInfoStageVo 数据传输对象
- 实现 InfoStageHandleService,支持保存、查询、删除项目阶段及同步阶段状态
- 在 InfoController 中添加项目阶段的保存、查询列表、删除接口
- 修改 InfoHandleService 支持根据ID更新项目基础信息
- 扩展计划阶段 PlanStageDto,新增排序字段和预计工期字段
- 调整 ListInfoVo,加入全部阶段信息字段以支持前端展示
- 优化数据库查询,增加 planStage 字段及其JSON类型处理映射
- 实现附件ID处理及附件列表填充功能,支持项目阶段附件管理
- 同步和排序项目阶段列表,确保阶段显示顺序和数据一致性
已添加7个文件
已修改5个文件
554 ■■■■■ 文件已修改
src/main/java/com/ruoyi/projectManagement/controller/InfoController.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/dto/InfoStageDto.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/dto/PlanStageDto.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/mapper/InfoStageMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/pojo/InfoStage.java 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/service/impl/handle/InfoHandleService.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/service/impl/handle/InfoStageHandleService.java 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/vo/InfoStageVo.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/vo/ListInfoVo.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/vo/SaveInfoStageVo.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/projectManagement/InfoMapper.xml 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/projectManagement/InfoStageMapper.xml 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/projectManagement/controller/InfoController.java
@@ -1,8 +1,11 @@
package com.ruoyi.projectManagement.controller;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.projectManagement.dto.InfoStageDto;
import com.ruoyi.projectManagement.dto.UpdateStateInfo;
import com.ruoyi.projectManagement.service.InfoService;
import com.ruoyi.projectManagement.service.impl.handle.InfoStageHandleService;
import com.ruoyi.projectManagement.vo.SaveInfoStageVo;
import com.ruoyi.projectManagement.vo.SaveInfoVo;
import com.ruoyi.projectManagement.vo.SearchInfoVo;
import io.swagger.annotations.Api;
@@ -24,6 +27,7 @@
public class InfoController {
    private final InfoService infoService;
    private final InfoStageHandleService infoStageHandleService;
    @PostMapping("/save")
    @ApiOperation("保存")
@@ -59,5 +63,25 @@
        return AjaxResult.success(infoService.getInfoById(id));
    }
    @PostMapping("/saveStage")
    @ApiOperation("保存阶段")
    public AjaxResult saveStage(@RequestBody @Valid SaveInfoStageVo dto) {
        infoStageHandleService.save(dto);
        return AjaxResult.success();
    }
    @PostMapping("/listStage/{id}")
    @ApiOperation("列表阶段")
    public AjaxResult listStage(@PathVariable Long id) {
        return AjaxResult.success(infoStageHandleService.getListVoByInfoId(id));
    }
    @PostMapping("/deleteStage/{id}")
    @ApiOperation("删除阶段")
    public AjaxResult deleteStage(@PathVariable Long id) {
        infoStageHandleService.deleteById(id);
        return AjaxResult.success();
    }
}
src/main/java/com/ruoyi/projectManagement/dto/InfoStageDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,92 @@
package com.ruoyi.projectManagement.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
 * @author buhuazhen
 * @date 2026/3/11
 * @email 3038525872@qq.com
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class InfoStageDto implements java.io.Serializable {
    private Long id;
    /**
     * å¯¹åº”计划节点id
     */
    @NotNull(message = "对应计划节点projectManagementPlanNodeId不能为空")
    private Long projectManagementPlanNodeId;
    /**
     * å¯¹åº”项目id
     */
    @NotNull(message = "对应项目projectManagementInfoId不能为空")
    private Long projectManagementInfoId;
    /**
     * æè¿°
     */
    private String description;
    /**
     * å®žé™…负责人id
     */
    private Long actuallyLeaderId;
    /**
     * å®žé™…负责人名称
     */
    private String actuallyLeaderName;
    /**
     * é¢„计工期
     */
    private Integer estimatedDuration;
    /**
     * è®¡åˆ’开始
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate planStartTime;
    /**
     * è¿›åº¦
     */
    private Integer progress;
    /**
     * å®žé™…开始时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate actualStartTime;
    /**
     * å®žé™…结束时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate actualEndTime;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    private String attachment;
}
src/main/java/com/ruoyi/projectManagement/dto/PlanStageDto.java
@@ -19,4 +19,6 @@
    private Long id;
    private String name;
    private PlanStageEnum planStageEnum;
    private Integer sort;
    private Integer estimatedDuration; // é¢„计工期
}
src/main/java/com/ruoyi/projectManagement/mapper/InfoStageMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.projectManagement.mapper;
import com.ruoyi.projectManagement.pojo.InfoStage;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author buhuazhen
* @description é’ˆå¯¹è¡¨ã€project_management_info_stage(项目阶段)】的数据库操作Mapper
* @createDate 2026-03-11 10:28:27
* @Entity com.ruoyi.projectManagement.pojo.InfoStage
*/
public interface InfoStageMapper extends BaseMapper<InfoStage> {
}
src/main/java/com/ruoyi/projectManagement/pojo/InfoStage.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,141 @@
package com.ruoyi.projectManagement.pojo;
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 java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import lombok.Data;
/**
 * é¡¹ç›®é˜¶æ®µ
 * @TableName project_management_info_stage
 */
@TableName(value ="project_management_info_stage")
@Data
public class InfoStage implements Serializable {
    /**
     *
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * å¯¹åº”计划节点id
     */
    @TableField(value = "project_management_plan_node_id")
    private Long projectManagementPlanNodeId;
    /**
     * å¯¹åº”项目id
     */
    @TableField(value = "project_management_info_id")
    private Long projectManagementInfoId;
    /**
     * æè¿°
     */
    @TableField(value = "description")
    private String description;
    /**
     * å®žé™…负责人id
     */
    @TableField(value = "actually_leader_id")
    private Long actuallyLeaderId;
    /**
     * å®žé™…负责人名称
     */
    @TableField(value = "actually_leader_name")
    private String actuallyLeaderName;
    /**
     * é¢„计工期
     */
    @TableField(value = "estimated_duration")
    private Integer estimatedDuration;
    /**
     * è®¡åˆ’开始
     */
    @TableField(value = "plan_start_time")
    private LocalDate planStartTime;
    /**
     * è®¡åˆ’结束
     */
    @TableField(value = "plan_end_time")
    private LocalDate planEndTime;
    /**
     * è¿›åº¦
     */
    @TableField(value = "progress")
    private Integer progress;
    /**
     * å®žé™…开始时间
     */
    @TableField(value = "actual_start_time")
    private LocalDate actualStartTime;
    /**
     * å®žé™…结束时间
     */
    @TableField(value = "actual_end_time")
    private LocalDate actualEndTime;
    /**
     * é™„ä»¶
     */
    @TableField(value = "attachment")
    private String attachment;
    /**
     *
     */
    @TableField(value = "create_time")
    private LocalDateTime createTime;
    /**
     *
     */
    @TableField(value = "update_time")
    private LocalDateTime updateTime;
    /**
     *
     */
    @TableField(value = "is_delete")
    private Integer isDelete;
    /**
     *
     */
    @TableField(value = "create_user")
    private Long createUser;
    /**
     *
     */
    @TableField(value = "update_user")
    private Long updateUser;
    /**
     *
     */
    @TableField(value = "create_user_name")
    private String createUserName;
    /**
     *
     */
    @TableField(value = "update_user_name")
    private String updateUserName;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
src/main/java/com/ruoyi/projectManagement/service/impl/handle/InfoHandleService.java
@@ -4,10 +4,12 @@
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.collect.Lists;
import com.ruoyi.basic.service.CustomerFollowUpFileService;
import com.ruoyi.common.enums.PlanStageEnum;
import com.ruoyi.common.enums.ReviewStatusEnum;
import com.ruoyi.projectManagement.dto.InfoStageDto;
import com.ruoyi.projectManagement.dto.PlanStageDto;
import com.ruoyi.projectManagement.dto.SaveInfoDto;
import com.ruoyi.projectManagement.mapper.InfoMapper;
@@ -68,6 +70,11 @@
        return info.getId();
    }
    @Transactional
    public void updateById(@NotNull Info info){
        infoMapper.updateById(info);
    }
    public SaveInfoDto getInfoById(@NotNull Long id) {
        Info info = infoMapper.selectById(id);
        return convert(info);
@@ -99,7 +106,7 @@
    private List<PlanStageDto> getPlanStageList(@NotNull Long planId) {
        List<PlanNode> planNodeByPlanId = planService.getPlanNodeByPlanId(planId);
        return planNodeByPlanId.stream().map(it -> new PlanStageDto(it.getId(), it.getName(), PlanStageEnum.TO_BEGIN)).collect(Collectors.toList());
        return planNodeByPlanId.stream().map(it -> new PlanStageDto(it.getId(), it.getName(), PlanStageEnum.TO_BEGIN, it.getSort(), it.getEstimatedDuration())).collect(Collectors.toList());
    }
src/main/java/com/ruoyi/projectManagement/service/impl/handle/InfoStageHandleService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,161 @@
package com.ruoyi.projectManagement.service.impl.handle;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ruoyi.basic.service.CustomerFollowUpFileService;
import com.ruoyi.common.enums.IsDeleteEnum;
import com.ruoyi.common.enums.PlanStageEnum;
import com.ruoyi.projectManagement.dto.InfoStageDto;
import com.ruoyi.projectManagement.dto.PlanStageDto;
import com.ruoyi.projectManagement.dto.SaveInfoDto;
import com.ruoyi.projectManagement.mapper.InfoStageMapper;
import com.ruoyi.projectManagement.pojo.Info;
import com.ruoyi.projectManagement.pojo.InfoStage;
import com.ruoyi.projectManagement.vo.InfoStageVo;
import com.ruoyi.projectManagement.vo.SaveInfoStageVo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @author buhuazhen
 * @date 2026/3/11
 * @email 3038525872@qq.com
 */
@Component
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class, readOnly = true)
public class InfoStageHandleService {
    private final InfoStageMapper infoStageMapper;
    private final InfoHandleService infoHandleService;
    private final CustomerFollowUpFileService customerFollowUpFileService;
    @Autowired
    @Lazy
    private InfoStageHandleService infoStageHandleService;
    @Transactional
    public void save(@NotNull SaveInfoStageVo saveInfoStageVo) {
        InfoStage infoStage = BeanUtil.copyProperties(saveInfoStageVo, InfoStage.class);
        // é™„件处理
        String attachmentIds = StrUtil.join(",", Optional.ofNullable(saveInfoStageVo.getAttachmentIds()).orElse(Collections.emptyList()));
        infoStage.setAttachment(attachmentIds);
        if (infoStage.getId() == null) {
            infoStageMapper.insert(infoStage);
        } else {
            infoStageMapper.updateById(infoStage);
        }
        infoStageHandleService.syncInfoStage(infoStage.getProjectManagementInfoId());
    }
    /**
     * åŒæ­¥é¡¹ç›®é˜¶æ®µçŠ¶æ€
     *
     * @param infoId
     */
    @Transactional
    public void syncInfoStage(@NotNull Long infoId) {
        SaveInfoDto infoById = infoHandleService.getInfoById(infoId);
        List<PlanStageDto> planStage = infoById.getPlanStage();
        // èŽ·å–ä¾æ—§å­˜åœ¨çš„é˜¶æ®µä¿¡æ¯
        List<InfoStageDto> infoStageNow = getListDtoByInfoId(infoId);
        Map<Long, Integer> maxProgressMap =
                infoStageNow.stream()
                        .filter(e -> e.getProjectManagementPlanNodeId() != null)
                        .collect(Collectors.toMap(
                                InfoStageDto::getProjectManagementPlanNodeId,
                                e -> Optional.ofNullable(e.getProgress()).orElse(0),
                                Integer::max
                        ));
        for (PlanStageDto stage : planStage) {
            int progress = maxProgressMap.getOrDefault(stage.getId(), 0);
            stage.setPlanStageEnum(calcStage(progress));
        }
        // è¿›è¡Œè°ƒæ•´
        Info info = new Info();
        info.setId(infoId);
        info.setPlanStage(planStage);
        infoHandleService.updateById(info);
    }
    private PlanStageEnum calcStage(int progress) {
        if (progress <= 0) {
            return PlanStageEnum.TO_BEGIN;
        } else if (progress < 100) {
            return PlanStageEnum.ON_GOING;
        }
        return PlanStageEnum.ENDED;
    }
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(@NotNull Long id) {
        InfoStage infoStage = infoStageMapper.selectById(id);
        if (infoStage == null) {
            return;
        }
        LambdaUpdateWrapper<InfoStage> updateWrapper = new LambdaUpdateWrapper<InfoStage>();
        updateWrapper.eq(InfoStage::getId, id);
        updateWrapper.set(InfoStage::getIsDelete, IsDeleteEnum.DELETED.getCode());
        infoStageMapper.update(null, updateWrapper);
        infoStageHandleService.syncInfoStage(infoStage.getProjectManagementInfoId());
    }
    public List<InfoStageDto> getListDtoByInfoId(@NotNull Long infoId) {
        LambdaQueryWrapper<InfoStage> queryWrapper = new LambdaQueryWrapper<InfoStage>();
        queryWrapper.eq(InfoStage::getProjectManagementInfoId, infoId);
        queryWrapper.eq(InfoStage::getIsDelete, IsDeleteEnum.NOT_DELETED.getCode());
        List<InfoStageDto> infoStageDtos = BeanUtil.copyToList(infoStageMapper.selectList(queryWrapper), InfoStageDto.class);
        /*
         * è¿›è¡ŒæŽ’序 å…ˆæŒ‰ç…§å¯¹åº”çš„sort进行排序,后按照创建时间排序
         * å¯èƒ½ä¼šå‡ºçŽ°åŽéƒ¨æƒ…å†µ æ¯”如
         * ç«‹é¡¹ 100%
         * ç«‹é¡¹ 50%   è¿™ç§æƒ…况,当然也支持修改操作
         */
        SaveInfoDto infoById = infoHandleService.getInfoById(infoId);
        List<PlanStageDto> planStage = infoById.getPlanStage();
        // æž„建 id -> sort æ˜ å°„
        Map<Long, Integer> stageSortMap = planStage.stream()
                .collect(Collectors.toMap(
                        PlanStageDto::getId,
                        PlanStageDto::getSort
                ));
        // æŽ’序
        infoStageDtos.sort(
                Comparator
                        // å…ˆæŒ‰é˜¶æ®µæŽ’序
                        .comparing((InfoStageDto dto) ->
                                stageSortMap.getOrDefault(dto.getProjectManagementPlanNodeId(), Integer.MAX_VALUE)
                        )
                        // å†æŒ‰åˆ›å»ºæ—¶é—´æŽ’序
                        .thenComparing(InfoStageDto::getCreateTime)
        );
        return infoStageDtos;
    }
    public List<InfoStageVo> getListVoByInfoId(@NotNull Long infoId) {
        List<InfoStageDto> listByInfoId = getListDtoByInfoId(infoId);
        List<InfoStageVo> infoStageVos = BeanUtil.copyToList(listByInfoId, InfoStageVo.class);
        // å¤„理附件
        customerFollowUpFileService.fillAttachment(infoStageVos, InfoStageVo::getAttachment, InfoStageVo::setAttachmentList);
        return infoStageVos;
    }
}
src/main/java/com/ruoyi/projectManagement/vo/InfoStageVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.ruoyi.projectManagement.vo;
import com.ruoyi.common.vo.SimpleFileVo;
import com.ruoyi.projectManagement.dto.InfoStageDto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.util.List;
/**
 * @author buhuazhen
 * @date 2026/3/11
 * @email 3038525872@qq.com
 */
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class InfoStageVo extends InfoStageDto implements java.io.Serializable {
    private List<SimpleFileVo> attachmentList; // é™„件列表
}
src/main/java/com/ruoyi/projectManagement/vo/ListInfoVo.java
@@ -1,6 +1,7 @@
package com.ruoyi.projectManagement.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.projectManagement.dto.PlanStageDto;
import com.ruoyi.projectManagement.dto.SaveInfoDto;
import lombok.AllArgsConstructor;
import lombok.Data;
@@ -10,6 +11,7 @@
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
/**
 * é¡µé¢åˆ—表信息
@@ -39,4 +41,6 @@
    private String createUserName; // åˆ›å»ºäººåç§°
    private String updateUserName; // æ›´æ–°äººåç§°
    // å…¨éƒ¨é˜¶æ®µä¿¡æ¯
    private List<PlanStageDto> planStage;
}
src/main/java/com/ruoyi/projectManagement/vo/SaveInfoStageVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.ruoyi.projectManagement.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.projectManagement.dto.InfoStageDto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate;
import java.util.List;
/**
 * @author buhuazhen
 * @date 2026/3/11
 * @email 3038525872@qq.com
 */
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SaveInfoStageVo extends InfoStageDto implements java.io.Serializable {
    private List<String> attachmentIds;
}
src/main/resources/mapper/projectManagement/InfoMapper.xml
@@ -48,7 +48,14 @@
        department_name,order_date,order_amount,
        remark,attachment
    </sql>
    <select id="searchListInfo" resultType="com.ruoyi.projectManagement.vo.ListInfoVo">
    <resultMap id="ListInfoVoMap" type="com.ruoyi.projectManagement.vo.ListInfoVo">
        <result column="plan_stage"
                property="planStage"
                typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
    </resultMap>
    <select id="searchListInfo" resultMap="ListInfoVoMap">
        select t1.*, t2.name as project_management_plan_name,t3.title as projectManagementInfoParentName
        from project_management_info as t1
        left join project_management_plan as t2 on t1.project_management_plan_id = t2.id
src/main/resources/mapper/projectManagement/InfoStageMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
<?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.projectManagement.mapper.InfoStageMapper">
    <resultMap id="BaseResultMap" type="com.ruoyi.projectManagement.pojo.InfoStage">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="projectManagementPlanNodeId" column="project_management_plan_node_id" jdbcType="BIGINT"/>
            <result property="projectManagementInfoId" column="project_management_info_id" jdbcType="BIGINT"/>
            <result property="description" column="description" jdbcType="VARCHAR"/>
            <result property="actuallyLeaderId" column="actually_leader_id" jdbcType="BIGINT"/>
            <result property="actuallyLeaderName" column="actually_leader_name" jdbcType="VARCHAR"/>
            <result property="estimatedDuration" column="estimated_duration" jdbcType="INTEGER"/>
            <result property="planStartTime" column="plan_start_time" jdbcType="DATE"/>
            <result property="planEndTime" column="plan_end_time" jdbcType="DATE"/>
            <result property="actualStartTime" column="actual_start_time" jdbcType="DATE"/>
            <result property="actualEndTime" column="actual_end_time" jdbcType="DATE"/>
            <result property="progress" column="progress" jdbcType="INTEGER"/>
            <result property="actuallyStartTime" column="actually_start_time" jdbcType="DATE"/>
            <result property="actuallyEndTime" column="actually_end_time" jdbcType="DATE"/>
            <result property="attachment" column="attachment" jdbcType="VARCHAR"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
            <result property="isDelete" column="is_delete" jdbcType="INTEGER"/>
            <result property="createUser" column="create_user" jdbcType="BIGINT"/>
            <result property="updateUser" column="update_user" jdbcType="BIGINT"/>
            <result property="createUserName" column="create_user_name" jdbcType="VARCHAR"/>
            <result property="updateUserName" column="update_user_name" jdbcType="VARCHAR"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,project_management_plan_node_id,project_management_info_id,
        description,actually_leader_id,actually_leader_name,
        estimated_duration,plan_start_time,plan_end_time,
        actual_start_time,actual_end_time,progress,
        actually_start_time,actually_end_time,attachment,
        create_time,update_time,is_delete,
        create_user,update_user,create_user_name,
        update_user_name
    </sql>
</mapper>