From dce840653b78fc05a732c5c89773c74e15dbed09 Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期四, 08 十月 2026 17:41:27 +0800
Subject: [PATCH] 采购管理系统模块优化

---
 src/main/java/com/ruoyi/basic/mapper/SupplierProductMapper.java                  |    4 
 src/main/java/com/ruoyi/basic/service/impl/SupplierServiceImpl.java              |  129 ++++++++++++
 src/main/resources/mapper/basic/SupplierManageMapper.xml                         |   56 ++---
 src/main/java/com/ruoyi/basic/dto/SupplierManageDto.java                         |    3 
 src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java                      |    2 
 src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java     |    3 
 src/main/java/com/ruoyi/basic/pojo/SupplierManage.java                           |   39 +++
 src/main/java/com/ruoyi/common/enums/FileNameType.java                           |    3 
 src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml                      |    5 
 src/main/java/com/ruoyi/basic/dto/SupplierArchiveSaveDto.java                    |   15 +
 src/main/java/com/ruoyi/basic/pojo/SupplierQualification.java                    |   32 +++
 src/main/java/com/ruoyi/purchase/pojo/TicketRegistration.java                    |   40 ++++
 src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java |  128 ++++++++----
 src/main/java/com/ruoyi/basic/mapper/SupplierCooperationRecordMapper.java        |    4 
 src/main/java/com/ruoyi/basic/pojo/SupplierProduct.java                          |   33 +++
 src/main/java/com/ruoyi/basic/dto/SupplierArchiveDetailVo.java                   |   21 ++
 src/main/java/com/ruoyi/basic/service/ISupplierService.java                      |    9 
 src/main/java/com/ruoyi/basic/pojo/SupplierCooperationRecord.java                |   32 +++
 src/main/java/com/ruoyi/basic/controller/SupplierManageController.java           |   37 +++
 src/main/java/com/ruoyi/basic/mapper/SupplierQualificationMapper.java            |    4 
 20 files changed, 507 insertions(+), 92 deletions(-)

diff --git a/src/main/java/com/ruoyi/basic/controller/SupplierManageController.java b/src/main/java/com/ruoyi/basic/controller/SupplierManageController.java
index 32cad29..7b63f66 100644
--- a/src/main/java/com/ruoyi/basic/controller/SupplierManageController.java
+++ b/src/main/java/com/ruoyi/basic/controller/SupplierManageController.java
@@ -2,10 +2,13 @@
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.basic.dto.SupplierManageDto;
+import com.ruoyi.basic.dto.SupplierArchiveSaveDto;
+import com.ruoyi.basic.pojo.SupplierCooperationRecord;
 import com.ruoyi.basic.pojo.Customer;
 import com.ruoyi.basic.pojo.SupplierManage;
 import com.ruoyi.basic.service.ISupplierService;
 import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.framework.aspectj.lang.annotation.Log;
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.domain.AjaxResult;
@@ -13,12 +16,16 @@
 import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.transaction.annotation.Transactional;
 
 import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 @RestController
 @RequestMapping("/system/supplier")
