feat(oa): 新增项目进度节点批量插入功能

- 新增 NodeDTO 数据传输对象,用于封装节点信息
- 在 OaProjectScheduleStepMapper 中添加 saveBatch 批量插入方法
- 实现 OaProjectScheduleStepServiceImpl 的 batchInsertNodes 方法
- 新增 TableDataConstantUtil 工具类,提供初始化节点数据- 在 OaProjectScheduleController 中新增 addByProjectId 接口
- 扩展 OaProjectScheduleStep 实体类与 VO/BO 类的字段结构
-优化首次编辑时 endTime 和 originalEndTime 的赋值逻辑
This commit is contained in:
2025-10-21 16:56:13 +08:00
parent ca849102b2
commit 2da9f92395
12 changed files with 691 additions and 2 deletions

View File

@@ -53,4 +53,6 @@ public interface IOaProjectScheduleService {
* @return
*/
boolean complete(OaProjectScheduleBo bo);
Boolean insertByProjectId(OaProjectScheduleBo bo);
}

View File

@@ -1,6 +1,9 @@
package com.ruoyi.oa.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.oa.domain.OaProjectScheduleStep;
import com.ruoyi.oa.domain.bo.BatchBo;
import com.ruoyi.oa.domain.dto.NodeDTO;
import com.ruoyi.oa.domain.vo.OaProjectScheduleStepVo;
import com.ruoyi.oa.domain.bo.OaProjectScheduleStepBo;
import com.ruoyi.common.core.page.TableDataInfo;
@@ -15,7 +18,7 @@ import java.util.List;
* @author hdka
* @date 2025-05-08
*/
public interface IOaProjectScheduleStepService {
public interface IOaProjectScheduleStepService{
/**
* 查询项目进度步骤跟踪
@@ -60,4 +63,6 @@ public interface IOaProjectScheduleStepService {
*/
int changeBatch(BatchBo boList);
void batchInsertNodes(List<NodeDTO> nodeList, Long scheduleId);
}

View File

@@ -2,6 +2,7 @@ package com.ruoyi.oa.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.esotericsoftware.minlog.Log;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.core.page.TableDataInfo;
@@ -13,12 +14,14 @@ import com.ruoyi.oa.domain.OaScheduleTemplate;
import com.ruoyi.oa.domain.OaScheduleTemplateStep;
import com.ruoyi.oa.domain.bo.OaProjectScheduleStepBo;
import com.ruoyi.oa.domain.bo.OaScheduleTemplateStepBo;
import com.ruoyi.oa.domain.dto.NodeDTO;
import com.ruoyi.oa.domain.vo.OaProjectScheduleStepVo;
import com.ruoyi.oa.domain.vo.OaScheduleTemplateStepVo;
import com.ruoyi.oa.domain.vo.OaScheduleTemplateVo;
import com.ruoyi.oa.mapper.OaScheduleTemplateMapper;
import com.ruoyi.oa.service.IOaProjectScheduleStepService;
import com.ruoyi.oa.service.IOaScheduleTemplateStepService;
import com.ruoyi.oa.utils.TableDataConstantUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.oa.domain.bo.OaProjectScheduleBo;
@@ -209,4 +212,22 @@ public class OaProjectScheduleServiceImpl implements IOaProjectScheduleService {
}
return updateByBo(bo);
}
@Override
public Boolean insertByProjectId(OaProjectScheduleBo bo) {
OaProjectSchedule add = BeanUtil.toBean(bo, OaProjectSchedule.class);
validEntityBeforeSave(add);
add.setTemplateId(1L);
int insert = baseMapper.insert(add);
if (insert <= 0) {
return false; // 插入失败直接返回
}
Long scheduleId = add.getScheduleId();
if (scheduleId == null) {
throw new RuntimeException("插入项目进度表后未获取到主键");
}
projectScheduleStepService.batchInsertNodes(TableDataConstantUtil.getTableData(), scheduleId);
Log.info("项目进度节点批量插入成功");
return true;
}
}

View File

@@ -3,6 +3,8 @@ package com.ruoyi.oa.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.common.core.mapper.BaseMapperPlus;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
@@ -11,8 +13,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.oa.domain.OaProjectSchedule;
import com.ruoyi.oa.domain.bo.BatchBo;
import com.ruoyi.oa.domain.dto.NodeDTO;
import com.ruoyi.oa.mapper.OaProjectScheduleMapper;
import lombok.RequiredArgsConstructor;
import org.flowable.job.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import com.ruoyi.oa.domain.bo.OaProjectScheduleStepBo;
import com.ruoyi.oa.domain.vo.OaProjectScheduleStepVo;
@@ -22,6 +26,8 @@ import com.ruoyi.oa.service.IOaProjectScheduleStepService;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
* 项目进度步骤跟踪Service业务层处理
@@ -99,6 +105,12 @@ public class OaProjectScheduleStepServiceImpl implements IOaProjectScheduleStepS
// 除了做更新还需要编辑文件权限将涉及到的所有文件 都涉及到userId
OaProjectScheduleStep update = BeanUtil.toBean(bo, OaProjectScheduleStep.class);
validEntityBeforeSave(update);
//查询end_time结束时间是不是空 如果是空则证明是第一次修改需要给end_time赋值也就是新的结束时间原来结束时间不变
OaProjectScheduleStep oaProjectScheduleStep = baseMapper.selectOne(new LambdaQueryWrapper<OaProjectScheduleStep>().eq(OaProjectScheduleStep::getTrackId, update.getTrackId()));
if (oaProjectScheduleStep.getEndTime() == null) {
update.setEndTime(bo.getEndTime());
update.setOriginalEndTime(bo.getEndTime());
}
return baseMapper.updateById(update) > 0;
}
@@ -187,4 +199,34 @@ public class OaProjectScheduleStepServiceImpl implements IOaProjectScheduleStepS
return flag;
}
/**
* 批量插入节点数据(按表结构约束设置字段值)
* @param nodeList 代码中定义的表格节点数据需包含tab、一二级节点和规范说明
* @param scheduleId 所属项目进度ID非空必须传入
*/
public void batchInsertNodes(List<NodeDTO> nodeList, Long scheduleId) {
// 步骤序号从1开始递增确保与schedule_id、use_flag、batch_id组合唯一
AtomicInteger stepOrder = new AtomicInteger(1);
List<OaProjectScheduleStep> entities = nodeList.stream().map(node -> {
OaProjectScheduleStep step = new OaProjectScheduleStep();
// 1. 必须设置值的四个核心字段
step.setTabNode(node.getTabNode()); // tab节点
step.setFirstLevelNode(node.getFirstLevelNode()); // 一级节点
step.setSecondLevelNode(node.getSecondLevelNode()); // 二级节点
step.setSpecification(node.getSpecification()); // 规范说明从NodeDTO补充此字段
// 2. 表结构中非空字段(必须设置,否则插入失败)
step.setScheduleId(scheduleId); // 所属项目进度ID非空外部传入
step.setStepOrder((long) stepOrder.getAndIncrement()); // 步骤序号(非空,递增生成)
step.setStepName(node.getStepName());// 步骤名称非空从NodeDTO获取建议用二级节点名
return step;
}).collect(Collectors.toList());
// 批量插入数据库
baseMapper.saveBatch(entities);
}
}