From b36dfcb807af748dabdbc76a134b0667196563f6 Mon Sep 17 00:00:00 2001
From: buhuazhen <hua100783@gmail.com>
Date: 星期二, 10 三月 2026 14:37:43 +0800
Subject: [PATCH] feat(projectManagement): 完善项目信息管理功能

---
 src/main/java/com/ruoyi/projectManagement/service/impl/handle/ShippingAddressHandleService.java |   11 +
 src/main/java/com/ruoyi/projectManagement/service/impl/handle/InfoHandleService.java            |   14 +
 src/main/java/com/ruoyi/projectManagement/vo/SearchInfoVo.java                                  |   32 ++++
 src/main/java/com/ruoyi/projectManagement/service/impl/handle/ContractInfoHandleService.java    |   11 +
 src/main/java/com/ruoyi/projectManagement/service/impl/InfoServiceImpl.java                     |   96 +++++++++++
 src/main/java/com/ruoyi/projectManagement/pojo/ShippingAddress.java                             |    7 
 src/main/java/com/ruoyi/projectManagement/vo/InfoVo.java                                        |   24 +++
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java                          |    8 +
 src/main/resources/mapper/projectManagement/InfoMapper.xml                                      |   23 ++
 src/main/java/com/ruoyi/projectManagement/controller/InfoController.java                        |   38 ++++
 src/main/java/com/ruoyi/common/enums/IsDeleteEnum.java                                          |   22 ++
 src/main/java/com/ruoyi/projectManagement/dto/UpdateStateInfo.java                              |   31 +++
 src/main/java/com/ruoyi/projectManagement/pojo/Plan.java                                        |    6 
 src/main/java/com/ruoyi/common/config/MybatisHandler.java                                       |    5 
 src/main/java/com/ruoyi/projectManagement/mapper/InfoMapper.java                                |    5 
 src/main/java/com/ruoyi/projectManagement/vo/SavePlanVo.java                                    |    2 
 src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java                                  |    3 
 src/main/java/com/ruoyi/projectManagement/pojo/PlanNode.java                                    |    6 
 src/main/java/com/ruoyi/projectManagement/vo/SavePlanNodeVo.java                                |    6 
 src/main/java/com/ruoyi/projectManagement/service/InfoService.java                              |   34 ++++
 src/main/java/com/ruoyi/projectManagement/dto/SaveInfoDto.java                                  |   18 +
 src/main/java/com/ruoyi/common/enums/PlanStageEnum.java                                         |    9 +
 src/main/java/com/ruoyi/common/enums/BaseEnum.java                                              |    1 
 src/main/java/com/ruoyi/projectManagement/pojo/Info.java                                        |    6 
 src/main/java/com/ruoyi/projectManagement/pojo/ContractInfo.java                                |    6 
 src/main/java/com/ruoyi/projectManagement/vo/ListInfoVo.java                                    |   42 +++++
 26 files changed, 451 insertions(+), 15 deletions(-)

diff --git a/src/main/java/com/ruoyi/common/config/MybatisHandler.java b/src/main/java/com/ruoyi/common/config/MybatisHandler.java
index 3cdd218..891410f 100644
--- a/src/main/java/com/ruoyi/common/config/MybatisHandler.java
+++ b/src/main/java/com/ruoyi/common/config/MybatisHandler.java
@@ -14,9 +14,11 @@
     public void insertFill(MetaObject metaObject) {
         Integer userId = null;
         Long tenantId = null;
+        String userName = null;
         try {
             userId = SecurityUtils.getUserId().intValue();
             tenantId = SecurityUtils.getLoginUser().getTenantId();
+            userName = SecurityUtils.getUsername();
         } catch (Exception ignored) {
         }
         this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
@@ -25,6 +27,9 @@
         this.strictInsertFill(metaObject, "updateUser", Integer.class, userId);
         this.strictInsertFill(metaObject, "createUser", Long.class, userId == null ? 0 : userId.longValue());
         this.strictInsertFill(metaObject, "updateUser", Long.class, userId == null ? 0 : userId.longValue());
+        this.strictInsertFill(metaObject, "createUserName", String.class, userName);
+        this.strictInsertFill(metaObject, "updateUserName", String.class, userName);
+
         this.strictInsertFill(metaObject, "tenantId", Long.class, tenantId);
     }
 
diff --git a/src/main/java/com/ruoyi/common/enums/BaseEnum.java b/src/main/java/com/ruoyi/common/enums/BaseEnum.java
index cf84dde..7f5b538 100644
--- a/src/main/java/com/ruoyi/common/enums/BaseEnum.java
+++ b/src/main/java/com/ruoyi/common/enums/BaseEnum.java
@@ -1,6 +1,7 @@
 package com.ruoyi.common.enums;
 
 
+import com.baomidou.mybatisplus.annotation.EnumValue;
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonValue;
 
