From ee3faed7faf76d2e4892cc466d2d92a718732049 Mon Sep 17 00:00:00 2001
From: yaowanxin <3588231647@qq.com>
Date: 星期五, 19 九月 2025 09:38:07 +0800
Subject: [PATCH] 销售报价,报价商品管理

---
 src/main/java/com/ruoyi/sales/mapper/SalesQuotationMapper.java                   |   14 ++
 src/main/java/com/ruoyi/sales/pojo/SalesQuotation.java                           |   62 ++++++++++
 src/main/java/com/ruoyi/sales/controller/SalesQuotationController.java           |   31 +++++
 src/main/resources/mapper/sales/SalesQuotationProductMapper.xml                  |   15 ++
 src/main/java/com/ruoyi/sales/service/SalesQuotationProductService.java          |    8 +
 src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java        |   96 ++++++++++++++++
 src/main/java/com/ruoyi/sales/service/impl/SalesQuotationProductServiceImpl.java |   11 +
 src/main/resources/mapper/sales/SalesQuotationMapper.xml                         |   19 +++
 src/main/java/com/ruoyi/sales/mapper/SalesQuotationProductMapper.java            |   16 ++
 src/main/java/com/ruoyi/sales/dto/SalesQuotationDto.java                         |   14 ++
 src/main/java/com/ruoyi/sales/service/SalesQuotationService.java                 |   17 ++
 src/main/java/com/ruoyi/sales/pojo/SalesQuotationProduct.java                    |   49 ++++++++
 12 files changed, 352 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/ruoyi/sales/controller/SalesQuotationController.java b/src/main/java/com/ruoyi/sales/controller/SalesQuotationController.java