+@Api(tags = "渚涘簲鍟嗘。妗�")
 public class SupplierManageController {
 
     @Autowired
@@ -30,6 +37,7 @@
      * @return
      */
     @PostMapping("/add")
+    @ApiOperation("鏂板渚涘簲鍟�")
     public AjaxResult add(@RequestBody SupplierManage supplierManage) {
         supplierService.saveSupplier(supplierManage);
         return AjaxResult.success();
@@ -41,6 +49,7 @@
      * @return
      */
     @DeleteMapping("/del")
+    @ApiOperation("鍒犻櫎渚涘簲鍟�")
     public AjaxResult delSupplier(@RequestBody List<Integer> ids) {
         if(CollectionUtils.isEmpty(ids)){
             return AjaxResult.error("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
@@ -55,6 +64,7 @@
      * @return
      */
     @GetMapping("/{id}")
+    @ApiOperation("渚涘簲鍟嗚鎯�")
     public AjaxResult supplierDetail(@PathVariable("id") Integer id) {
         return AjaxResult.success(supplierService.supplierDetail(id));
     }
@@ -65,6 +75,7 @@
      * @return
      */
     @PostMapping("/update")
+    @ApiOperation("淇敼渚涘簲鍟�")
     public AjaxResult update(@RequestBody SupplierManage supplierManage) {
         supplierService.supplierUpdate(supplierManage);
         return AjaxResult.success();
@@ -77,6 +88,7 @@
      * @return
      */
     @GetMapping("/listPage")
+    @ApiOperation("渚涘簲鍟嗗垎椤垫煡璇�")
     public AjaxResult supplierListPage(Page page, SupplierManageDto supplierManageDto) {
         return AjaxResult.success(supplierService.supplierListPage(page, supplierManageDto));
     }
@@ -117,7 +129,30 @@
      * @return
      */
     @GetMapping("/getOptions")
+    @ApiOperation("渚涘簲鍟嗛�夐」")
     public AjaxResult getOptions() {
-        return AjaxResult.success(supplierService.list());
+        return AjaxResult.success(supplierService.lambdaQuery().eq(SupplierManage::getCooperationStatus,1)
+                .eq(SupplierManage::getDeleteFlag,0)
+                .eq(SupplierManage::getTenantId, SecurityUtils.getLoginUser().getTenantId()).list());
+    }
+
+    @GetMapping("/{id}/archive")
+    @ApiOperation("渚涘簲鍟嗗畬鏁存。妗�")
+    public AjaxResult archive(@PathVariable Integer id) {
+        return AjaxResult.success(supplierService.supplierArchiveDetail(id));
+    }
+
+    @PostMapping("/archive/save")
+    @ApiOperation("淇濆瓨渚涘簲鍟嗗畬鏁存。妗�")
+    @Transactional(rollbackFor = Exception.class)
+    public AjaxResult saveArchive(@RequestBody SupplierArchiveSaveDto archive) {
+        return AjaxResult.success(supplierService.saveArchive(archive));
+    }
+
+    @PostMapping("/{id}/cooperation")
+    @ApiOperation("鏂板渚涘簲鍟嗗悎浣滆褰�")
+    public AjaxResult addCooperation(@PathVariable Integer id, @RequestBody SupplierCooperationRecord record) {
+        supplierService.addCooperationRecord(id, record);
+        return AjaxResult.success();
     }
 }
diff --git a/src/main/java/com/ruoyi/basic/dto/SupplierArchiveDetailVo.java b/src/main/java/com/ruoyi/basic/dto/SupplierArchiveDetailVo.java
new file mode 100644
index 0000000..458cd9e
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/dto/SupplierArchiveDetailVo.java
@@ -0,0 +1,21 @@
+package com.ruoyi.basic.dto;
+
+import com.ruoyi.basic.pojo.SupplierCooperationRecord;
+import com.ruoyi.basic.pojo.SupplierManage;
+import com.ruoyi.basic.pojo.SupplierProduct;
+import com.ruoyi.basic.pojo.SupplierQualification;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+public class SupplierArchiveDetailVo {
+    @ApiModelProperty("渚涘簲鍟嗕富妗�") private SupplierManage supplier;
+    @ApiModelProperty("璧勮川璇佹槑鍒楄〃") private List<SupplierQualification> qualifications;
+    @ApiModelProperty("渚涘簲浜у搧鍒楄〃") private List<SupplierProduct> products;
+    @ApiModelProperty("鍚堜綔璇勪环鍒楄〃") private List<SupplierCooperationRecord> cooperationRecords;
+    @ApiModelProperty("閲囪喘鍚堝悓鏁伴噺") private Long purchaseCount;
+    @ApiModelProperty("閲囪喘鎬婚") private BigDecimal purchaseAmount;
+    @ApiModelProperty("宸叉潵绁ㄩ噾棰�") private BigDecimal invoicedAmount;
+}
diff --git a/src/main/java/com/ruoyi/basic/dto/SupplierArchiveSaveDto.java b/src/main/java/com/ruoyi/basic/dto/SupplierArchiveSaveDto.java
new file mode 100644
index 0000000..4905361
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/dto/SupplierArchiveSaveDto.java
@@ -0,0 +1,15 @@
+package com.ruoyi.basic.dto;
+
+import com.ruoyi.basic.pojo.SupplierManage;
+import com.ruoyi.basic.pojo.SupplierProduct;
+import com.ruoyi.basic.pojo.SupplierQualification;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.util.List;
+
+@Data
+public class SupplierArchiveSaveDto {
+    @ApiModelProperty("渚涘簲鍟嗕富妗�") private SupplierManage supplier;
+    @ApiModelProperty("璧勮川璇佹槑鍒楄〃") private List<SupplierQualification> qualifications;
+    @ApiModelProperty("渚涘簲浜у搧鍒楄〃") private List<SupplierProduct> products;
+}
diff --git a/src/main/java/com/ruoyi/basic/dto/SupplierManageDto.java b/src/main/java/com/ruoyi/basic/dto/SupplierManageDto.java
index 30044ad..bad7cf6 100644
--- a/src/main/java/com/ruoyi/basic/dto/SupplierManageDto.java
+++ b/src/main/java/com/ruoyi/basic/dto/SupplierManageDto.java
@@ -9,4 +9,7 @@
 
     @ApiModelProperty(value = "缁存姢浜哄憳鍚嶇О")
     private String maintainUserName;
+
+    @ApiModelProperty(value = "渚涘簲浜у搧鎼滅储鍏抽敭瀛�")
+    private String productKeyword;
 }
diff --git a/src/main/java/com/ruoyi/basic/mapper/SupplierCooperationRecordMapper.java b/src/main/java/com/ruoyi/basic/mapper/SupplierCooperationRecordMapper.java
new file mode 100644
index 0000000..9ce8222
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/mapper/SupplierCooperationRecordMapper.java
@@ -0,0 +1,4 @@
+package com.ruoyi.basic.mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.basic.pojo.SupplierCooperationRecord;
+public interface SupplierCooperationRecordMapper extends BaseMapper<SupplierCooperationRecord> { }
diff --git a/src/main/java/com/ruoyi/basic/mapper/SupplierProductMapper.java b/src/main/java/com/ruoyi/basic/mapper/SupplierProductMapper.java
new file mode 100644
index 0000000..996358f
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/mapper/SupplierProductMapper.java
@@ -0,0 +1,4 @@
+package com.ruoyi.basic.mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.basic.pojo.SupplierProduct;
+public interface SupplierProductMapper extends BaseMapper<SupplierProduct> { }
diff --git a/src/main/java/com/ruoyi/basic/mapper/SupplierQualificationMapper.java b/src/main/java/com/ruoyi/basic/mapper/SupplierQualificationMapper.java
new file mode 100644
index 0000000..a61bdd9
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/mapper/SupplierQualificationMapper.java
@@ -0,0 +1,4 @@
+package com.ruoyi.basic.mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.basic.pojo.SupplierQualification;
+public interface SupplierQualificationMapper extends BaseMapper<SupplierQualification> { }
diff --git a/src/main/java/com/ruoyi/basic/pojo/SupplierCooperationRecord.java b/src/main/java/com/ruoyi/basic/pojo/SupplierCooperationRecord.java
new file mode 100644
index 0000000..4e5d28e
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/pojo/SupplierCooperationRecord.java
@@ -0,0 +1,32 @@
+package com.ruoyi.basic.pojo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+@Data
+@TableName("supplier_cooperation_record")
+public class SupplierCooperationRecord {
+    @TableId(type = IdType.AUTO) @ApiModelProperty("涓婚敭ID") private Long id;
+    @ApiModelProperty("渚涘簲鍟咺D") private Long supplierId;
+    @JsonFormat(pattern="yyyy-MM-dd") @ApiModelProperty("鍚堜綔鏃ユ湡") private LocalDate cooperationDate;
+    @ApiModelProperty("鍚堜綔绫诲瀷") private String cooperationType;
+    @ApiModelProperty("鍏宠仈涓氬姟ID") private Long businessId;
+    @ApiModelProperty("鍏宠仈涓氬姟缂栧彿") private String businessNo;
+    @ApiModelProperty("娑夊強閲戦") private BigDecimal amount;
+    @ApiModelProperty("璇勪环缁撴灉") private String result;
+    @ApiModelProperty("璇勫垎") private BigDecimal rating;
+    @ApiModelProperty("鍚堜綔璁板綍鍐呭") private String description;
+    @ApiModelProperty("绉熸埛ID") private Long tenantId;
+    @ApiModelProperty("鍒涘缓鐢ㄦ埛ID") private Long createUser;
+    @ApiModelProperty("鏇存柊鐢ㄦ埛ID") private Long updateUser;
+    @ApiModelProperty("鍒涘缓鏃堕棿") private LocalDateTime createTime;
+    @ApiModelProperty("鏇存柊鏃堕棿") private LocalDateTime updateTime;
+    @ApiModelProperty("鍒犻櫎鏍囧織") private Integer deleteFlag;
+}
diff --git a/src/main/java/com/ruoyi/basic/pojo/SupplierManage.java b/src/main/java/com/ruoyi/basic/pojo/SupplierManage.java
index 142a6f2..bcbbc8c 100644
--- a/src/main/java/com/ruoyi/basic/pojo/SupplierManage.java
+++ b/src/main/java/com/ruoyi/basic/pojo/SupplierManage.java
@@ -14,8 +14,47 @@
 public class SupplierManage {
 
     @TableId(value = "id", type = IdType.AUTO)
+    @ApiModelProperty(value = "渚涘簲鍟咺D")
     private Integer id;
 
+    @ApiModelProperty(value = "渚涘簲鍟嗙紪鐮�")
+    private String supplierCode;
+
+    @ApiModelProperty(value = "渚涘簲鍟嗙畝绉�")
+    private String supplierShortName;
+
+    @ApiModelProperty(value = "渚涘簲鍟嗗垎绫�")
+    private String supplierCategory;
+
+    @ApiModelProperty(value = "渚涘簲鍟嗙瓑绾�")
+    private String supplierLevel;
+
+    @ApiModelProperty(value = "鍚堜綔鐘舵�侊細0鍋滅敤锛�1鍚堜綔涓紝2鏆傚仠")
+    private Integer cooperationStatus;
+
+    @ApiModelProperty(value = "棣栨鍚堜綔鏃ユ湡")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private LocalDate cooperationStartDate;
+
+    @ApiModelProperty(value = "璧勮川鐘舵�侊細0寰呭畬鍠勶紝1鏈夋晥锛�2鍗冲皢鍒版湡锛�3宸茶繃鏈�")
+    private Integer qualificationStatus;
+
+    @ApiModelProperty(value = "鏈�杩戣祫璐ㄥ埌鏈熸棩鏈�")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private LocalDate qualificationExpiryDate;
+
+    @ApiModelProperty(value = "渚涘簲浜у搧鎽樿")
+    private String suppliedProductsSummary;
+
+    @ApiModelProperty(value = "鍚堜綔鍘嗗彶鎽樿")
+    private String cooperationHistorySummary;
+
+    @ApiModelProperty(value = "澶囨敞")
+    private String remark;
+
+    @ApiModelProperty(value = "鍒犻櫎鏍囧織锛�0姝e父锛�1鍒犻櫎")
+    private Integer deleteFlag;
+
     @ApiModelProperty(value = "渚涘簲鍟嗗悕绉�")
     @Excel(name = "渚涘簲鍟嗗悕绉�")
     private String supplierName;
diff --git a/src/main/java/com/ruoyi/basic/pojo/SupplierProduct.java b/src/main/java/com/ruoyi/basic/pojo/SupplierProduct.java
new file mode 100644
index 0000000..e31e75f
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/pojo/SupplierProduct.java
@@ -0,0 +1,33 @@
+package com.ruoyi.basic.pojo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+@TableName("supplier_product")
+public class SupplierProduct {
+    @TableId(type = IdType.AUTO) @ApiModelProperty("涓婚敭ID") private Long id;
+    @ApiModelProperty("渚涘簲鍟咺D") private Long supplierId;
+    @ApiModelProperty("浜у搧鍚嶇О") private String productName;
+    @ApiModelProperty("浜у搧鍒嗙被") private String productCategory;
+    @ApiModelProperty("瑙勬牸鍨嬪彿") private String specificationModel;
+    @ApiModelProperty("鍝佺墝") private String brand;
+    @ApiModelProperty("鍗曚綅") private String unit;
+    @ApiModelProperty("鏈�灏忚捣璁㈤噺") private BigDecimal minOrderQuantity;
+    @ApiModelProperty("渚涜揣鍛ㄦ湡锛堝ぉ锛�") private Integer leadTimeDays;
+    @ApiModelProperty("鍙傝�冨崟浠�") private BigDecimal referencePrice;
+    @ApiModelProperty("甯佺") private String currency;
+    @ApiModelProperty("鐘舵�侊細0鍋滀緵锛�1渚涘簲涓�") private Integer status;
+    @ApiModelProperty("澶囨敞") private String remark;
+    @ApiModelProperty("绉熸埛ID") private Long tenantId;
+    @ApiModelProperty("鍒涘缓鐢ㄦ埛ID") private Long createUser;
+    @ApiModelProperty("鏇存柊鐢ㄦ埛ID") private Long updateUser;
+    @ApiModelProperty("鍒涘缓鏃堕棿") private LocalDateTime createTime;
+    @ApiModelProperty("鏇存柊鏃堕棿") private LocalDateTime updateTime;
+    @ApiModelProperty("鍒犻櫎鏍囧織") private Integer deleteFlag;
+}
diff --git a/src/main/java/com/ruoyi/basic/pojo/SupplierQualification.java b/src/main/java/com/ruoyi/basic/pojo/SupplierQualification.java
new file mode 100644
index 0000000..5fe4c39
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/pojo/SupplierQualification.java
@@ -0,0 +1,32 @@
+package com.ruoyi.basic.pojo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+@Data
+@TableName("supplier_qualification")
+public class SupplierQualification {
+    @TableId(type = IdType.AUTO) @ApiModelProperty("涓婚敭ID") private Long id;
+    @ApiModelProperty("渚涘簲鍟咺D") private Long supplierId;
+    @ApiModelProperty("璧勮川鍚嶇О") private String qualificationName;
+    @ApiModelProperty("璧勮川绫诲瀷") private String qualificationType;
+    @ApiModelProperty("璇佷功缂栧彿") private String certificateNo;
+    @ApiModelProperty("鍙戣瘉鏈烘瀯") private String issuingAuthority;
+    @JsonFormat(pattern="yyyy-MM-dd") @ApiModelProperty("鍙戣瘉鏃ユ湡") private LocalDate issueDate;
+    @JsonFormat(pattern="yyyy-MM-dd") @ApiModelProperty("鍒版湡鏃ユ湡") private LocalDate expiryDate;
+    @ApiModelProperty("鏄惁闀挎湡鏈夋晥锛�0鍚︼紝1鏄�") private Integer longTermValid;
+    @ApiModelProperty("鐘舵�侊細0寰呭鏍革紝1鏈夋晥锛�2杩囨湡锛�3浣滃簾") private Integer status;
+    @ApiModelProperty("澶囨敞") private String remark;
+    @ApiModelProperty("绉熸埛ID") private Long tenantId;
+    @ApiModelProperty("鍒涘缓鐢ㄦ埛ID") private Long createUser;
+    @ApiModelProperty("鏇存柊鐢ㄦ埛ID") private Long updateUser;
+    @ApiModelProperty("鍒涘缓鏃堕棿") private LocalDateTime createTime;
+    @ApiModelProperty("鏇存柊鏃堕棿") private LocalDateTime updateTime;
+    @ApiModelProperty("鍒犻櫎鏍囧織") private Integer deleteFlag;
+}
diff --git a/src/main/java/com/ruoyi/basic/service/ISupplierService.java b/src/main/java/com/ruoyi/basic/service/ISupplierService.java
index f3e46c2..24d737e 100644
--- a/src/main/java/com/ruoyi/basic/service/ISupplierService.java
+++ b/src/main/java/com/ruoyi/basic/service/ISupplierService.java
@@ -4,6 +4,9 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.basic.dto.SupplierManageDto;
+import com.ruoyi.basic.dto.SupplierArchiveDetailVo;
+import com.ruoyi.basic.dto.SupplierArchiveSaveDto;
+import com.ruoyi.basic.pojo.SupplierCooperationRecord;
 import com.ruoyi.basic.pojo.SupplierManage;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import org.springframework.web.multipart.MultipartFile;
@@ -57,4 +60,10 @@
     void supplierExport(HttpServletResponse response, SupplierManageDto supplierManageDto);
 
     Boolean importData(MultipartFile file);
+
+    SupplierArchiveDetailVo supplierArchiveDetail(Integer id);
+
+    Integer saveArchive(SupplierArchiveSaveDto archive);
+
+    void addCooperationRecord(Integer supplierId, SupplierCooperationRecord record);
 }
diff --git a/src/main/java/com/ruoyi/basic/service/impl/SupplierServiceImpl.java b/src/main/java/com/ruoyi/basic/service/impl/SupplierServiceImpl.java
index 020a9cd..c047570 100644
--- a/src/main/java/com/ruoyi/basic/service/impl/SupplierServiceImpl.java
+++ b/src/main/java/com/ruoyi/basic/service/impl/SupplierServiceImpl.java
@@ -6,8 +6,16 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.basic.dto.SupplierManageDto;
+import com.ruoyi.basic.dto.SupplierArchiveDetailVo;
+import com.ruoyi.basic.dto.SupplierArchiveSaveDto;
 import com.ruoyi.basic.excel.SupplierManageExcelDto;
 import com.ruoyi.basic.mapper.SupplierManageMapper;
+import com.ruoyi.basic.mapper.SupplierQualificationMapper;
+import com.ruoyi.basic.mapper.SupplierProductMapper;
+import com.ruoyi.basic.mapper.SupplierCooperationRecordMapper;
+import com.ruoyi.basic.pojo.SupplierQualification;
+import com.ruoyi.basic.pojo.SupplierProduct;
+import com.ruoyi.basic.pojo.SupplierCooperationRecord;
 import com.ruoyi.basic.pojo.Customer;
 import com.ruoyi.basic.pojo.SupplierManage;
 import com.ruoyi.basic.service.ISupplierService;
@@ -16,13 +24,19 @@
 import com.ruoyi.framework.web.domain.AjaxResult;
 import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
 import com.ruoyi.purchase.pojo.PurchaseLedger;
+import com.ruoyi.purchase.mapper.TicketRegistrationMapper;
+import com.ruoyi.purchase.pojo.TicketRegistration;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.stream.Collectors;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -33,6 +47,10 @@
     private SupplierManageMapper supplierMapper;
     @Autowired
     private PurchaseLedgerMapper purchaseLedgerMapper;
+    @Autowired private TicketRegistrationMapper ticketRegistrationMapper;
+    @Autowired private SupplierQualificationMapper qualificationMapper;
+    @Autowired private SupplierProductMapper productMapper;
+    @Autowired private SupplierCooperationRecordMapper cooperationMapper;
 
     /**
      * 渚涘簲鍟嗘柊澧�
@@ -41,12 +59,24 @@
      */
     @Override
     public void saveSupplier(SupplierManage supplierManage) {
+        Long tenantId = SecurityUtils.getLoginUser().getTenantId();
         LambdaQueryWrapper<SupplierManage> supplierManageLambdaQueryWrapper = new LambdaQueryWrapper<>();
-        supplierManageLambdaQueryWrapper.eq(SupplierManage::getSupplierName,supplierManage.getSupplierName());
+        supplierManageLambdaQueryWrapper.eq(SupplierManage::getSupplierName,supplierManage.getSupplierName())
+                .eq(SupplierManage::getTenantId, tenantId).eq(SupplierManage::getDeleteFlag, 0);
         if (supplierMapper.selectCount(supplierManageLambdaQueryWrapper) > 0) {
             throw new RuntimeException("渚涘簲鍟嗗凡瀛樺湪");
         }
+        supplierManage.setTenantId(tenantId);
+        supplierManage.setDeleteFlag(0);
+        supplierManage.setCooperationStatus(supplierManage.getCooperationStatus() == null ? 1 : supplierManage.getCooperationStatus());
+        supplierManage.setQualificationStatus(supplierManage.getQualificationStatus() == null ? 0 : supplierManage.getQualificationStatus());
+        supplierManage.setMaintainUserId(SecurityUtils.getUserId().intValue());
+        supplierManage.setMaintainTime(LocalDate.now());
         supplierMapper.insert(supplierManage);
+        if (supplierManage.getSupplierCode() == null || supplierManage.getSupplierCode().trim().isEmpty()) {
+            supplierManage.setSupplierCode(String.format("SUP%06d", supplierManage.getId()));
+            supplierMapper.updateById(supplierManage);
+        }
     }
 
     /**
@@ -56,14 +86,18 @@
      */
     @Override
     public int delSupplier(List<Integer> ids) {
-        List<PurchaseLedger> purchaseLedgers = purchaseLedgerMapper.selectList(new QueryWrapper<PurchaseLedger>().lambda().in(PurchaseLedger::getSupplierId, ids));
+        Long tenantId=SecurityUtils.getLoginUser().getTenantId();
+        List<PurchaseLedger> purchaseLedgers = purchaseLedgerMapper.selectList(new QueryWrapper<PurchaseLedger>().lambda()
+                .in(PurchaseLedger::getSupplierId, ids).eq(PurchaseLedger::getTenantId,tenantId));
         if (purchaseLedgers.size() > 0) {
             throw new RuntimeException("渚涘簲鍟嗗凡瀛樺湪閲囪喘鍚堝悓");
         }
-        LambdaQueryWrapper<SupplierManage> delWrapper = new LambdaQueryWrapper<>();
-        delWrapper.in(SupplierManage::getId, ids);
-
-        return supplierMapper.delete(delWrapper);
+        int count=0;
+        for(Integer id:ids){
+            SupplierManage supplier=supplierDetail(id);
+            if(supplier!=null){ supplier.setDeleteFlag(1); supplier.setCooperationStatus(0); count+=supplierMapper.updateById(supplier); }
+        }
+        return count;
     }
 
     /**
@@ -73,7 +107,9 @@
      */
     @Override
     public SupplierManage supplierDetail(Integer id) {
-        return supplierMapper.selectById(id);
+        return supplierMapper.selectOne(new LambdaQueryWrapper<SupplierManage>().eq(SupplierManage::getId,id)
+                .eq(SupplierManage::getTenantId, SecurityUtils.getLoginUser().getTenantId())
+                .eq(SupplierManage::getDeleteFlag,0));
     }
 
     /**
@@ -83,7 +119,11 @@
      */
     @Override
     public int supplierUpdate(SupplierManage supplierManage) {
-        return supplierMapper.updateById(supplierManage);
+        SupplierManage current = supplierDetail(supplierManage.getId());
+        if (current == null) throw new RuntimeException("渚涘簲鍟嗕笉瀛樺湪");
+        supplierManage.setTenantId(current.getTenantId());
+        return supplierMapper.update(supplierManage, new LambdaQueryWrapper<SupplierManage>()
+                .eq(SupplierManage::getId, supplierManage.getId()).eq(SupplierManage::getTenantId,current.getTenantId()));
     }
 
     /**
@@ -94,6 +134,7 @@
      */
     @Override
     public IPage<SupplierManage> supplierListPage(Page page, SupplierManageDto supplierManageDto) {
+        supplierManageDto.setTenantId(SecurityUtils.getLoginUser().getTenantId());
         return supplierMapper.supplierListPage(page,supplierManageDto);
     }
 
@@ -104,6 +145,7 @@
      */
     @Override
     public void supplierExport(HttpServletResponse response, SupplierManageDto supplierManageDto) {
+        supplierManageDto.setTenantId(SecurityUtils.getLoginUser().getTenantId());
         List<SupplierManageExcelDto> supplierManageList = supplierMapper.supplierExportList(supplierManageDto);
         ExcelUtil<SupplierManageExcelDto> util = new ExcelUtil<SupplierManageExcelDto>(SupplierManageExcelDto.class);
         util.exportExcel(response, supplierManageList, "渚涘簲鍟嗗鍑�");
@@ -133,4 +175,75 @@
         }
         return false;
     }
+
+    @Override
+    public SupplierArchiveDetailVo supplierArchiveDetail(Integer id) {
+        SupplierManage supplier = supplierDetail(id);
+        if (supplier == null) throw new RuntimeException("渚涘簲鍟嗕笉瀛樺湪");
+        long supplierId = id.longValue();
+        long tenantId = supplier.getTenantId();
+        SupplierArchiveDetailVo result = new SupplierArchiveDetailVo();
+        result.setSupplier(supplier);
+        result.setQualifications(qualificationMapper.selectList(new LambdaQueryWrapper<SupplierQualification>()
+                .eq(SupplierQualification::getSupplierId,supplierId).eq(SupplierQualification::getTenantId,tenantId)
+                .eq(SupplierQualification::getDeleteFlag,0).orderByAsc(SupplierQualification::getExpiryDate)));
+        result.setProducts(productMapper.selectList(new LambdaQueryWrapper<SupplierProduct>()
+                .eq(SupplierProduct::getSupplierId,supplierId).eq(SupplierProduct::getTenantId,tenantId)
+                .eq(SupplierProduct::getDeleteFlag,0)));
+        result.setCooperationRecords(cooperationMapper.selectList(new LambdaQueryWrapper<SupplierCooperationRecord>()
+                .eq(SupplierCooperationRecord::getSupplierId,supplierId).eq(SupplierCooperationRecord::getTenantId,tenantId)
+                .eq(SupplierCooperationRecord::getDeleteFlag,0).orderByDesc(SupplierCooperationRecord::getCooperationDate)));
+        List<PurchaseLedger> purchases = purchaseLedgerMapper.selectList(new LambdaQueryWrapper<PurchaseLedger>()
+                .eq(PurchaseLedger::getSupplierId,supplierId).eq(PurchaseLedger::getTenantId,tenantId));
+        result.setPurchaseCount((long)purchases.size());
+        result.setPurchaseAmount(purchases.stream().map(PurchaseLedger::getContractAmount).filter(java.util.Objects::nonNull)
+                .reduce(BigDecimal.ZERO, BigDecimal::add));
+        result.setInvoicedAmount(ticketRegistrationMapper.selectList(new LambdaQueryWrapper<TicketRegistration>()
+                .eq(TicketRegistration::getSupplierId,supplierId).eq(TicketRegistration::getTenantId,tenantId)
+                .eq(TicketRegistration::getDeleteFlag,0)).stream().map(TicketRegistration::getInvoiceAmount)
+                .filter(java.util.Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add));
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Integer saveArchive(SupplierArchiveSaveDto archive) {
+        if (archive == null || archive.getSupplier() == null) throw new RuntimeException("渚涘簲鍟嗕俊鎭笉鑳戒负绌�");
+        SupplierManage supplier = archive.getSupplier();
+        if (supplier.getId() == null) saveSupplier(supplier); else supplierUpdate(supplier);
+        long tenantId = SecurityUtils.getLoginUser().getTenantId();
+        long userId = SecurityUtils.getUserId();
+        long supplierId = supplier.getId().longValue();
+        qualificationMapper.delete(new LambdaQueryWrapper<SupplierQualification>().eq(SupplierQualification::getSupplierId,supplierId).eq(SupplierQualification::getTenantId,tenantId));
+        productMapper.delete(new LambdaQueryWrapper<SupplierProduct>().eq(SupplierProduct::getSupplierId,supplierId).eq(SupplierProduct::getTenantId,tenantId));
+        LocalDate nearest = null;
+        if (archive.getQualifications() != null) for (SupplierQualification item : archive.getQualifications()) {
+            item.setId(null); item.setSupplierId(supplierId); item.setTenantId(tenantId); item.setCreateUser(userId);
+            item.setCreateTime(LocalDateTime.now()); item.setUpdateTime(LocalDateTime.now()); item.setDeleteFlag(0);
+            item.setStatus(item.getStatus() == null ? 1 : item.getStatus()); qualificationMapper.insert(item);
+            if (item.getExpiryDate()!=null && (nearest==null || item.getExpiryDate().isBefore(nearest))) nearest=item.getExpiryDate();
+        }
+        if (archive.getProducts() != null) for (SupplierProduct item : archive.getProducts()) {
+            if (item.getProductName()==null || item.getProductName().trim().isEmpty()) continue;
+            item.setId(null); item.setSupplierId(supplierId); item.setTenantId(tenantId); item.setCreateUser(userId);
+            item.setCreateTime(LocalDateTime.now()); item.setUpdateTime(LocalDateTime.now()); item.setDeleteFlag(0);
+            item.setStatus(item.getStatus()==null?1:item.getStatus()); item.setCurrency(item.getCurrency()==null?"CNY":item.getCurrency()); productMapper.insert(item);
+        }
+        supplier.setQualificationExpiryDate(nearest);
+        supplier.setQualificationStatus(nearest==null?0:(nearest.isBefore(LocalDate.now())?3:(nearest.isBefore(LocalDate.now().plusDays(31))?2:1)));
+        if (archive.getProducts()!=null) supplier.setSuppliedProductsSummary(archive.getProducts().stream().map(SupplierProduct::getProductName)
+                .filter(java.util.Objects::nonNull).limit(5).collect(Collectors.joining("銆�")));
+        supplierUpdate(supplier);
+        return supplier.getId();
+    }
+
+    @Override
+    public void addCooperationRecord(Integer supplierId, SupplierCooperationRecord record) {
+        SupplierManage supplier = supplierDetail(supplierId);
+        if (supplier == null) throw new RuntimeException("渚涘簲鍟嗕笉瀛樺湪");
+        record.setId(null); record.setSupplierId(supplierId.longValue()); record.setTenantId(supplier.getTenantId());
+        record.setCreateUser(SecurityUtils.getUserId()); record.setUpdateUser(SecurityUtils.getUserId());
+        record.setCreateTime(LocalDateTime.now()); record.setUpdateTime(LocalDateTime.now()); record.setDeleteFlag(0);
+        cooperationMapper.insert(record);
+    }
 }
diff --git a/src/main/java/com/ruoyi/common/enums/FileNameType.java b/src/main/java/com/ruoyi/common/enums/FileNameType.java
index 16d51f6..ba42a1f 100644
--- a/src/main/java/com/ruoyi/common/enums/FileNameType.java
+++ b/src/main/java/com/ruoyi/common/enums/FileNameType.java
@@ -11,7 +11,8 @@
     MEASURING(5),  //璁¢噺鍣ㄥ叿鍙拌处
     MEASURINGRecord(6),//璁¢噺鍣ㄥ叿鍙拌处璁板綍
     ApproveNode(7),  //鍗忓悓瀹℃壒鑺傜偣瀹℃牳
-    ApproveProcess(8);  //鍗忓悓瀹℃壒涓绘暟鎹�
+    ApproveProcess(8),  //鍗忓悓瀹℃壒涓绘暟鎹�
+    SUPPLIER_QUALIFICATION(9); //渚涘簲鍟嗚祫璐ㄩ檮浠�
 
     private final int value;
 
diff --git a/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java b/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
index 7d1e9e5..6e9cda0 100644
--- a/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
+++ b/src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
@@ -16,6 +16,8 @@
 @Data
 public class PurchaseLedgerDto {
 
+    @ApiModelProperty(value = "绉熸埛ID")
+    private Long tenantId;
 
     private String entryDateStart;
     private String entryDateEnd;
diff --git a/src/main/java/com/ruoyi/purchase/pojo/TicketRegistration.java b/src/main/java/com/ruoyi/purchase/pojo/TicketRegistration.java
index e79796a..b063b2c 100644
--- a/src/main/java/com/ruoyi/purchase/pojo/TicketRegistration.java
+++ b/src/main/java/com/ruoyi/purchase/pojo/TicketRegistration.java
@@ -25,8 +25,48 @@
      * 涓婚敭ID
      */
     @TableId(value = "id", type = IdType.AUTO)
+    @ApiModelProperty(value = "鏉ョエ鐧昏ID")
     private Long id;
 
+    @ApiModelProperty(value = "渚涘簲鍟咺D")
+    private Long supplierId;
+
+    @ApiModelProperty(value = "鍙戠エ浠g爜")
+    private String invoiceCode;
+
+    @ApiModelProperty(value = "鍙戠エ绫诲瀷")
+    private String invoiceType;
+
+    @ApiModelProperty(value = "绋庣巼")
+    private BigDecimal taxRate;
+
+    @ApiModelProperty(value = "绋庨")
+    private BigDecimal taxAmount;
+
+    @ApiModelProperty(value = "甯佺")
+    private String currency;
+
+    @ApiModelProperty(value = "鍙戠エ鐘舵�侊細0鑽夌锛�1宸茬櫥璁帮紝2绾㈠啿锛�3浣滃簾")
+    private Integer invoiceStatus;
+
+    @ApiModelProperty(value = "鏍搁獙鐘舵�侊細0鏈牳楠岋紝1閫氳繃锛�2寮傚父")
+    private Integer verificationStatus;
+
+    @ApiModelProperty(value = "澶囨敞")
+    private String remark;
+
+    @ApiModelProperty(value = "鍒涘缓鐢ㄦ埛ID")
+    private Long createUser;
+
+    @ApiModelProperty(value = "鏇存柊鐢ㄦ埛ID")
+    private Long updateUser;
+
+    @ApiModelProperty(value = "鏇存柊鏃堕棿")
+    private Date updateTime;
+
+    @ApiModelProperty(value = "鍒犻櫎鏍囧織锛�0姝e父锛�1鍒犻櫎")
+    private Integer deleteFlag;
+
     /**
      * 鐘舵��
      */
diff --git a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
index 70762b9..0b60d65 100644
--- a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -472,8 +472,7 @@
 
     @Override
     public IPage<PurchaseLedgerDto> selectPurchaseLedgerListPage(IPage ipage, PurchaseLedgerDto purchaseLedger) {
-        Long userId = SecurityUtils.getUserId();
-        purchaseLedger.setRecorderId(userId);
+        purchaseLedger.setTenantId(SecurityUtils.getLoginUser().getTenantId());
         IPage<PurchaseLedgerDto> purchaseLedgerDtoIPage = purchaseLedgerMapper.selectPurchaseLedgerListPage(ipage, purchaseLedger);
         purchaseLedgerDtoIPage.getRecords().forEach(purchaseLedgerDto -> {
             List<CommonFile> commonFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>().eq(CommonFile::getCommonId, purchaseLedgerDto.getId()).eq(CommonFile::getType, FileNameType.PURCHASELEDGER.getValue()));
diff --git a/src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java b/src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java
index 9ba8faa..2f680d5 100644
--- a/src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java
+++ b/src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java
@@ -42,6 +42,7 @@
 
 import java.io.IOException;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -91,6 +92,8 @@
     @Override
     public List<TicketRegistration> selectTicketRegistrationList(TicketRegistration ticketRegistration) {
         LambdaQueryWrapper<TicketRegistration> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(TicketRegistration::getTenantId,SecurityUtils.getLoginUser().getTenantId())
+                .eq(TicketRegistration::getDeleteFlag,0);
         if (StringUtils.isNotBlank(ticketRegistration.getPurchaseContractNumber())) {
             queryWrapper.like(TicketRegistration::getPurchaseContractNumber, ticketRegistration.getPurchaseContractNumber())
                     .like(TicketRegistration::getSupplierName, ticketRegistration.getSupplierName())
@@ -122,11 +125,39 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public int addOrUpdateRegistration(TicketRegistrationDto ticketRegistrationDto) throws IOException {
+        Long tenantId = SecurityUtils.getLoginUser().getTenantId();
+        Long userId = SecurityUtils.getUserId();
+        if (ticketRegistrationDto.getPurchaseLedgerId() == null) throw new BaseException("璇烽�夋嫨閲囪喘鍗�");
+        if (StringUtils.isBlank(ticketRegistrationDto.getInvoiceNumber())) throw new BaseException("鍙戠エ鍙风爜涓嶈兘涓虹┖");
+        if (ticketRegistrationDto.getIssueDate() == null) throw new BaseException("寮�绁ㄦ棩鏈熶笉鑳戒负绌�");
+        if (ticketRegistrationDto.getInvoiceAmount() == null || ticketRegistrationDto.getInvoiceAmount().compareTo(BigDecimal.ZERO) <= 0) {
+            throw new BaseException("鍙戠エ閲戦蹇呴』澶т簬0");
+        }
         // 1. 鏌ヨ閲囪喘鍙拌处璁板綍
-        PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(ticketRegistrationDto.getPurchaseLedgerId());
+        PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectOne(new LambdaQueryWrapper<PurchaseLedger>()
+                .eq(PurchaseLedger::getId,ticketRegistrationDto.getPurchaseLedgerId())
+                .eq(PurchaseLedger::getTenantId,tenantId));
         if (purchaseLedger == null) {
             // 澶勭悊閲囪喘鍙拌处涓嶅瓨鍦ㄧ殑鎯呭喌锛屼緥濡傛姏鍑哄紓甯告垨杩斿洖閿欒
             throw new IllegalArgumentException("閲囪喘鍙拌处璁板綍涓嶅瓨鍦紝ID: " + ticketRegistrationDto.getPurchaseLedgerId());
+        }
+
+        LambdaQueryWrapper<TicketRegistration> duplicate = new LambdaQueryWrapper<TicketRegistration>()
+                .eq(TicketRegistration::getTenantId, tenantId)
+                .eq(TicketRegistration::getInvoiceNumber, ticketRegistrationDto.getInvoiceNumber())
+                .eq(TicketRegistration::getDeleteFlag, 0);
+        if (ticketRegistrationDto.getId() != null) duplicate.ne(TicketRegistration::getId, ticketRegistrationDto.getId());
+        if (ticketRegistrationMapper.selectCount(duplicate) > 0) throw new BaseException("璇ュ彂绁ㄥ彿鐮佸凡鐧昏");
+
+        BigDecimal registered = ticketRegistrationMapper.selectList(new LambdaQueryWrapper<TicketRegistration>()
+                .eq(TicketRegistration::getTenantId,tenantId)
+                .eq(TicketRegistration::getPurchaseLedgerId,purchaseLedger.getId())
+                .eq(TicketRegistration::getDeleteFlag,0)
+                .ne(ticketRegistrationDto.getId()!=null,TicketRegistration::getId,ticketRegistrationDto.getId()))
+                .stream().map(TicketRegistration::getInvoiceAmount).filter(java.util.Objects::nonNull)
+                .reduce(BigDecimal.ZERO,BigDecimal::add);
+        if (purchaseLedger.getContractAmount()!=null && registered.add(ticketRegistrationDto.getInvoiceAmount()).compareTo(purchaseLedger.getContractAmount())>0) {
+            throw new BaseException("鏉ョエ閲戦瓒呰繃閲囪喘鍗曞墿浣欏彲鐧昏閲戦锛�" + purchaseLedger.getContractAmount().subtract(registered));
         }
 
 
@@ -135,11 +166,23 @@
         TicketRegistration ticketRegistration = new TicketRegistration();
         BeanUtils.copyProperties(ticketRegistrationDto, ticketRegistration);
         ticketRegistration.setPurchaseContractNumber(purchaseLedger.getPurchaseContractNumber());
-        ticketRegistration.setTenantId(purchaseLedger.getTenantId());
+        ticketRegistration.setTenantId(tenantId);
+        ticketRegistration.setSupplierId(purchaseLedger.getSupplierId());
+        ticketRegistration.setSupplierName(purchaseLedger.getSupplierName());
         ticketRegistration.setIssueDate(ticketRegistrationDto.getIssueDate());
         ticketRegistration.setContractAmount(purchaseLedger.getContractAmount());
         ticketRegistration.setSalesLedgerId(purchaseLedger.getSalesLedgerId());
         ticketRegistration.setEnterDate(ticketRegistrationDto.getEnterDate());
+        ticketRegistration.setCurrency(StringUtils.isBlank(ticketRegistration.getCurrency()) ? "CNY" : ticketRegistration.getCurrency());
+        ticketRegistration.setInvoiceStatus(ticketRegistration.getInvoiceStatus()==null?1:ticketRegistration.getInvoiceStatus());
+        ticketRegistration.setVerificationStatus(ticketRegistration.getVerificationStatus()==null?0:ticketRegistration.getVerificationStatus());
+        ticketRegistration.setDeleteFlag(0);
+        ticketRegistration.setUpdateUser(userId);
+        ticketRegistration.setUpdateTime(DateUtils.getNowDate());
+        if (ticketRegistration.getTaxAmount()==null && ticketRegistration.getTaxRate()!=null) {
+            BigDecimal rate=ticketRegistration.getTaxRate().compareTo(BigDecimal.ONE)>0?ticketRegistration.getTaxRate().divide(new BigDecimal("100"),6,RoundingMode.HALF_UP):ticketRegistration.getTaxRate();
+            ticketRegistration.setTaxAmount(ticketRegistration.getInvoiceAmount().multiply(rate).divide(BigDecimal.ONE.add(rate),2,RoundingMode.HALF_UP));
+        }
 
         // 4. 澶勭悊瀛愯〃鏁版嵁
         List<SalesLedgerProduct> productData = ticketRegistrationDto.getProductData();
@@ -148,7 +191,15 @@
         }
 
         // 5. 鎵ц鎻掑叆鎴栨洿鏂版搷浣�
-        int rowsAffected = ticketRegistrationMapper.insert(ticketRegistration);
+        int rowsAffected;
+        if (ticketRegistration.getId()==null) {
+            ticketRegistration.setCreateUser(userId);
+            rowsAffected=ticketRegistrationMapper.insert(ticketRegistration);
+        } else {
+            rowsAffected=ticketRegistrationMapper.update(ticketRegistration,new LambdaQueryWrapper<TicketRegistration>()
+                    .eq(TicketRegistration::getId,ticketRegistration.getId()).eq(TicketRegistration::getTenantId,tenantId));
+            productRecordMapper.delete(new LambdaQueryWrapper<ProductRecord>().eq(ProductRecord::getTicketRegistrationId,ticketRegistration.getId()).eq(ProductRecord::getTenantId,tenantId));
+        }
 
         // 6. 澧炲姞閲囪喘鍙拌处浜у搧寮�绁ㄨ褰�
         List<SalesLedgerProduct> salesLedgerProducts = ticketRegistrationDto.getProductData();
@@ -166,6 +217,7 @@
                     productRecord.setSaleLedgerProjectId(salesLedgerProduct.getId());
                     productRecord.setId(null);
                     productRecord.setType("2");
+                    productRecord.setTenantId(tenantId);
                      insert = productRecordMapper.insert(productRecord);
                 }
                 if (insert <= 0) {
@@ -241,7 +293,7 @@
                 fileRecord.setName(originalFilename);
                 fileRecord.setUrl(formalFilePath.toString());
                 fileRecord.setCreateTime(LocalDateTime.now());
-                fileRecord.setType(4);
+                fileRecord.setType(FileNameType.INVOICE.getValue());
                 commonFileMapper.insert(fileRecord);
 
                 log.info("鏂囦欢杩佺Щ鎴愬姛: {} -> {}", tempFile.getTempPath(), formalFilePath);
@@ -255,59 +307,36 @@
 
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public int delRegistration(Long[] ids) {
-        // 鍒犻櫎閲囪喘鍙拌处浜у搧寮�绁ㄨ褰曞璞�
+        Long tenantId=SecurityUtils.getLoginUser().getTenantId();
         LambdaQueryWrapper<ProductRecord> productRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
-        productRecordLambdaQueryWrapper.in(ProductRecord::getId, Arrays.asList(ids));
+        productRecordLambdaQueryWrapper.in(ProductRecord::getTicketRegistrationId, Arrays.asList(ids)).eq(ProductRecord::getTenantId,tenantId);
         List<ProductRecord> productRecords = productRecordMapper.selectList(productRecordLambdaQueryWrapper);
-        if(CollectionUtils.isEmpty(productRecords)){
-            return 0;
-        }
-        LambdaQueryWrapper<TicketRegistration> ticketRegistrationLambdaQueryWrapper = new LambdaQueryWrapper<>();
-        ticketRegistrationLambdaQueryWrapper.in(TicketRegistration::getId, productRecords.stream().map(ProductRecord::getTicketRegistrationId).collect(Collectors.toList()));
-        List<TicketRegistration> ticketRegistrations = ticketRegistrationMapper.selectList(ticketRegistrationLambdaQueryWrapper);
-
-        // 淇敼浜у搧淇℃伅
         for (ProductRecord productRecord : productRecords) {
-            BigDecimal subtract = ticketRegistrations.get(0).getInvoiceAmount().subtract(productRecords.get(0).getTicketsAmount());
-            // 灏忎簬绛変簬0鍒犻櫎 锛屽ぇ浜�0淇敼
-            if(subtract.compareTo(BigDecimal.ZERO) <= 0){
-                ticketRegistrationMapper.deleteById(ticketRegistrations.get(0));
-                // 鍒犻櫎浠樻娴佹按
-                paymentRegistrationMapper.delete(new LambdaQueryWrapper<PaymentRegistration>().eq(PaymentRegistration::getTicketRegistrationId, ticketRegistrations.get(0).getId()));
-            }else if(subtract.compareTo(BigDecimal.ZERO) > 0){
-                ticketRegistrations.get(0).setInvoiceAmount(subtract);
-                ticketRegistrationMapper.updateById(ticketRegistrations.get(0));
-            }
-            LambdaQueryWrapper<SalesLedgerProduct> salesLedgerProductLambdaQueryWrapper = new LambdaQueryWrapper<>();
-            salesLedgerProductLambdaQueryWrapper.eq(SalesLedgerProduct::getId, productRecord.getSaleLedgerProjectId())
-                    .eq(SalesLedgerProduct::getType, 2);
-            List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(salesLedgerProductLambdaQueryWrapper);
-            if(!CollectionUtils.isEmpty(salesLedgerProducts)){
-                for (SalesLedgerProduct salesLedgerProduct : salesLedgerProducts) {
-                    salesLedgerProduct.setFutureTickets(salesLedgerProduct.getFutureTickets().add(productRecord.getTicketsNum()));
-                    salesLedgerProduct.setFutureTicketsAmount(salesLedgerProduct.getFutureTicketsAmount().add(productRecord.getTicketsAmount()));
-                    salesLedgerProduct.setTicketsAmount(salesLedgerProduct.getTaxInclusiveTotalPrice().subtract(productRecord.getFutureTicketsAmount()));
-                    salesLedgerProduct.setTicketsNum(salesLedgerProduct.getQuantity().subtract(productRecord.getFutureTickets()));
-                    salesLedgerProductMapper.updateById(salesLedgerProduct);
-
-                }
+            SalesLedgerProduct product=salesLedgerProductMapper.selectById(productRecord.getSaleLedgerProjectId());
+            if(product!=null){
+                product.setTicketsNum(nvl(product.getTicketsNum()).subtract(nvl(productRecord.getTicketsNum())).max(BigDecimal.ZERO));
+                product.setTicketsAmount(nvl(product.getTicketsAmount()).subtract(nvl(productRecord.getTicketsAmount())).max(BigDecimal.ZERO));
+                product.setFutureTickets(nvl(product.getFutureTickets()).add(nvl(productRecord.getTicketsNum())));
+                product.setFutureTicketsAmount(nvl(product.getFutureTicketsAmount()).add(nvl(productRecord.getTicketsAmount())));
+                salesLedgerProductMapper.updateById(product);
             }
         }
-        // 鍒犻櫎閲囪喘鍙拌处浜у搧寮�绁ㄨ褰�
         productRecordMapper.delete(productRecordLambdaQueryWrapper);
-        return 1;
+        paymentRegistrationMapper.delete(new LambdaQueryWrapper<PaymentRegistration>().in(PaymentRegistration::getTicketRegistrationId,Arrays.asList(ids)));
+        return ticketRegistrationMapper.delete(new LambdaQueryWrapper<TicketRegistration>().in(TicketRegistration::getId,Arrays.asList(ids)).eq(TicketRegistration::getTenantId,tenantId));
     }
 
     @Override
     public TicketRegistrationDto getRegistrationById(TicketRegistrationDto ticketRegistrationDto) {
-        TicketRegistration ticketRegistration = ticketRegistrationMapper.selectById(ticketRegistrationDto.getId());
+        TicketRegistration ticketRegistration = ticketRegistrationMapper.selectOne(new LambdaQueryWrapper<TicketRegistration>()
+                .eq(TicketRegistration::getId,ticketRegistrationDto.getId()).eq(TicketRegistration::getTenantId,SecurityUtils.getLoginUser().getTenantId()));
+        if (ticketRegistration == null) throw new BaseException("鏉ョエ鐧昏涓嶅瓨鍦�");
         LambdaQueryWrapper<PurchaseLedger> purchaseQueryWrapper = new LambdaQueryWrapper<>();
         purchaseQueryWrapper.eq(PurchaseLedger::getId, ticketRegistration.getPurchaseLedgerId());
         PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectOne(purchaseQueryWrapper);
-        if (ticketRegistration == null) {
-            throw new BaseException("閲囪喘鍙拌处涓嶅瓨鍦�");
-        }
+        if (purchaseLedger == null) throw new BaseException("閲囪喘鍙拌处涓嶅瓨鍦�");
         // 鍒涘缓骞跺~鍏匘TO
         TicketRegistrationDto resultDto = new TicketRegistrationDto();
         BeanUtils.copyProperties(ticketRegistration, resultDto);
@@ -325,7 +354,9 @@
     public List getTicketNo(TicketRegistrationDto ticketRegistrationDto) {
         LambdaQueryWrapper<TicketRegistration> queryWrapper = new LambdaQueryWrapper<>();
         queryWrapper.select(TicketRegistration::getId, TicketRegistration::getInvoiceNumber, TicketRegistration::getInvoiceAmount)
-                .eq(TicketRegistration::getPurchaseLedgerId, ticketRegistrationDto.getId());
+                .eq(TicketRegistration::getPurchaseLedgerId, ticketRegistrationDto.getId())
+                .eq(TicketRegistration::getTenantId,SecurityUtils.getLoginUser().getTenantId())
+                .eq(TicketRegistration::getDeleteFlag,0);
         List<Map<String, Object>> result = ticketRegistrationMapper.selectMaps(queryWrapper);
         // 灏嗕笅鍒掔嚎鍛藉悕杞崲涓洪┘宄板懡鍚�
         return result.stream().map(map -> map.entrySet().stream()
@@ -349,7 +380,8 @@
         if (!ObjectUtils.isEmpty(ticketRegistration.getIssueDateStart()) && !ObjectUtils.isEmpty(ticketRegistration.getIssueDateEnd())) {
             queryWrapper.between(TicketRegistration::getIssueDate, LocalDate.parse(ticketRegistration.getIssueDateStart(), DateTimeFormatter.ofPattern("yyyy-MM-dd")), LocalDate.parse(ticketRegistration.getIssueDateEnd(), DateTimeFormatter.ofPattern("yyyy-MM-dd")));
         }
-        queryWrapper.eq(TicketRegistration::getIssUerId, SecurityUtils.getUserId());
+        queryWrapper.eq(TicketRegistration::getTenantId, SecurityUtils.getLoginUser().getTenantId())
+                .eq(TicketRegistration::getDeleteFlag,0);
         IPage<TicketRegistration> ticketRegistrationIPage = ticketRegistrationMapper.selectPage(page, queryWrapper);
         // 璁$畻宸蹭粯娆鹃噾棰�
         if (CollectionUtils.isNotEmpty(ticketRegistrationIPage.getRecords())) {
@@ -385,7 +417,9 @@
 
     @Override
     public PurchaseLedgerDto getPuargeById(Long id) {
-        PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(id);
+        PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectOne(new LambdaQueryWrapper<PurchaseLedger>()
+                .eq(PurchaseLedger::getId,id).eq(PurchaseLedger::getTenantId,SecurityUtils.getLoginUser().getTenantId()));
+        if(purchaseLedger==null) throw new BaseException("閲囪喘鍙拌处涓嶅瓨鍦�");
         PurchaseLedgerDto purchaseLedgerDto = new PurchaseLedgerDto();
         BeanUtils.copyProperties(purchaseLedger, purchaseLedgerDto);
         SalesLedgerProduct salesLedgerProduct = new SalesLedgerProduct();
@@ -455,6 +489,8 @@
         }
     }
 
+    private BigDecimal nvl(BigDecimal value) { return value == null ? BigDecimal.ZERO : value; }
+
     /**
      * 涓嬪垝绾垮懡鍚嶈浆椹煎嘲鍛藉悕
      */
diff --git a/src/main/resources/mapper/basic/SupplierManageMapper.xml b/src/main/resources/mapper/basic/SupplierManageMapper.xml
index 9e65903..efec4d0 100644
--- a/src/main/resources/mapper/basic/SupplierManageMapper.xml
+++ b/src/main/resources/mapper/basic/SupplierManageMapper.xml
@@ -6,58 +6,48 @@
 
     <select id="supplierListPage" resultType="com.ruoyi.basic.dto.SupplierManageDto">
         SELECT
-        T1.id,
-        T1.supplier_name,
-        T1.taxpayer_identification_num,
-        T1.company_address,
-        T1.company_phone,
-        T1.bank_account_name,
-        T1.bank_account_num,
-        T1.contact_user_name,
-        T1.contact_user_phone,
-        T1.maintain_user_id,
-        T1.maintain_time,
-        T1.create_time,
-        T1.create_user,
-        T1.update_time,
-        T1.update_user,
-        T1.tenant_id,
+        T1.*,
         T2.nick_name AS maintainUserName
         FROM supplier_manage T1
         LEFT JOIN sys_user T2 ON T1.maintain_user_id = T2.user_id
         <where>
+            T1.tenant_id = #{supplierManageDto.tenantId}
+            AND T1.delete_flag = 0
             <if test="supplierManageDto.supplierName != null and supplierManageDto.supplierName != '' ">
                 AND T1.supplier_name LIKE CONCAT('%',#{supplierManageDto.supplierName},'%')
             </if>
+            <if test="supplierManageDto.supplierCode != null and supplierManageDto.supplierCode != ''">
+                AND T1.supplier_code LIKE CONCAT('%',#{supplierManageDto.supplierCode},'%')
+            </if>
+            <if test="supplierManageDto.productKeyword != null and supplierManageDto.productKeyword != ''">
+                AND EXISTS (SELECT 1 FROM supplier_product SP WHERE SP.supplier_id=T1.id AND SP.tenant_id=T1.tenant_id AND SP.delete_flag=0 AND SP.product_name LIKE CONCAT('%',#{supplierManageDto.productKeyword},'%'))
+            </if>
+            <if test="supplierManageDto.supplierLevel != null and supplierManageDto.supplierLevel != ''">
+                AND T1.supplier_level = #{supplierManageDto.supplierLevel}
+            </if>
+            <if test="supplierManageDto.cooperationStatus != null">
+                AND T1.cooperation_status = #{supplierManageDto.cooperationStatus}
+            </if>
+            <if test="supplierManageDto.qualificationStatus != null">
+                AND T1.qualification_status = #{supplierManageDto.qualificationStatus}
+            </if>
         </where>
+        ORDER BY T1.id DESC
     </select>
 
     <select id="supplierExportList" resultType="com.ruoyi.basic.excel.SupplierManageExcelDto">
         SELECT
-        T1.id,
-        T1.supplier_name,
-        T1.taxpayer_identification_num,
-        T1.company_address,
-        T1.company_phone,
-        T1.bank_account_name,
-        T1.bank_account_num,
-        T1.contact_user_name,
-        T1.contact_user_phone,
-        T1.maintain_user_id,
-        T1.maintain_time,
-        T1.create_time,
-        T1.create_user,
-        T1.update_time,
-        T1.update_user,
-        T1.tenant_id,
+        T1.*,
         T2.nick_name AS maintainUserName
         FROM supplier_manage T1
         LEFT JOIN sys_user T2 ON T1.maintain_user_id = T2.user_id
         <where>
+            T1.tenant_id = #{supplierManageDto.tenantId}
+            AND T1.delete_flag = 0
             <if test="supplierManageDto.supplierName != null and supplierManageDto.supplierName != '' ">
                 AND T1.supplier_name LIKE CONCAT('%',#{supplierManageDto.supplierName},'%')
             </if>
         </where>
     </select>
 
-</mapper>
\ No newline at end of file
+</mapper>
diff --git a/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml b/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
index 9abb583..e9ee182 100644
--- a/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
+++ b/src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
@@ -26,6 +26,9 @@
         left join product_record pr on pl.id = pr.purchase_ledger_id
         <where>
             1 = 1
+            <if test="c.tenantId != null">
+                AND pl.tenant_id = #{c.tenantId}
+            </if>
             <if test="c.purchaseContractNumber != null and c.purchaseContractNumber != ''">
                and pl.purchase_contract_number like concat('%',#{c.purchaseContractNumber},'%')
             </if>
@@ -73,4 +76,4 @@
         WHERE
             T4.id = #{id}
     </select>
-</mapper>
\ No newline at end of file
+</mapper>

--
Gitblit v1.9.3