diff --git a/src/main/java/com/ruoyi/common/enums/IsDeleteEnum.java b/src/main/java/com/ruoyi/common/enums/IsDeleteEnum.java
new file mode 100644
index 0000000..8d4061b
--- /dev/null
+++ b/src/main/java/com/ruoyi/common/enums/IsDeleteEnum.java
@@ -0,0 +1,22 @@
+package com.ruoyi.common.enums;
+
+import lombok.Getter;
+
+/**
+ * @author buhuazhen
+ * @date 2026/3/10
+ * @email 3038525872@qq.com
+ */
+@Getter
+public enum IsDeleteEnum implements BaseEnum<Integer> {
+    NOT_DELETED(0, "鏈垹闄�"),
+    DELETED(1, "宸插垹闄�");
+
+    private final Integer code;
+    private final String value;
+
+    IsDeleteEnum(Integer code, String value) {
+        this.code = code;
+        this.value = value;
+    }
+}
diff --git a/src/main/java/com/ruoyi/common/enums/PlanStageEnum.java b/src/main/java/com/ruoyi/common/enums/PlanStageEnum.java
index e7aedb9..d2e812d 100644
--- a/src/main/java/com/ruoyi/common/enums/PlanStageEnum.java
+++ b/src/main/java/com/ruoyi/common/enums/PlanStageEnum.java
@@ -1,5 +1,6 @@
 package com.ruoyi.common.enums;
 
+import com.baomidou.mybatisplus.annotation.EnumValue;
 import com.fasterxml.jackson.annotation.JsonCreator;
 import lombok.Getter;
 
@@ -15,12 +16,18 @@
     TO_BEGIN(1, "寰呭紑濮�"),
     ON_GOING(2, "杩涜涓�"),
     ENDED(3, "宸茬粨鏉�");
-
+    @EnumValue
     private final Integer code;
+
     private final String value;
 
     PlanStageEnum(Integer code, String value) {
         this.code = code;
         this.value = value;
     }
+
+    @JsonCreator
+    public static PlanStageEnum fromCode(Integer code) {
+        return BaseEnum.fromCode(PlanStageEnum.class, code);
+    }
 }
diff --git a/src/main/java/com/ruoyi/projectManagement/controller/InfoController.java b/src/main/java/com/ruoyi/projectManagement/controller/InfoController.java
index 23af4cc..85a7070 100644
--- a/src/main/java/com/ruoyi/projectManagement/controller/InfoController.java
+++ b/src/main/java/com/ruoyi/projectManagement/controller/InfoController.java
@@ -1,14 +1,14 @@
 package com.ruoyi.projectManagement.controller;
 
 import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.projectManagement.dto.UpdateStateInfo;
 import com.ruoyi.projectManagement.service.InfoService;
 import com.ruoyi.projectManagement.vo.SaveInfoVo;
+import com.ruoyi.projectManagement.vo.SearchInfoVo;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
 
@@ -26,8 +26,38 @@
     private final InfoService infoService;
 
     @PostMapping("/save")
+    @ApiOperation("淇濆瓨")
     public AjaxResult save(@RequestBody @Valid SaveInfoVo saveInfoVo) {
         infoService.save(saveInfoVo);
         return AjaxResult.success();
     }
+
+    @PostMapping("/updateStatus")
+    @ApiOperation("淇敼鐘舵��")
+    public AjaxResult updateStatus(@RequestBody @Valid UpdateStateInfo updateStateInfo){
+        infoService.updateStatus(updateStateInfo);
+        return AjaxResult.success();
+    }
+
+    @PostMapping("/delete/{id}")
+    @ApiOperation("鍒犻櫎")
+    public AjaxResult delete(@PathVariable Long id) {
+        infoService.deleteInfo(id);
+        return AjaxResult.success();
+    }
+
+    @PostMapping("/listPage")
+    @ApiOperation("鍒嗛〉鍒楄〃")
+    public AjaxResult listPage(@RequestBody @Valid SearchInfoVo vo) {
+        return AjaxResult.success(infoService.searchListInfo(vo));
+    }
+
+
+    @PostMapping("/{id}")
+    @ApiOperation("璇︽儏")
+    public AjaxResult getInfoById(@PathVariable Long id) {
+        return AjaxResult.success(infoService.getInfoById(id));
+    }
+
+
 }
diff --git a/src/main/java/com/ruoyi/projectManagement/dto/SaveInfoDto.java b/src/main/java/com/ruoyi/projectManagement/dto/SaveInfoDto.java
index aa1d99c..0b878ef 100644
--- a/src/main/java/com/ruoyi/projectManagement/dto/SaveInfoDto.java
+++ b/src/main/java/com/ruoyi/projectManagement/dto/SaveInfoDto.java
@@ -1,6 +1,8 @@
 package com.ruoyi.projectManagement.dto;
 
 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;