new file mode 100644
index 0000000..6df2ede
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/controller/SalesQuotationController.java
@@ -0,0 +1,31 @@
+package com.ruoyi.sales.controller;
+
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.sales.dto.SalesQuotationDto;
+import com.ruoyi.sales.service.SalesQuotationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/sales/quotation")
+public class SalesQuotationController {
+    @Autowired
+    private SalesQuotationService salesQuotationService;
+    @GetMapping("/list")
+    public AjaxResult getList(Page page, SalesQuotationDto salesQuotationDto) {
+        return AjaxResult.success(salesQuotationService.listPage(page, salesQuotationDto));
+    }
+    @PostMapping("/add")
+    public AjaxResult add(@RequestBody SalesQuotationDto salesQuotationDto) {
+        return AjaxResult.success(salesQuotationService.add(salesQuotationDto));
+    }
+    @PostMapping("/update")
+    public AjaxResult update(@RequestBody SalesQuotationDto salesQuotationDto) {
+        return AjaxResult.success(salesQuotationService.edit(salesQuotationDto));
+    }
+    @DeleteMapping("/delete")
+    public AjaxResult delete(@RequestBody Long id) {
+        return AjaxResult.success(salesQuotationService.delete(id));
+    }
+}
diff --git a/src/main/java/com/ruoyi/sales/dto/SalesQuotationDto.java b/src/main/java/com/ruoyi/sales/dto/SalesQuotationDto.java
new file mode 100644
index 0000000..c292a10
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/dto/SalesQuotationDto.java
@@ -0,0 +1,14 @@
+package com.ruoyi.sales.dto;
+
+import com.ruoyi.sales.pojo.SalesQuotation;
+import com.ruoyi.sales.pojo.SalesQuotationProduct;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class SalesQuotationDto extends SalesQuotation {
+    @ApiModelProperty(value = "鎶ヤ环鍟嗗搧")
+    private List<SalesQuotationProduct> products;
+}
diff --git a/src/main/java/com/ruoyi/sales/mapper/SalesQuotationMapper.java b/src/main/java/com/ruoyi/sales/mapper/SalesQuotationMapper.java
new file mode 100644
index 0000000..86f9c1a
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/mapper/SalesQuotationMapper.java
@@ -0,0 +1,14 @@
+package com.ruoyi.sales.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.ruoyi.sales.dto.SalesQuotationDto;
+import com.ruoyi.sales.pojo.SalesQuotation;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.data.repository.query.Param;
+
+@Mapper
+public interface SalesQuotationMapper extends BaseMapper<SalesQuotation> {
+    IPage<SalesQuotationDto> listPage(Page page,@Param("salesQuotationDto") SalesQuotationDto salesQuotationDto);
+}
diff --git a/src/main/java/com/ruoyi/sales/mapper/SalesQuotationProductMapper.java b/src/main/java/com/ruoyi/sales/mapper/SalesQuotationProductMapper.java
new file mode 100644
index 0000000..838e921
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/mapper/SalesQuotationProductMapper.java
@@ -0,0 +1,16 @@
+package com.ruoyi.sales.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.sales.pojo.SalesQuotationProduct;
+import io.lettuce.core.dynamic.annotation.Param;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+@Mapper
+public interface SalesQuotationProductMapper extends BaseMapper<SalesQuotationProduct> {
+//    List<SalesQuotationProduct> selectBySalesQuotationIds(List<Long> salesQuotationIds);
+
+    List<SalesQuotationProduct> selectBySalesQuotationId(@Param("id") Long id);
+}
diff --git a/src/main/java/com/ruoyi/sales/pojo/SalesQuotation.java b/src/main/java/com/ruoyi/sales/pojo/SalesQuotation.java
new file mode 100644
index 0000000..72c4f00
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/pojo/SalesQuotation.java
@@ -0,0 +1,62 @@
+package com.ruoyi.sales.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+@Data
+@TableName("sales_quotation")
+public class SalesQuotation {
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+    @ApiModelProperty(value = "鎶ヤ环鍗曠紪鍙�")
+    private String quotationNo;
+    @ApiModelProperty(value = "瀹㈡埛鍚嶇О")
+    private String customer;
+
+    @ApiModelProperty(value = "涓氬姟鍛�")
+    private String salesperson;
+    @ApiModelProperty(value = "鎶ヤ环鏃ユ湡")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate quotationDate;
+    @ApiModelProperty(value = "鏈夋晥鏈熻嚦")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate validDate;
+    @ApiModelProperty(value = "浠樻鏂瑰紡")
+    private String paymentMethod;
+    @ApiModelProperty(value = "浜よ揣鍛ㄦ湡澶╂暟")
+    private String deliveryPeriod;
+    @ApiModelProperty(value = "鐘舵��")
+    private String status;
+    @ApiModelProperty(value = "鎶ヤ环鎬婚噾棰�")
+    private Double totalAmount;
+
+    @ApiModelProperty(value = "澶囨敞")
+    private String remark;
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "淇敼鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty(value = "鍒涘缓鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT)
+    private Integer createUser;
+
+    @ApiModelProperty(value = "淇敼鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateUser;
+
+    @ApiModelProperty(value = "绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+}
diff --git a/src/main/java/com/ruoyi/sales/pojo/SalesQuotationProduct.java b/src/main/java/com/ruoyi/sales/pojo/SalesQuotationProduct.java
new file mode 100644
index 0000000..709dacf
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/pojo/SalesQuotationProduct.java
@@ -0,0 +1,49 @@
+package com.ruoyi.sales.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("sales_quotation_product")
+public class SalesQuotationProduct {
+    @ApiModelProperty(value = "鎶ヤ环鍟嗗搧ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+    @ApiModelProperty(value = "閿�鍞姤浠峰崟id")
+    private Long salesQuotationId;
+
+    @ApiModelProperty(value = "鍟嗗搧鍚嶇О")
+    private String product;
+    @ApiModelProperty(value = "鍟嗗搧瑙勬牸")
+    private String specification;
+    @ApiModelProperty(value = "鍗曚綅")
+    private String unit;
+    @ApiModelProperty(value = "鍗曚环")
+    private Double unitPrice;
+    @ApiModelProperty(value = "鏁伴噺")
+    private Integer quantity;
+    @ApiModelProperty(value = "閲戦")
+    private Double amount;
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty(value = "淇敼鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty(value = "鍒涘缓鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT)
+    private Integer createUser;
+
+    @ApiModelProperty(value = "淇敼鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateUser;
+
+    @ApiModelProperty(value = "绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+}
diff --git a/src/main/java/com/ruoyi/sales/service/SalesQuotationProductService.java b/src/main/java/com/ruoyi/sales/service/SalesQuotationProductService.java
new file mode 100644
index 0000000..6d37db3
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/service/SalesQuotationProductService.java
@@ -0,0 +1,8 @@
+package com.ruoyi.sales.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.sales.pojo.SalesQuotationProduct;
+
+
+public interface SalesQuotationProductService extends IService<SalesQuotationProduct> {
+}
diff --git a/src/main/java/com/ruoyi/sales/service/SalesQuotationService.java b/src/main/java/com/ruoyi/sales/service/SalesQuotationService.java
new file mode 100644
index 0000000..7f29a7f
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/service/SalesQuotationService.java
@@ -0,0 +1,17 @@
+package com.ruoyi.sales.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.sales.dto.SalesQuotationDto;
+import com.ruoyi.sales.pojo.SalesQuotation;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+public interface SalesQuotationService extends IService<SalesQuotation> {
+    IPage listPage(Page page, SalesQuotationDto salesQuotationDto);
+
+    boolean add(SalesQuotationDto salesQuotationDto);
+
+    boolean delete(Long id);
+
+    boolean edit(SalesQuotationDto salesQuotationDto);
+}
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationProductServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationProductServiceImpl.java
new file mode 100644
index 0000000..bb75795
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationProductServiceImpl.java
@@ -0,0 +1,11 @@
+package com.ruoyi.sales.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.sales.mapper.SalesQuotationProductMapper;
+import com.ruoyi.sales.pojo.SalesQuotationProduct;
+import com.ruoyi.sales.service.SalesQuotationProductService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class SalesQuotationProductServiceImpl extends ServiceImpl<SalesQuotationProductMapper, SalesQuotationProduct> implements SalesQuotationProductService {
+}
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java
new file mode 100644
index 0000000..104a712
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java
@@ -0,0 +1,96 @@
+package com.ruoyi.sales.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+import com.ruoyi.common.utils.bean.BeanUtils;
+import com.ruoyi.sales.dto.SalesQuotationDto;
+import com.ruoyi.sales.mapper.SalesQuotationMapper;
+import com.ruoyi.sales.mapper.SalesQuotationProductMapper;
+import com.ruoyi.sales.pojo.SalesQuotation;
+import com.ruoyi.sales.pojo.SalesQuotationProduct;
+import com.ruoyi.sales.service.SalesQuotationProductService;
+import com.ruoyi.sales.service.SalesQuotationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+@Transactional(rollbackFor = Exception.class)
+public class SalesQuotationServiceImpl extends ServiceImpl<SalesQuotationMapper, SalesQuotation> implements SalesQuotationService {
+    @Autowired
+    private SalesQuotationMapper salesQuotationMapper;
+    @Autowired
+    private SalesQuotationProductMapper salesQuotationProductMapper;
+    @Autowired
+    private SalesQuotationProductService salesQuotationProductService;
+    @Override
+    public IPage<SalesQuotationDto> listPage(Page page, SalesQuotationDto salesQuotationDto) {
+        IPage<SalesQuotationDto> salesQuotationDtoIPage = salesQuotationMapper.listPage(page, salesQuotationDto);
+        if(CollectionUtils.isEmpty(salesQuotationDtoIPage.getRecords())){
+            return salesQuotationDtoIPage;
+        }
+        salesQuotationDtoIPage.getRecords().forEach(record -> {
+            List<SalesQuotationProduct> products = salesQuotationProductMapper.selectBySalesQuotationId(record.getId());
+            record.setProducts(products);
+        });
+        return salesQuotationDtoIPage;
+    }
+
+    @Override
+    public boolean add(SalesQuotationDto salesQuotationDto) {
+        SalesQuotation salesQuotation = new SalesQuotation();
+        BeanUtils.copyProperties(salesQuotationDto, salesQuotation);
+        String quotationNo = salesQuotation.getQuotationNo();
+        salesQuotationMapper.insert(salesQuotation);
+//        if(salesQuotationMapper.insert(salesQuotation)!=1){
+//            return false;
+//        }
+        if(CollectionUtils.isEmpty(salesQuotationDto.getProducts())){
+            return true;
+        }
+        List<SalesQuotationProduct> products = salesQuotationDto.getProducts().stream().map(product -> {
+            SalesQuotationProduct salesQuotationProduct = new SalesQuotationProduct();
+            BeanUtils.copyProperties(product, salesQuotationProduct);
+            salesQuotationProduct.setSalesQuotationId(salesQuotationMapper.selectOne(new LambdaQueryWrapper<SalesQuotation>().eq(SalesQuotation::getQuotationNo, quotationNo)).getId());
+            return salesQuotationProduct;
+        }).collect(Collectors.toList());
+        salesQuotationProductService.saveBatch(products);
+        return true;
+    }
+    @Override
+    public boolean edit(SalesQuotationDto salesQuotationDto) {
+        SalesQuotation salesQuotation = new SalesQuotation();
+        BeanUtils.copyProperties(salesQuotationDto, salesQuotation);
+        if(salesQuotationMapper.updateById(salesQuotation)!=1){
+            return false;
+        }
+        salesQuotationProductMapper.delete(new LambdaQueryWrapper<SalesQuotationProduct>().eq(SalesQuotationProduct::getSalesQuotationId, salesQuotationDto.getId()));
+        if(CollectionUtils.isEmpty(salesQuotationDto.getProducts())){
+            return true;
+        }
+        List<SalesQuotationProduct> products = salesQuotationDto.getProducts().stream().map(product -> {
+            SalesQuotationProduct salesQuotationProduct = new SalesQuotationProduct();
+            BeanUtils.copyProperties(product, salesQuotationProduct);
+            salesQuotationProduct.setSalesQuotationId(salesQuotation.getId());
+            return salesQuotationProduct;
+        }).collect(Collectors.toList());
+        salesQuotationProductService.saveBatch(products);
+        return true;
+    }
+    @Override
+    public boolean delete(Long id) {
+        salesQuotationMapper.deleteById(id);
+        salesQuotationProductMapper.delete(new LambdaQueryWrapper<SalesQuotationProduct>().eq(SalesQuotationProduct::getSalesQuotationId, id));
+        return true;
+    }
+
+
+}
diff --git a/src/main/resources/mapper/sales/SalesQuotationMapper.xml b/src/main/resources/mapper/sales/SalesQuotationMapper.xml
new file mode 100644
index 0000000..a39cd45
--- /dev/null
+++ b/src/main/resources/mapper/sales/SalesQuotationMapper.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.sales.mapper.SalesQuotationMapper">
+    <select id="listPage" resultType="com.ruoyi.sales.dto.SalesQuotationDto">
+        SELECT * FROM sales_quotation
+        WHERE 1=1
+        <if test="salesQuotationDto.quotationNo != null and salesQuotationDto.quotationNo != '' ">
+            AND quotation_no LIKE CONCAT('%',#{salesQuotationDto.quotationNo},'%')
+        </if>
+        <if test="salesQuotationDto.customer != null and salesQuotationDto.customer != '' ">
+            AND customer = #{salesQuotationDto.customer}
+        </if>
+        <if test="salesQuotationDto.status != null and salesQuotationDto.status != '' ">
+            AND status = #{salesQuotationDto.status}
+        </if>
+    </select>
+</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/sales/SalesQuotationProductMapper.xml b/src/main/resources/mapper/sales/SalesQuotationProductMapper.xml
new file mode 100644
index 0000000..fa3745e
--- /dev/null
+++ b/src/main/resources/mapper/sales/SalesQuotationProductMapper.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.sales.mapper.SalesQuotationProductMapper">
+<!--    <select id="selectBySalesQuotationIds" resultType="com.ruoyi.sales.pojo.SalesQuotationProduct">-->
+<!--        select * from sales_quotation_product where sales_quotation_id in-->
+<!--        <foreach collection="salesQuotationIds" item="salesQuotationId" open="(" close=")" separator=",">-->
+<!--            #{salesQuotationId}-->
+<!--        </foreach>-->
+<!--    </select>-->
+    <select id="selectBySalesQuotationId" resultType="com.ruoyi.sales.pojo.SalesQuotationProduct">
+        select * from sales_quotation_product where sales_quotation_id = #{id}
+    </select>
+</mapper>

--
Gitblit v1.9.3