From 101f7a8f8c6ab2c830ca28992f2e14bb4f29bb17 Mon Sep 17 00:00:00 2001
From: buhuazhen <hua100783@gmail.com>
Date: 星期六, 07 三月 2026 11:22:33 +0800
Subject: [PATCH] feat(projectManagement): 优化项目管理计划及节点功能
---
src/main/java/com/ruoyi/basic/service/CustomerFollowUpFileService.java | 3
src/main/resources/mapper/projectManagement/PlanMapper.xml | 15 +-
src/main/java/com/ruoyi/projectManagement/controller/PlanController.java | 49 ++++++++
src/main/java/com/ruoyi/projectManagement/vo/PlanVo.java | 10 +
src/main/java/com/ruoyi/projectManagement/pojo/Plan.java | 8
src/main/java/com/ruoyi/projectManagement/service/PlanService.java | 11 +
src/main/java/com/ruoyi/projectManagement/service/impl/PlanServiceImpl.java | 92 +++++++++++++--
src/main/java/com/ruoyi/projectManagement/vo/PlanNodeVo.java | 35 +++++
src/main/java/com/ruoyi/projectManagement/vo/SavePlanVo.java | 6
src/main/java/com/ruoyi/projectManagement/pojo/PlanNode.java | 31 +++-
src/main/java/com/ruoyi/projectManagement/vo/SavePlanNodeVo.java | 41 ++++++
11 files changed, 264 insertions(+), 37 deletions(-)
diff --git a/src/main/java/com/ruoyi/basic/service/CustomerFollowUpFileService.java b/src/main/java/com/ruoyi/basic/service/CustomerFollowUpFileService.java
index 66e5e2c..968ddba 100644
--- a/src/main/java/com/ruoyi/basic/service/CustomerFollowUpFileService.java
+++ b/src/main/java/com/ruoyi/basic/service/CustomerFollowUpFileService.java
@@ -4,6 +4,7 @@
import com.ruoyi.basic.pojo.CustomerFollowUpFile;
import com.ruoyi.common.vo.SimpleFileVo;
+import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import java.util.List;
@@ -29,7 +30,7 @@
* @param <T>
*/
<T> void fillAttachment(
- @Null List<T> list,
+ @Nullable List<T> list,
@NotNull Function<T, String> getAttachmentIds,
@NotNull BiConsumer<T, List<SimpleFileVo>> setAttachmentList
);
diff --git a/src/main/java/com/ruoyi/projectManagement/controller/PlanController.java b/src/main/java/com/ruoyi/projectManagement/controller/PlanController.java
new file mode 100644
index 0000000..f3a4745
--- /dev/null
+++ b/src/main/java/com/ruoyi/projectManagement/controller/PlanController.java
@@ -0,0 +1,49 @@
+package com.ruoyi.projectManagement.controller;
+
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.projectManagement.service.PlanService;
+import com.ruoyi.projectManagement.vo.SavePlanNodeVo;
+import com.ruoyi.projectManagement.vo.SavePlanVo;
+import com.ruoyi.projectManagement.vo.SearchPlanVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * @author buhuazhen
+ * @date 2026/3/7
+ * @email 3038525872@qq.com
+ */
+@RestController
+@RequestMapping("/projectManagement/plan")
+@Api(value = "PlanController", tags = "椤圭洰绠$悊璁″垝琛�(椤圭洰绠$悊绫诲瀷)")
+@RequiredArgsConstructor
+public class PlanController {
+
+ private final PlanService planService;
+
+ @PostMapping("/save")
+ @ApiOperation("淇濆瓨")
+ public AjaxResult save(@RequestBody @Valid SavePlanVo savePlanVo) {
+ planService.savePlan(savePlanVo);
+ return AjaxResult.success();
+ }
+
+ @PostMapping("/delete/{id}")
+ @ApiOperation("鍒犻櫎")
+ public AjaxResult delete(@PathVariable Long id) {
+ planService.deletePlan(id);
+ return AjaxResult.success();
+ }
+
+ @PostMapping("/listPage")
+ @ApiOperation("鍒嗛〉鍒楄〃")
+ public AjaxResult listPage(@RequestBody SearchPlanVo searchPlanVo) {
+ return AjaxResult.success(planService.searchPlan(searchPlanVo));
+ }
+
+}
diff --git a/src/main/java/com/ruoyi/projectManagement/pojo/Plan.java b/src/main/java/com/ruoyi/projectManagement/pojo/Plan.java
index 3fa3a98..ea62dde 100644
--- a/src/main/java/com/ruoyi/projectManagement/pojo/Plan.java
+++ b/src/main/java/com/ruoyi/projectManagement/pojo/Plan.java
@@ -36,9 +36,9 @@
/**
* 璁″垝鎻忚堪
*/
- @TableField(value = "describe")
+ @TableField(value = "description")
@ApiModelProperty(value="璁″垝鎻忚堪")
- private String describe;
+ private String description;
/**
* 闄勪欢 ,杩涜鍒嗗壊
@@ -73,12 +73,12 @@
*/
@TableField(value = "create_user",fill = FieldFill.INSERT)
@ApiModelProperty(value="鍒涘缓浜�")
- private String createUser;
+ private Integer createUser;
/**
*
*/
@TableField(value = "update_user",fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty(value="鏇存柊浜�")
- private String updateUser;
+ private Integer updateUser;
}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/projectManagement/pojo/PlanNode.java b/src/main/java/com/ruoyi/projectManagement/pojo/PlanNode.java
index 11a5252..eddaf90 100644
--- a/src/main/java/com/ruoyi/projectManagement/pojo/PlanNode.java
+++ b/src/main/java/com/ruoyi/projectManagement/pojo/PlanNode.java
@@ -1,10 +1,9 @@
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 com.baomidou.mybatisplus.annotation.*;
+
import java.io.Serializable;
+import java.time.LocalDateTime;
import java.util.Date;
import lombok.Data;
@@ -19,72 +18,86 @@
*
*/
@TableId(type = IdType.AUTO)
+ @TableField(value = "id")
private Long id;
/**
* 瀵瑰簲id
*/
+ @TableField(value = "project_management_plan_id")
private Long projectManagementPlanId;
/**
* 鎺掑簭
*/
+ @TableField(value = "sort")
private Integer sort;
/**
* 闃舵鍚嶇О
*/
+ @TableField(value = "name")
private String name;
/**
* 璐熻矗浠籌D
*/
+ @TableField(value = "leader_id")
private Long leaderId;
/**
* 璐熻矗浠诲悕绉�
*/
+ @TableField(value = "leader_name")
private String leaderName;
/**
* 棰勮宸ユ湡(澶�)
*/
+ @TableField(value = "estimated_duration")
private Integer estimatedDuration;
/**
- *
+ * 宸ヤ环
*/
+ @TableField(value = "hourly_rate")
private String hourlyRate;
/**
* 浣滀笟鍐呭
*/
+ @TableField(value = "work_content")
private String workContent;
/**
*
*/
+ @TableField(value = "is_delete")
private Integer isDelete;
/**
*
*/
- private Date createTime;
+ @TableField(value = "create_time",fill = FieldFill.INSERT)
+ private LocalDateTime createTime;
/**
*
*/
- private Date updateTime;
+ @TableField(value = "update_time",fill = FieldFill.INSERT_UPDATE)
+ private LocalDateTime updateTime;
/**
*
*/
- private String createUser;
+ @TableField(value = "create_user",fill = FieldFill.INSERT)
+ private Integer createUser;
/**
*
*/
- private String updateUser;
+ @TableField(value = "update_user",fill = FieldFill.INSERT_UPDATE)
+ private Integer updateUser;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
diff --git a/src/main/java/com/ruoyi/projectManagement/service/PlanService.java b/src/main/java/com/ruoyi/projectManagement/service/PlanService.java
index 7eab7d8..de2d38a 100644
--- a/src/main/java/com/ruoyi/projectManagement/service/PlanService.java
+++ b/src/main/java/com/ruoyi/projectManagement/service/PlanService.java
@@ -4,10 +4,13 @@
import com.ruoyi.projectManagement.pojo.Plan;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.projectManagement.vo.PlanVo;
+import com.ruoyi.projectManagement.vo.SavePlanNodeVo;
import com.ruoyi.projectManagement.vo.SavePlanVo;
import com.ruoyi.projectManagement.vo.SearchPlanVo;
+import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Null;
import java.util.List;
/**
@@ -24,11 +27,19 @@
void savePlan(@NotNull SavePlanVo savePlanVo);
/**
+ * 淇濆瓨璁″垝鑺傜偣
+ * @param planId
+ * @param savePlanNodeVos
+ */
+ void savePlanNode(@NotNull Long planId,@Nullable List<SavePlanNodeVo> savePlanNodeVos);
+
+ /**
* 鍒犻櫎椤圭洰绠$悊璁″垝
* @param id
*/
void deletePlan(@NotNull Long id);
+ void deletePlanNode(@Nullable List<Long> ids);
IPage<PlanVo> searchPlan(@NotNull SearchPlanVo searchPlanVo);
}
diff --git a/src/main/java/com/ruoyi/projectManagement/service/impl/PlanServiceImpl.java b/src/main/java/com/ruoyi/projectManagement/service/impl/PlanServiceImpl.java
index 4262f89..6856bb6 100644
--- a/src/main/java/com/ruoyi/projectManagement/service/impl/PlanServiceImpl.java
+++ b/src/main/java/com/ruoyi/projectManagement/service/impl/PlanServiceImpl.java
@@ -1,21 +1,32 @@
package com.ruoyi.projectManagement.service.impl;
import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.lang.Assert;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.basic.service.CustomerFollowUpFileService;
+import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.projectManagement.mapper.PlanMapper;
+import com.ruoyi.projectManagement.mapper.PlanNodeMapper;
import com.ruoyi.projectManagement.pojo.Plan;
+import com.ruoyi.projectManagement.pojo.PlanNode;
import com.ruoyi.projectManagement.service.PlanService;
-import com.ruoyi.projectManagement.vo.PlanVo;
-import com.ruoyi.projectManagement.vo.SavePlanVo;
-import com.ruoyi.projectManagement.vo.SearchPlanVo;
+import com.ruoyi.projectManagement.vo.*;
import lombok.RequiredArgsConstructor;
+import org.jetbrains.annotations.Nullable;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
/**
* @author buhuazhen
@@ -31,6 +42,12 @@
private final CustomerFollowUpFileService customerFollowUpFileService;
+ private final PlanNodeMapper planNodeMapper;
+
+ @Lazy
+ @Autowired
+ private PlanService planService;
+
@Override
@Transactional(rollbackFor = Exception.class)
public void savePlan(SavePlanVo savePlanVo) {
@@ -38,18 +55,55 @@
// 闄勪欢澶勭悊 , 鎷兼帴
String attachments = String.join(",", Optional.ofNullable(savePlanVo.getAttachmentIds()).orElse(Collections.emptyList()));
plan.setAttachment(attachments);
-
-
if (savePlanVo.getId() == null) {
planMapper.insert(plan);
} else {
planMapper.updateById(plan);
}
-
- // todo@ 鑺傜偣淇濆瓨
-
-
+ planService.savePlanNode(plan.getId(), savePlanVo.getSavePlanNodeList());
}
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void savePlanNode(Long planId, @Nullable List<SavePlanNodeVo> savePlanNodeVos) {
+ Assert.notNull(planId, () -> new ServiceException("璁″垝ID涓嶈兘涓虹┖"));
+ if (CollUtil.isEmpty(savePlanNodeVos)) {
+ return;
+ }
+
+ // 鍒犻櫎澶氫綑鑺傜偣
+ List<PlanNode> needDeleteNode = planNodeMapper.selectList(new LambdaQueryWrapper<PlanNode>()
+ .select(PlanNode::getId)
+ .eq(PlanNode::getProjectManagementPlanId, planId)
+ .ne(PlanNode::getId, savePlanNodeVos.get(0).getId())
+ .notIn(PlanNode::getId, savePlanNodeVos.stream().map(SavePlanNodeVo::getId).collect(Collectors.toList())));
+ deletePlanNode(needDeleteNode.stream().map(PlanNode::getId).collect(Collectors.toList()));
+
+ List<PlanNode> planNodes = BeanUtil.copyToList(savePlanNodeVos, PlanNode.class);
+ // 璁剧疆鎺掑簭绱㈠紩
+ IntStream.range(0, savePlanNodeVos.size()).forEach(i -> {
+ planNodes.get(i).setSort(i);
+ planNodes.get(i).setProjectManagementPlanId(planId);
+ if (planNodes.get(i).getId() == null) {
+ planNodeMapper.insert(planNodes.get(i));
+ } else {
+ planNodeMapper.updateById(planNodes.get(i));
+ }
+ });
+ }
+
+ private List<PlanNode> getPlanNodeByPlanId(Long planId) {
+ return planNodeMapper.selectList(new LambdaQueryWrapper<PlanNode>()
+ .eq(PlanNode::getIsDelete, 0)
+ .eq(PlanNode::getProjectManagementPlanId, planId));
+ }
+
+ private List<PlanNode> getPlanNodeByPlanIds(List<Long> planIds) {
+ return planNodeMapper.selectList(new LambdaQueryWrapper<PlanNode>()
+ .eq(PlanNode::getIsDelete, 0)
+ .in(PlanNode::getProjectManagementPlanId, planIds));
+ }
+
@Override
@Transactional(rollbackFor = Exception.class)
@@ -58,9 +112,18 @@
new LambdaUpdateWrapper<Plan>()
.eq(Plan::getId, id)
.set(Plan::getIsDelete, 1));
- // todo@ 瀵瑰簲鑺傜偣鍏ㄩ儴鍒犻櫎
+ planService.deletePlanNode(getPlanNodeByPlanId(id).stream().map(PlanNode::getId).collect(Collectors.toList()));
+ }
-
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void deletePlanNode(List<Long> ids) {
+ if (CollUtil.isNotEmpty(ids)) {
+ planNodeMapper.update(null,
+ new LambdaUpdateWrapper<PlanNode>()
+ .in(PlanNode::getId, ids)
+ .set(PlanNode::getIsDelete, 1));
+ }
}
@Override
@@ -69,8 +132,11 @@
IPage<PlanVo> resultPage = planIPage.convert(plan -> BeanUtil.copyProperties(plan, PlanVo.class));
// 鏂囦欢鑾峰彇
customerFollowUpFileService.fillAttachment(resultPage.getRecords(), PlanVo::getAttachment, PlanVo::setAttachmentList);
- // todo@ node 鑺傜偣鑾峰彇
-
+ Map<Long, List<PlanNodeVo>> collect = getPlanNodeByPlanIds(resultPage.getRecords().stream().map(PlanVo::getId).collect(Collectors.toList()))
+ .stream()
+ .map(it -> BeanUtil.copyProperties(it, PlanNodeVo.class))
+ .collect(Collectors.groupingBy(PlanNodeVo::getProjectManagementPlanId, Collectors.toList()));
+ resultPage.getRecords().forEach(planVo -> planVo.setPlanNodeList(collect.getOrDefault(planVo.getId(), Collections.emptyList())));
return resultPage;
}
diff --git a/src/main/java/com/ruoyi/projectManagement/vo/PlanNodeVo.java b/src/main/java/com/ruoyi/projectManagement/vo/PlanNodeVo.java
new file mode 100644
index 0000000..6194755
--- /dev/null
+++ b/src/main/java/com/ruoyi/projectManagement/vo/PlanNodeVo.java
@@ -0,0 +1,35 @@
+package com.ruoyi.projectManagement.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @author buhuazhen
+ * @date 2026/3/7
+ * @email 3038525872@qq.com
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class PlanNodeVo implements Serializable {
+ private Long id;
+
+ private Long projectManagementPlanId;
+
+ private Integer sort;
+
+ private String name;
+
+ private Long leaderId;
+
+ private String leaderName;
+
+ private Integer estimatedDuration;
+
+ private String hourlyRate;
+
+ private String workContent;
+}
diff --git a/src/main/java/com/ruoyi/projectManagement/vo/PlanVo.java b/src/main/java/com/ruoyi/projectManagement/vo/PlanVo.java
index 9ee78e9..492435e 100644
--- a/src/main/java/com/ruoyi/projectManagement/vo/PlanVo.java
+++ b/src/main/java/com/ruoyi/projectManagement/vo/PlanVo.java
@@ -1,10 +1,12 @@
package com.ruoyi.projectManagement.vo;
+import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.ruoyi.common.vo.SimpleFileVo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
+import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDateTime;
@@ -25,7 +27,7 @@
private String name;
- private String describe;
+ private String description;
// 闄勪欢
private List<SimpleFileVo> attachmentList;
@@ -33,8 +35,14 @@
@JsonIgnore
private String attachment;
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
+ private List<PlanNodeVo> planNodeList;
+
}
diff --git a/src/main/java/com/ruoyi/projectManagement/vo/SavePlanNodeVo.java b/src/main/java/com/ruoyi/projectManagement/vo/SavePlanNodeVo.java
new file mode 100644
index 0000000..3e98742
--- /dev/null
+++ b/src/main/java/com/ruoyi/projectManagement/vo/SavePlanNodeVo.java
@@ -0,0 +1,41 @@
+package com.ruoyi.projectManagement.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @author buhuazhen
+ * @date 2026/3/7
+ * @email 3038525872@qq.com
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class SavePlanNodeVo implements Serializable {
+ private Long id;
+
+ private Long projectManagementPlanId;
+
+ private Integer sort;
+
+ @NotBlank
+ private String name;
+
+ @NotNull
+ private Long leaderId;
+
+ @NotBlank
+ private String leaderName;
+
+ private Integer estimatedDuration;
+
+ private String hourlyRate;
+
+ private String workContent;
+
+}
diff --git a/src/main/java/com/ruoyi/projectManagement/vo/SavePlanVo.java b/src/main/java/com/ruoyi/projectManagement/vo/SavePlanVo.java
index 5c79940..906184b 100644
--- a/src/main/java/com/ruoyi/projectManagement/vo/SavePlanVo.java
+++ b/src/main/java/com/ruoyi/projectManagement/vo/SavePlanVo.java
@@ -4,6 +4,7 @@
import lombok.Data;
import lombok.NoArgsConstructor;
+import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.util.List;
@@ -22,10 +23,11 @@
@NotBlank
private String name;
@NotBlank
- private String describe;
+ private String description;
private List<String> attachmentIds;
-
+ @Valid
+ private List<SavePlanNodeVo> savePlanNodeList;
}
diff --git a/src/main/resources/mapper/projectManagement/PlanMapper.xml b/src/main/resources/mapper/projectManagement/PlanMapper.xml
index 3578358..de652e7 100644
--- a/src/main/resources/mapper/projectManagement/PlanMapper.xml
+++ b/src/main/resources/mapper/projectManagement/PlanMapper.xml
@@ -7,17 +7,17 @@
<resultMap id="BaseResultMap" type="com.ruoyi.projectManagement.pojo.Plan">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="name" column="name" jdbcType="VARCHAR"/>
- <result property="describe" column="describe" jdbcType="VARCHAR"/>
+ <result property="description" column="description" jdbcType="VARCHAR"/>
<result property="attachment" column="attachment" jdbcType="VARCHAR"/>
- <result property="is_delete" column="is_delete" jdbcType="INTEGER"/>
- <result property="create_time" column="create_time" jdbcType="TIMESTAMP"/>
- <result property="update_time" column="update_time" jdbcType="TIMESTAMP"/>
- <result property="create_user" column="create_user" jdbcType="VARCHAR"/>
- <result property="update_user" column="update_user" jdbcType="VARCHAR"/>
+ <result property="isDelete" column="is_delete" jdbcType="INTEGER"/>
+ <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+ <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
+ <result property="createUser" column="create_user" jdbcType="VARCHAR"/>
+ <result property="updateUser" column="update_user" jdbcType="VARCHAR"/>
</resultMap>
<sql id="Base_Column_List">
- id,name,describe,
+ id,name,description,
attachment,is_delete,create_time,
update_time,create_user,update_user
</sql>
@@ -25,6 +25,7 @@
<select id="selectPlanPage" resultMap="BaseResultMap">
select t1.*
from project_management_plan as t1
+ where t1.is_delete = 0
order by t1.create_time desc
</select>
</mapper>
--
Gitblit v1.9.3