@@ -24,7 +26,7 @@
 public class SaveInfoDto implements Serializable {
     private Long id;
     private String no;
-    @NotBlank
+    @NotBlank(message = "title涓虹┖")
     private String title;
     private Long clientId;
     private String clientName;
@@ -35,7 +37,7 @@
     @DateTimeFormat(pattern = "yyyy-MM-dd")
     private LocalDate establishTime;
     // 椤圭洰绫诲瀷 id
-    @NotNull
+    @NotNull(message = "projectManagementPlanId涓虹┖")
     private Long projectManagementPlanId;
 
     private String source;
@@ -43,7 +45,7 @@
     private Long managerId;
     private String managerName;
     private Long salesmanId;
-        private String salesmanName;
+    private String salesmanName;
 
     @JsonFormat(pattern = "yyyy-MM-dd")
     @DateTimeFormat(pattern = "yyyy-MM-dd")
@@ -61,6 +63,9 @@
     @DateTimeFormat(pattern = "yyyy-MM-dd")
     private LocalDate actualEndTime;
 
+    // 瀹℃牳鐘舵��
+    private Integer reviewStatus;
+
     // 椤圭洰鐘舵��
     private Integer status;
 
@@ -76,7 +81,14 @@
 
     private String remark;
 
+    @JsonIgnore
+    private String attachment;
+
+    private List<SimpleFileVo> attachmentList;
+
     private List<String> attachmentIds; // 闄勪欢ids
 
     private List<TeamDto> teamList;
+
+    private List<PlanStageDto> planStage;
 }
diff --git a/src/main/java/com/ruoyi/projectManagement/dto/UpdateStateInfo.java b/src/main/java/com/ruoyi/projectManagement/dto/UpdateStateInfo.java
new file mode 100644
index 0000000..162a1d6
--- /dev/null
+++ b/src/main/java/com/ruoyi/projectManagement/dto/UpdateStateInfo.java
@@ -0,0 +1,31 @@
+package com.ruoyi.projectManagement.dto;
+
+import com.ruoyi.common.enums.PlanStageEnum;
+import com.ruoyi.common.enums.ReviewStatusEnum;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @author buhuazhen
+ * @date 2026/3/10
+ * @email 3038525872@qq.com
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class UpdateStateInfo implements Serializable {
+    @NotNull(message = "id涓嶈兘涓虹┖")
+    private Long id;
+
+    // 瀹℃壒鐘舵��
+    private ReviewStatusEnum reviewStatus;
+
+    // 杩涘害鐘舵��
+    private PlanStageEnum stage;
+
+
+}
diff --git a/src/main/java/com/ruoyi/projectManagement/mapper/InfoMapper.java b/src/main/java/com/ruoyi/projectManagement/mapper/InfoMapper.java
index 6a23232..5648e78 100644
--- a/src/main/java/com/ruoyi/projectManagement/mapper/InfoMapper.java
+++ b/src/main/java/com/ruoyi/projectManagement/mapper/InfoMapper.java
@@ -1,7 +1,11 @@
 package com.ruoyi.projectManagement.mapper;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.projectManagement.pojo.Info;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.projectManagement.vo.ListInfoVo;
+import com.ruoyi.projectManagement.vo.SearchInfoVo;
+import org.apache.ibatis.annotations.Param;
 
 /**
 * @author buhuazhen
@@ -11,6 +15,7 @@
 */
 public interface InfoMapper extends BaseMapper<Info> {
 
+    Page<ListInfoVo> searchListInfo(@Param("vo") SearchInfoVo vo);
 }
 
 
diff --git a/src/main/java/com/ruoyi/projectManagement/pojo/ContractInfo.java b/src/main/java/com/ruoyi/projectManagement/pojo/ContractInfo.java
index aab582f..d568a02 100644
--- a/src/main/java/com/ruoyi/projectManagement/pojo/ContractInfo.java
+++ b/src/main/java/com/ruoyi/projectManagement/pojo/ContractInfo.java
@@ -127,6 +127,12 @@
     @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
     private LocalDateTime updateTime;
 
+    @TableField(value = "create_user_name", fill = FieldFill.INSERT)
+    private String createUserName;
+
+    @TableField(value = "update_user_name", fill = FieldFill.INSERT_UPDATE)
+    private String updateUserName;
+
     @TableField(exist = false)
     private static final long serialVersionUID = 1L;
 }
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/projectManagement/pojo/Info.java b/src/main/java/com/ruoyi/projectManagement/pojo/Info.java
index a6e8ed5..999e787 100644
--- a/src/main/java/com/ruoyi/projectManagement/pojo/Info.java
+++ b/src/main/java/com/ruoyi/projectManagement/pojo/Info.java
@@ -207,4 +207,10 @@
 
     @TableField(value = "team",typeHandler = JacksonTypeHandler.class)
     private List<TeamDto> team;
+
+    @TableField(value = "create_user_name", fill = FieldFill.INSERT)
+    private String createUserName;
+
+    @TableField(value = "update_user_name", fill = FieldFill.INSERT_UPDATE)
+    private String updateUserName;
 }
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/projectManagement/pojo/Plan.java b/src/main/java/com/ruoyi/projectManagement/pojo/Plan.java
index ea62dde..fd63a03 100644
--- a/src/main/java/com/ruoyi/projectManagement/pojo/Plan.java
+++ b/src/main/java/com/ruoyi/projectManagement/pojo/Plan.java
@@ -81,4 +81,10 @@
     @TableField(value = "update_user",fill = FieldFill.INSERT_UPDATE)
     @ApiModelProperty(value="鏇存柊浜�")
     private Integer updateUser;
+
+    @TableField(value = "create_user_name", fill = FieldFill.INSERT)
+    private String createUserName;
+
+    @TableField(value = "update_user_name", fill = FieldFill.INSERT_UPDATE)
+    private String updateUserName;
 }
\ 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 eddaf90..3d9d9b1 100644
--- a/src/main/java/com/ruoyi/projectManagement/pojo/PlanNode.java
+++ b/src/main/java/com/ruoyi/projectManagement/pojo/PlanNode.java
@@ -99,6 +99,12 @@
     @TableField(value = "update_user",fill = FieldFill.INSERT_UPDATE)
     private Integer updateUser;
 
+    @TableField(value = "create_user_name", fill = FieldFill.INSERT)
+    private String createUserName;
+
+    @TableField(value = "update_user_name", fill = FieldFill.INSERT_UPDATE)
+    private String updateUserName;
+
     @TableField(exist = false)
     private static final long serialVersionUID = 1L;
 }
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/projectManagement/pojo/ShippingAddress.java b/src/main/java/com/ruoyi/projectManagement/pojo/ShippingAddress.java
index 9b4a527..ffc6940 100644
--- a/src/main/java/com/ruoyi/projectManagement/pojo/ShippingAddress.java
+++ b/src/main/java/com/ruoyi/projectManagement/pojo/ShippingAddress.java
@@ -70,6 +70,13 @@
     @TableField(value = "project_management_info_id")
     private Long projectManagementInfoId;
 
+
+    @TableField(value = "create_user_name", fill = FieldFill.INSERT)
+    private String createUserName;
+
+    @TableField(value = "update_user_name", fill = FieldFill.INSERT_UPDATE)
+    private String updateUserName;
+
     @TableField(exist = false)
     private static final long serialVersionUID = 1L;
 }
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/projectManagement/service/InfoService.java b/src/main/java/com/ruoyi/projectManagement/service/InfoService.java
index b796533..ac3d8e8 100644
--- a/src/main/java/com/ruoyi/projectManagement/service/InfoService.java
+++ b/src/main/java/com/ruoyi/projectManagement/service/InfoService.java
@@ -1,6 +1,11 @@
 package com.ruoyi.projectManagement.service;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.projectManagement.dto.UpdateStateInfo;
+import com.ruoyi.projectManagement.vo.InfoVo;
+import com.ruoyi.projectManagement.vo.ListInfoVo;
 import com.ruoyi.projectManagement.vo.SaveInfoVo;
+import com.ruoyi.projectManagement.vo.SearchInfoVo;
 
 import javax.validation.constraints.NotNull;
 
@@ -10,6 +15,35 @@
  * @email 3038525872@qq.com
  */
 public interface InfoService {
+    /**
+     * 淇濆瓨椤圭洰淇℃伅
+     *
+     * @param saveInfoVo 淇濆瓨椤圭洰淇℃伅鐨凞TO
+     */
     void save(@NotNull SaveInfoVo saveInfoVo);
 
+    /**
+     * 鏇存柊椤圭洰淇℃伅鐘舵��
+     *
+     * @param updateStateInfo 鏇存柊椤圭洰淇℃伅鐘舵�佺殑DTO
+     */
+    void updateStatus(@NotNull UpdateStateInfo updateStateInfo);
+
+    /**
+     * 鍒犻櫎椤圭洰淇℃伅
+     *
+     * @param id 椤圭洰淇℃伅ID
+     */
+    void deleteInfo(@NotNull Long id);
+
+    /**
+     * 鍒嗛〉鏌ヨ椤圭洰淇℃伅鍒楄〃
+     *
+     * @param vo 鏌ヨ鏉′欢
+     * @return 椤圭洰淇℃伅鍒楄〃
+     */
+    Page<ListInfoVo> searchListInfo(@NotNull SearchInfoVo vo);
+
+
+    InfoVo getInfoById(@NotNull Long id);
 }
diff --git a/src/main/java/com/ruoyi/projectManagement/service/impl/InfoServiceImpl.java b/src/main/java/com/ruoyi/projectManagement/service/impl/InfoServiceImpl.java
index e6bd8c5..2c21be4 100644
--- a/src/main/java/com/ruoyi/projectManagement/service/impl/InfoServiceImpl.java
+++ b/src/main/java/com/ruoyi/projectManagement/service/impl/InfoServiceImpl.java
@@ -1,15 +1,32 @@
 package com.ruoyi.projectManagement.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.enums.IsDeleteEnum;
 import com.ruoyi.common.enums.SaleEnum;
+import com.ruoyi.projectManagement.dto.ContractInfoDto;
+import com.ruoyi.projectManagement.dto.SaveInfoDto;
+import com.ruoyi.projectManagement.dto.ShippingAddressDto;
+import com.ruoyi.projectManagement.dto.UpdateStateInfo;
+import com.ruoyi.projectManagement.mapper.InfoMapper;
+import com.ruoyi.projectManagement.pojo.Info;
 import com.ruoyi.projectManagement.service.InfoService;
 import com.ruoyi.projectManagement.service.impl.handle.ContractInfoHandleService;
 import com.ruoyi.projectManagement.service.impl.handle.InfoHandleService;
 import com.ruoyi.projectManagement.service.impl.handle.ShippingAddressHandleService;
+import com.ruoyi.projectManagement.vo.InfoVo;
+import com.ruoyi.projectManagement.vo.ListInfoVo;
 import com.ruoyi.projectManagement.vo.SaveInfoVo;
+import com.ruoyi.projectManagement.vo.SearchInfoVo;
+import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import com.ruoyi.sales.service.ISalesLedgerService;
 import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
 
 /**
  * @author buhuazhen
@@ -21,17 +38,90 @@
 @Transactional(readOnly = true)
 public class InfoServiceImpl implements InfoService {
     private final InfoHandleService infoHandleService;
+    private final InfoMapper infoMapper;
     private final ContractInfoHandleService contractInfoHandleService;
     private final ShippingAddressHandleService shippingAddressHandleService;
     private final ISalesLedgerService salesLedgerService;
+
 
     @Transactional(rollbackFor = Exception.class)
     @Override
     public void save(SaveInfoVo saveInfoVo) {
         // 淇濆瓨涓讳俊鎭�
         Long infoId = infoHandleService.save(saveInfoVo.getInfo());
-        shippingAddressHandleService.save(infoId, saveInfoVo.getShippingAddress());
-        contractInfoHandleService.save(infoId, saveInfoVo.getContractInfo());
-        salesLedgerService.handleSalesLedgerProducts(infoId, saveInfoVo.getSalesLedgerProductList(), SaleEnum.MANAGEMENT);
+        if(saveInfoVo.getShippingAddress() != null){
+            shippingAddressHandleService.save(infoId, saveInfoVo.getShippingAddress());
+        }
+        if(saveInfoVo.getContractInfo() != null){
+            contractInfoHandleService.save(infoId, saveInfoVo.getContractInfo());
+        }
+        if(saveInfoVo.getSalesLedgerProductList() != null){
+            salesLedgerService.handleSalesLedgerProducts(infoId, saveInfoVo.getSalesLedgerProductList(), SaleEnum.MANAGEMENT);
+        }
     }
+
+    @Override
+    @Transactional
+    public void updateStatus(UpdateStateInfo updateStateInfo) {
+        Info info = new Info();
+        info.setId(updateStateInfo.getId());
+        // 瀹℃壒鐘舵��
+        if(updateStateInfo.getReviewStatus() != null){
+            info.setReviewStatus(updateStateInfo.getReviewStatus().getCode());
+        }
+
+        // 杩涘害鐘舵��
+        if(updateStateInfo.getStage() != null){
+            info.setStatus(updateStateInfo.getStage().getCode());
+        }
+
+        infoMapper.updateById(info);
+    }
+
+    @Override
+    @Transactional
+    public void deleteInfo(Long id) {
+        LambdaUpdateWrapper<Info> updateWrapper = new LambdaUpdateWrapper<Info>();
+        updateWrapper.eq(Info::getId, id);
+        updateWrapper.set(Info::getIsDelete, IsDeleteEnum.DELETED.getCode());
+
+        // 瀵瑰簲闄勮〃淇℃伅鏄惁鍒犻櫎寰呯‘瀹氾紙鍥犱负鍚庣画鍙兘浼氳繘琛屽紩鐢ㄦ墍浠ュ厛涓嶅垹闄�
+    }
+
+    @Override
+    public Page<ListInfoVo> searchListInfo(SearchInfoVo vo) {
+        Page<ListInfoVo> listInfoVoPage = infoMapper.searchListInfo(vo);
+
+
+        return listInfoVoPage;
+    }
+
+    @Override
+    @SneakyThrows
+    public InfoVo getInfoById(Long id) {
+
+        CompletableFuture<SaveInfoDto> infoFuture = CompletableFuture.supplyAsync(() -> infoHandleService.getInfoById(id));
+        CompletableFuture<ContractInfoDto> contractFuture = CompletableFuture.supplyAsync(() -> contractInfoHandleService.getByInfoId(id));
+        CompletableFuture<ShippingAddressDto> shippingFuture = CompletableFuture.supplyAsync(() -> shippingAddressHandleService.getByInfoId(id));
+        CompletableFuture<List<SalesLedgerProduct>> listCompletableFuture = CompletableFuture.supplyAsync(() -> salesLedgerService.getSalesLedgerProductListByRelateId(id,SaleEnum.MANAGEMENT));
+
+        // 鍟嗗搧
+
+        // 绛夊緟鎵�鏈夊紓姝ュ畬鎴�
+        CompletableFuture.allOf(infoFuture, contractFuture, shippingFuture).join();
+
+        SaveInfoDto info = infoFuture.get();
+        ContractInfoDto contract = contractFuture.get();
+        ShippingAddressDto shippingAddress = shippingFuture.get();
+        List<SalesLedgerProduct> salesLedgerProductList = listCompletableFuture.get();
+
+        InfoVo vo = new InfoVo();
+        vo.setInfo(info);
+        vo.setContractInfo(contract);
+        vo.setShippingAddress(shippingAddress);
+        vo.setSalesLedgerProductList(salesLedgerProductList);
+
+        return vo;
+    }
+
 }
diff --git a/src/main/java/com/ruoyi/projectManagement/service/impl/handle/ContractInfoHandleService.java b/src/main/java/com/ruoyi/projectManagement/service/impl/handle/ContractInfoHandleService.java
index 18bdc96..59cbb9f 100644
--- a/src/main/java/com/ruoyi/projectManagement/service/impl/handle/ContractInfoHandleService.java
+++ b/src/main/java/com/ruoyi/projectManagement/service/impl/handle/ContractInfoHandleService.java
@@ -1,6 +1,7 @@
 package com.ruoyi.projectManagement.service.impl.handle;
 
 import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.ruoyi.projectManagement.dto.ContractInfoDto;
 import com.ruoyi.projectManagement.mapper.ContractInfoMapper;
 import com.ruoyi.projectManagement.pojo.ContractInfo;
@@ -34,4 +35,14 @@
             contractInfoMapper.updateById(contractInfo);
         }
     }
+
+    public ContractInfoDto getByInfoId(@NotNull Long id) {
+        LambdaQueryWrapper<ContractInfo> queryWrapper = new LambdaQueryWrapper<ContractInfo>();
+        queryWrapper.eq(ContractInfo::getProjectManagementInfoId, id);
+        queryWrapper.eq(ContractInfo::getIsDelete, 0);
+        queryWrapper.last("limit 1");
+        ContractInfo contractInfo = contractInfoMapper.selectOne(queryWrapper);
+        return BeanUtil.copyProperties(contractInfo, ContractInfoDto.class);
+    }
+
 }
diff --git a/src/main/java/com/ruoyi/projectManagement/service/impl/handle/InfoHandleService.java b/src/main/java/com/ruoyi/projectManagement/service/impl/handle/InfoHandleService.java
index 74c392d..4f00fa6 100644
--- a/src/main/java/com/ruoyi/projectManagement/service/impl/handle/InfoHandleService.java
+++ b/src/main/java/com/ruoyi/projectManagement/service/impl/handle/InfoHandleService.java
@@ -4,6 +4,8 @@
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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.common.utils.EnumUtil;
@@ -14,6 +16,7 @@
 import com.ruoyi.projectManagement.pojo.PlanNode;
 import com.ruoyi.projectManagement.service.PlanService;
 import com.ruoyi.projectManagement.service.impl.PlanServiceImpl;
+import com.ruoyi.projectManagement.vo.PlanVo;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
@@ -40,6 +43,8 @@
 
     private final PlanService planService;
 
+    private final CustomerFollowUpFileService customerFollowUpFileService;
+
     @Transactional(rollbackFor = Exception.class)
     public Long save(@NotNull SaveInfoDto saveInfoDto){
         Info info = BeanUtil.copyProperties(saveInfoDto, Info.class);
@@ -66,6 +71,15 @@
         return info.getId();
     }
 
+    public SaveInfoDto getInfoById(@NotNull Long id){
+        Info info = infoMapper.selectById(id);
+        SaveInfoDto saveInfoDto = BeanUtil.copyProperties(info, SaveInfoDto.class);
+        // 闄勪欢澶勭悊
+        saveInfoDto.setTeamList(info.getTeam());
+        customerFollowUpFileService.fillAttachment(Lists.newArrayList(saveInfoDto), SaveInfoDto::getAttachment, SaveInfoDto::setAttachmentList);
+        return saveInfoDto;
+    }
+
 
     private List<PlanStageDto> getPlanStageList(@NotNull Long planId) {
         List<PlanNode> planNodeByPlanId = planService.getPlanNodeByPlanId(planId);
diff --git a/src/main/java/com/ruoyi/projectManagement/service/impl/handle/ShippingAddressHandleService.java b/src/main/java/com/ruoyi/projectManagement/service/impl/handle/ShippingAddressHandleService.java
index 6dba016..f5e6cf6 100644
--- a/src/main/java/com/ruoyi/projectManagement/service/impl/handle/ShippingAddressHandleService.java
+++ b/src/main/java/com/ruoyi/projectManagement/service/impl/handle/ShippingAddressHandleService.java
@@ -1,6 +1,7 @@
 package com.ruoyi.projectManagement.service.impl.handle;
 
 import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.ruoyi.projectManagement.dto.ShippingAddressDto;
 import com.ruoyi.projectManagement.mapper.ShippingAddressMapper;
 import com.ruoyi.projectManagement.pojo.ShippingAddress;
@@ -33,4 +34,14 @@
             shippingAddressMapper.updateById(shippingAddress);
         }
     }
+
+
+    public ShippingAddressDto getByInfoId(@NotNull Long id) {
+        LambdaQueryWrapper<ShippingAddress> queryWrapper = new LambdaQueryWrapper<ShippingAddress>();
+        queryWrapper.eq(ShippingAddress::getProjectManagementInfoId, id);
+        queryWrapper.eq(ShippingAddress::getIsDelete, 0);
+        queryWrapper.last("limit 1");
+        ShippingAddress shippingAddress = shippingAddressMapper.selectOne(queryWrapper);
+        return BeanUtil.copyProperties(shippingAddress, ShippingAddressDto.class);
+    }
 }
diff --git a/src/main/java/com/ruoyi/projectManagement/vo/InfoVo.java b/src/main/java/com/ruoyi/projectManagement/vo/InfoVo.java
new file mode 100644
index 0000000..147f0a6
--- /dev/null
+++ b/src/main/java/com/ruoyi/projectManagement/vo/InfoVo.java
@@ -0,0 +1,24 @@
+package com.ruoyi.projectManagement.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @author buhuazhen
+ * @date 2026/3/10
+ * @email 3038525872@qq.com
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class InfoVo extends SaveInfoVo implements Serializable {
+
+
+    // 椤圭洰闃舵
+    private String xxx;
+}
diff --git a/src/main/java/com/ruoyi/projectManagement/vo/ListInfoVo.java b/src/main/java/com/ruoyi/projectManagement/vo/ListInfoVo.java
new file mode 100644
index 0000000..864dc8e
--- /dev/null
+++ b/src/main/java/com/ruoyi/projectManagement/vo/ListInfoVo.java
@@ -0,0 +1,42 @@
+package com.ruoyi.projectManagement.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.projectManagement.dto.SaveInfoDto;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 椤甸潰鍒楄〃淇℃伅
+ *
+ * @author buhuazhen
+ * @date 2026/3/10
+ * @email 3038525872@qq.com
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ListInfoVo extends SaveInfoDto implements Serializable {
+
+    // 瀵瑰簲椤圭洰绫诲瀷鍚嶇О
+    private String projectManagementPlanName;
+
+    // 瀵瑰簲鐖堕」鐩悕绉�
+    private String projectManagementInfoParentName;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime; // 鍒涘缓鏃堕棿
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime; // 鏇存柊鏃堕棿
+
+    private String createUserName; // 鍒涘缓浜哄悕绉�
+    private String updateUserName; // 鏇存柊浜哄悕绉�
+}
diff --git a/src/main/java/com/ruoyi/projectManagement/vo/SavePlanNodeVo.java b/src/main/java/com/ruoyi/projectManagement/vo/SavePlanNodeVo.java
index 3e98742..7f059da 100644
--- a/src/main/java/com/ruoyi/projectManagement/vo/SavePlanNodeVo.java
+++ b/src/main/java/com/ruoyi/projectManagement/vo/SavePlanNodeVo.java
@@ -23,13 +23,13 @@
 
     private Integer sort;
 
-    @NotBlank
+    @NotBlank(message = "name涓嶈兘涓虹┖")
     private String name;
 
-    @NotNull
+    @NotNull(message = "leaderId涓嶈兘涓虹┖")
     private Long leaderId;
 
-    @NotBlank
+    @NotBlank(message = "leaderName涓嶈兘涓虹┖")
     private String leaderName;
 
     private Integer estimatedDuration;
diff --git a/src/main/java/com/ruoyi/projectManagement/vo/SavePlanVo.java b/src/main/java/com/ruoyi/projectManagement/vo/SavePlanVo.java
index 380c14d..bd42d84 100644
--- a/src/main/java/com/ruoyi/projectManagement/vo/SavePlanVo.java
+++ b/src/main/java/com/ruoyi/projectManagement/vo/SavePlanVo.java
@@ -22,7 +22,7 @@
 public class SavePlanVo implements Serializable {
 
     private Long id;
-    @NotBlank
+    @NotBlank(message = "name涓嶈兘涓虹┖")
     private String name;
 //    @NotBlank
     private String description;
diff --git a/src/main/java/com/ruoyi/projectManagement/vo/SearchInfoVo.java b/src/main/java/com/ruoyi/projectManagement/vo/SearchInfoVo.java
new file mode 100644
index 0000000..725dc9a
--- /dev/null
+++ b/src/main/java/com/ruoyi/projectManagement/vo/SearchInfoVo.java
@@ -0,0 +1,32 @@
+package com.ruoyi.projectManagement.vo;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.enums.PlanStageEnum;
+import com.ruoyi.common.enums.ReviewStatusEnum;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @author buhuazhen
+ * @date 2026/3/10
+ * @email 3038525872@qq.com
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class SearchInfoVo extends Page implements Serializable {
+    private String noOrName; // 椤圭洰缂栧彿鎴栭」鐩悕绉�
+    private String clientName; // 瀹㈡埛鍚嶇О
+    private String salesmanName; // 涓氬姟鍛�
+
+    // 瀹℃壒鐘舵��
+    private ReviewStatusEnum reviewStatus;
+
+    // 杩涘害鐘舵��
+    private PlanStageEnum stage;
+}
diff --git a/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java b/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
index f70bd01..79aea98 100644
--- a/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
+++ b/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
@@ -13,6 +13,7 @@
 import com.ruoyi.sales.pojo.SalesLedgerProduct;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.validation.constraints.NotNull;
 import java.math.BigDecimal;
 import java.util.List;
 
@@ -30,6 +31,8 @@
 
     int addOrUpdateSalesLedger(SalesLedgerDto salesLedgerDto);
 
+    List<SalesLedgerProduct> getSalesLedgerProductListByRelateId(@NotNull Long relateId,@NotNull SaleEnum type);
+
     void handleSalesLedgerProducts(Long salesLedgerId, List<SalesLedgerProduct> products, SaleEnum type);
 
     SalesLedgerDto getSalesLedgerWithProducts(SalesLedgerDto salesLedgerDto);
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
index 9158fe3..8f13c5e 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -160,6 +160,14 @@
         return salesLedgerMapper.selectSalesLedgerList(salesLedgerDto);
     }
 
+
+    public List<SalesLedgerProduct> getSalesLedgerProductListByRelateId(Long relateId, SaleEnum type){
+        LambdaQueryWrapper<SalesLedgerProduct> productWrapper = new LambdaQueryWrapper<>();
+        productWrapper.eq(SalesLedgerProduct::getSalesLedgerId, relateId);
+        productWrapper.eq(SalesLedgerProduct::getType, type.getCode());
+        return salesLedgerProductMapper.selectList(productWrapper);
+    }
+
     @Override
     public SalesLedgerDto getSalesLedgerWithProducts(SalesLedgerDto salesLedgerDto) {
         // 1. 鏌ヨ涓昏〃
diff --git a/src/main/resources/mapper/projectManagement/InfoMapper.xml b/src/main/resources/mapper/projectManagement/InfoMapper.xml
index 26449ef..504394e 100644
--- a/src/main/resources/mapper/projectManagement/InfoMapper.xml
+++ b/src/main/resources/mapper/projectManagement/InfoMapper.xml
@@ -48,4 +48,27 @@
         department_name,order_date,order_amount,
         remark,attachment
     </sql>
+    <select id="searchListInfo" resultType="com.ruoyi.projectManagement.vo.ListInfoVo">
+        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
+        left join project_management_info as t3 on t1.project_management_info_parent_id = t3.id
+        where t1.is_delete = 0
+        <if test="vo.noOrName != null and vo.noOrName != ''">
+            and ( t1.no like concat('%', #{vo.noOrName}, '%') OR t1.title like concat('%', #{vo.noOrName}, '%') )
+        </if>
+        <if test="vo.clientName != null and vo.clientName != ''">
+            and t1.client_name like concat('%', #{vo.clientName}, '%')
+        </if>
+        <if test="vo.salesmanName != null and vo.salesmanName != ''">
+            and t1.salesman_name like concat('%', #{vo.salesmanName}, '%')
+        </if>
+        <if test="vo.reviewStatus != null">
+            and t1.review_status = #{vo.reviewStatus.code}
+        </if>
+        <if test="vo.stage != null">
+            and t1.stage = #{vo.stage.code}
+        </if>
+        order by t1.create_time desc
+    </select>
 </mapper>

--
Gitblit v1.9.3