Selaa lähdekoodia

化纤统计图表

xuezizhuo 1 vuosi sitten
vanhempi
säilyke
b72bb2aaf0
33 muutettua tiedostoa jossa 6164 lisäystä ja 12 poistoa
  1. 2 2
      zkqy-custom-business/src/main/java/com/zkqy/business/controller/ProductCodeController.java
  2. 9 8
      zkqy-custom-business/src/main/java/com/zkqy/business/controller/ProductInventoryController.java
  3. 8 0
      zkqy-custom-business/src/main/java/com/zkqy/business/controller/ProductWarehousingRecordController.java
  4. 66 0
      zkqy-custom-business/src/main/java/com/zkqy/business/controller/SaleOrderController.java
  5. 11 0
      zkqy-custom-business/src/main/java/com/zkqy/business/domain/SaleOrder.java
  6. 8 0
      zkqy-custom-business/src/main/java/com/zkqy/business/mapper/ProductInventoryMapper.java
  7. 12 0
      zkqy-custom-business/src/main/java/com/zkqy/business/mapper/ProductWarehousingRecordMapper.java
  8. 114 0
      zkqy-custom-business/src/main/java/com/zkqy/business/mapper/SaleOrderMapper.java
  9. 7 0
      zkqy-custom-business/src/main/java/com/zkqy/business/service/IProductInventoryService.java
  10. 10 0
      zkqy-custom-business/src/main/java/com/zkqy/business/service/IProductWarehousingRecordService.java
  11. 39 0
      zkqy-custom-business/src/main/java/com/zkqy/business/service/ISaleOrderService.java
  12. 22 0
      zkqy-custom-business/src/main/java/com/zkqy/business/service/impl/ProductInventoryServiceImpl.java
  13. 27 0
      zkqy-custom-business/src/main/java/com/zkqy/business/service/impl/ProductWarehousingRecordServiceImpl.java
  14. 455 0
      zkqy-custom-business/src/main/java/com/zkqy/business/service/impl/SaleOrderServiceImpl.java
  15. 13 0
      zkqy-custom-business/src/main/resources/mapper/business/ProductInventoryMapper.xml
  16. 49 0
      zkqy-custom-business/src/main/resources/mapper/business/ProductWarehousingRecordMapper.xml
  17. 622 0
      zkqy-custom-business/src/main/resources/mapper/business/SaleOrderMapper.xml
  18. 107 0
      zkqy-ui/src/api/statisticalAnalysis/index.js
  19. 1 1
      zkqy-ui/src/views/orderMange/customerMange/index.vue
  20. 1 0
      zkqy-ui/src/views/orderMange/index.vue
  21. 2 1
      zkqy-ui/src/views/orderMange/retailMange/index.vue
  22. 239 0
      zkqy-ui/src/views/orderMange/statisticalAnalysis/ProductionSalesRatio.vue
  23. 265 0
      zkqy-ui/src/views/orderMange/statisticalAnalysis/customerOrderRanking.vue
  24. 601 0
      zkqy-ui/src/views/orderMange/statisticalAnalysis/customerStatistics.vue
  25. 467 0
      zkqy-ui/src/views/orderMange/statisticalAnalysis/fastSellingProduct.vue
  26. 87 0
      zkqy-ui/src/views/orderMange/statisticalAnalysis/index.vue
  27. 286 0
      zkqy-ui/src/views/orderMange/statisticalAnalysis/peoductLevel.vue
  28. 544 0
      zkqy-ui/src/views/orderMange/statisticalAnalysis/productsSoldRanking.vue
  29. 259 0
      zkqy-ui/src/views/orderMange/statisticalAnalysis/saleCategoryProportion.vue
  30. 70 0
      zkqy-ui/src/views/orderMange/statisticalAnalysis/saleIndex.vue
  31. 445 0
      zkqy-ui/src/views/orderMange/statisticalAnalysis/saleOrderRanking.vue
  32. 543 0
      zkqy-ui/src/views/orderMange/statisticalAnalysis/salesStatistics.vue
  33. 773 0
      zkqy-ui/src/views/orderMange/statisticalAnalysis/yield.vue

+ 2 - 2
zkqy-custom-business/src/main/java/com/zkqy/business/controller/ProductCodeController.java

@@ -41,8 +41,8 @@ public class ProductCodeController extends BaseController
  * 查询产品编码列表
  */
 //@PreAuthorize("@ss.hasPermi('system:productCode:list')")
-@GetMapping("/list")
-@ApiOperation(value = "查询产品编码列表")
+    @GetMapping("/list")
+    @ApiOperation(value = "查询产品编码列表")
     public TableDataInfo list(ProductCode productCode)
     {
         startPage();

+ 9 - 8
zkqy-custom-business/src/main/java/com/zkqy/business/controller/ProductInventoryController.java

@@ -16,14 +16,7 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-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 com.zkqy.common.annotation.Log;
 import com.zkqy.common.core.controller.BaseController;
 import com.zkqy.common.core.domain.AjaxResult;
@@ -226,4 +219,12 @@ public class ProductInventoryController extends BaseController {
 //    }
 
 
+    /**
+     * 统计库存各个类型下等级货品重量
+     */
+    @GetMapping("/statisticsSuttleByLevels")
+    public AjaxResult statisticsSuttleByLevels(@RequestParam String productType){
+        return AjaxResult.success(productInventoryService.statisticsSuttleByLevels(productType));
+    }
+
 }

+ 8 - 0
zkqy-custom-business/src/main/java/com/zkqy/business/controller/ProductWarehousingRecordController.java

@@ -119,4 +119,12 @@ public class ProductWarehousingRecordController extends BaseController
         return success(true);
     }
 
+    /**
+     * 统计产量---年月日季度查询
+     */
+    @GetMapping("/productionStatistics")
+    public AjaxResult productionStatistics(@RequestParam("timeType") String timeType,@RequestParam("timeParam") String timeParam){
+        return AjaxResult.success(productWarehousingRecordService.productionStatistics(timeType,timeParam));
+    }
+
 }

+ 66 - 0
zkqy-custom-business/src/main/java/com/zkqy/business/controller/SaleOrderController.java

@@ -1,6 +1,9 @@
 package com.zkqy.business.controller;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import javax.servlet.http.HttpServletResponse;
 
 import com.zkqy.business.domain.ProductInvoice;
@@ -210,5 +213,68 @@ public class SaleOrderController extends BaseController {
         return toAjax(saleOrderService.updateOrder(saleOrder));
     }
 
+    /**
+     * 查询销售单下单前10名客户信息单据数量货品总量
+     */
+    @GetMapping("/saleOrderTop10List")
+    public AjaxResult saleOrderTop10List(){
+        return AjaxResult.success(saleOrderService.saleOrderTop10List());
+    }
+
+    /**
+     * 统计客户单量和每个货品的数量月、季度、年度进行筛选,默认年度
+     */
+    @PostMapping("/customerOrderStatistics")
+    public AjaxResult customerOrderStatistics(@RequestBody Map<String,Object> map){
+        return AjaxResult.success(saleOrderService.customerStatistics(map));
+    }
+
+    /**
+     * 按品钟查询已售货品数量最多得产品、年-月-日-季度筛选
+     */
+    @PostMapping("/mostItemsSold")
+    public AjaxResult mostItemsSold(@RequestBody Map<String,Object> map){
+        return AjaxResult.success(saleOrderService.mostItemsSold(map));
+    }
+
+    /**
+     * 统计各销售员当月销售单量和单据货品总数量可选择日、月、季度、年度进行筛选
+     */
+    @PostMapping("/saleOrderCountBySalesman")
+    public AjaxResult saleOrderCountBySalesman(@RequestBody Map<String,Object> map){
+        return AjaxResult.success(saleOrderService.saleOrderCountBySalesman(map,getTenantId()));
+    }
+
+    /**
+     * 销售品类占比  各个已销售的产品中各类产品的占用百分比
+     */
+    @GetMapping("/productPercentage")
+    public AjaxResult productPercentage(){
+        return AjaxResult.success(saleOrderService.productPercentage());
+    }
+
+    /**
+     * 销售统计(产销比例)已销售的产品和生产产品的比较、可选择日、月、季度、年度进行筛选
+     */
+    @PostMapping("/productionMarketingRatio")
+    public AjaxResult productionMarketingRatio(@RequestBody Map<String,Object> map){
+        return AjaxResult.success(saleOrderService.productionMarketingRatio(map));
+    }
+
+    /**
+     * 销售排行   按时间可以进行查询、默认当月、可选择日、月、季度、年度进行筛选
+     */
+    @PostMapping("/saleOrderRanking")
+    public AjaxResult saleOrderRanking(@RequestBody Map<String,Object> map){
+        return AjaxResult.success(saleOrderService.saleOrderRanking(map));
+    }
+
+    /**
+     * 当月快销产品统计、可选择日、月、季度、年度进行筛选
+     */
+    @PostMapping("/fastSellingProduct")
+    public AjaxResult fastSellingProduct(@RequestBody Map<String,Object> map){
+        return AjaxResult.success(saleOrderService.fastSellingProduct(map));
+    }
 
 }

+ 11 - 0
zkqy-custom-business/src/main/java/com/zkqy/business/domain/SaleOrder.java

@@ -127,6 +127,9 @@ public class SaleOrder extends BaseEntity
     /** 批号 */
     private String lotNumber;
 
+    /** 完成时间 */
+    private Date completionTime;
+
     //超级查询
     private String queryParam;
 
@@ -389,6 +392,14 @@ public class SaleOrder extends BaseEntity
         this.queryParam = queryParam;
     }
 
+    public Date getCompletionTime() {
+        return completionTime;
+    }
+
+    public void setCompletionTime(Date completionTime) {
+        this.completionTime = completionTime;
+    }
+
     @Override
     public String toString() {
         return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

+ 8 - 0
zkqy-custom-business/src/main/java/com/zkqy/business/mapper/ProductInventoryMapper.java

@@ -1,6 +1,7 @@
 package com.zkqy.business.mapper;
 
 import java.util.List;
+import java.util.Map;
 
 import com.zkqy.business.domain.ProductInventory;
 import com.zkqy.business.domain.vo.ProductCodeListVO;
@@ -98,4 +99,11 @@ public interface ProductInventoryMapper {
      */
     ProductInventory selectProductInventoryInfo(ProductInventory productInventory);
 
+    /**
+     * 统计库存各个类型下等级货品重量
+     * @param productType 产品类型
+     * @return
+     */
+    List<Map<String,Object>> statisticsSuttleByLevels(String productType);
+
 }

+ 12 - 0
zkqy-custom-business/src/main/java/com/zkqy/business/mapper/ProductWarehousingRecordMapper.java

@@ -1,8 +1,11 @@
 package com.zkqy.business.mapper;
 
 import java.util.List;
+import java.util.Map;
+
 import com.zkqy.business.domain.ProductWarehousingRecord;
 import com.zkqy.business.domain.vo.ProductCodeListVO;
+import org.apache.ibatis.annotations.MapKey;
 import org.apache.ibatis.annotations.Param;
 
 /**
@@ -84,4 +87,13 @@ public interface ProductWarehousingRecordMapper
      */
     public int deleteProductWarehousingRecordByUUID(String qrCodeId);
 
+    /**
+     * 统计产量---年月日季度查询
+     * @param timeType 时间类型
+     * @param timeParam 时间参数
+     * @return
+     */
+    @MapKey("id")
+    List<Map<String,Object>> productionStatistics(@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+
 }

+ 114 - 0
zkqy-custom-business/src/main/java/com/zkqy/business/mapper/SaleOrderMapper.java

@@ -6,7 +6,9 @@ import java.util.Objects;
 
 import com.zkqy.business.domain.SaleOrder;
 import com.zkqy.business.domain.vo.SaleOrderVO;
+import org.apache.ibatis.annotations.MapKey;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * 销售订单Mapper接口
@@ -30,6 +32,7 @@ public interface SaleOrderMapper {
      * @param saleOrderNo 销售订单主键
      * @return 销售订单
      */
+    @MapKey("saleNo")
     public Map<String, Object> selectSaleOrderByNo(String saleOrderNo);
 
     /**
@@ -114,4 +117,115 @@ public interface SaleOrderMapper {
      */
     List<SaleOrderVO> saleOrderList(SaleOrder saleOrder);
 
+    /**
+     * 查询销售单下单前10名客户信息、单据总量和货品总量信息
+     */
+    @MapKey("customerNo")
+    List<Map<String,Object>> saleOrderTop10List(List<String> customerNoList);
+
+    /**
+     * 查询零售单单下单前10名客户信息、单据总量和货品总量信息
+     */
+    @MapKey("customerNo")
+    List<Map<String,Object>> saleRetailOrderTop10List(List<String> customerNoList);
+
+    /**
+     * 查询销售单下单前10名客户编号
+     */
+    List<String> saleOrderTop10CustomerNoList();
+
+    /**
+     * 根据客户单号查询销售单下单数量
+     */
+    Map<String,Object> selectSaleOrderCountByCustomerNo(@Param("customerNo")String customerNo,@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+
+    /**
+     * 根据客户单号查询零售单单下单数量
+     */
+    Map<String,Object> selectRetailOrderCountByCustomerNo(@Param("customerNo")String customerNo,@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+
+    /**
+     * 根据客户编号查询销售单下单货品数量
+     */
+    List<Map<String,Object>> selectSaleOrderProductCountByCustomerNo(@Param("customerNo")String customerNo,@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+
+    /**
+     * 根据客户编号查询零售单单下单货品数量
+     */
+    List<Map<String,Object>> selectRetailOrderProductCountByCustomerNo(@Param("customerNo")String customerNo,@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+
+    /**
+     * 按品钟查询已售货品数量最多得产品、年-月-日-季度筛选
+     */
+    @MapKey("productId")
+    List<Map<String,Object>> selectMaxProductCountByproductType(@Param("productType") String productType,@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+
+    /**
+     * 每个销售员销售销售单货品总量、年-月-日-季度筛选
+     */
+    @MapKey("saleId")
+    List<Map<String,Object>> saleOrderProductCountBySalesman(@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+
+    /**
+     * 每个销售员销售零售单货品总量、年-月-日-季度筛选
+     */
+    @MapKey("saleId")
+    List<Map<String,Object>> retailOrderProductCountBySalesman(@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+    /**
+     * 每个销售员销售销售单单据总量、年-月-日-季度筛选
+     */
+    @MapKey("saleId")
+    List<Map<String,Object>> saleOrderCountBySalesman(@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+
+    /**
+     * 每个销售员销售零售单单据总量、年-月-日-季度筛选
+     */
+    @MapKey("saleId")
+    List<Map<String,Object>> retailOrderCountBySalesman(@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+
+    /**
+     * 销售单已销售产品中各类产品的总重量
+     */
+    @MapKey("productType")
+    List<Map<String,Object>> saleOrderProductWeightByProductType();
+
+    /**
+     * 零售单已销售产品中各类产品的总重量
+     */
+    @MapKey("productType")
+    List<Map<String,Object>> retailOrderProductWeightByProductType();
+
+    /**
+     * 销售单销量
+     */
+    Map<String,Object> saleOrderSaleVolume(@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+
+    /**
+     * 零售单销量
+     */
+    Map<String,Object> retailOrderSaleVolume(@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+
+    /**
+     * 产量
+     */
+    Map<String,Object> productionVolume(@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+
+    /**
+     * 销售排行   按时间可以进行查询、默认当月、可选择日、月、季度、年度进行筛选
+     */
+    @MapKey("productId")
+    List<Map<String,Object>> saleOrderRanking(@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+
+    /***
+     * 快销品,查询零售单中每个产品的销量
+     */
+    @MapKey("productId")
+    List<Map<String,Object>> retailFastSellingProduct(@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+
+    /***
+     * 快销品,查询零售单中每个产品的销量
+     */
+    @MapKey("productId")
+    List<Map<String,Object>> saleFastSellingProduct(@Param("timeType") String timeType,@Param("timeParam") String timeParam);
+
 }

+ 7 - 0
zkqy-custom-business/src/main/java/com/zkqy/business/service/IProductInventoryService.java

@@ -102,4 +102,11 @@ public interface IProductInventoryService {
      */
     int batchInsertProductInventory(List<ProductInventory> productInventoryList);
 
+    /**
+     * 统计库存各个类型下等级货品重量
+     * @param productType 产品类型
+     * @return
+     */
+    Map<String,Object> statisticsSuttleByLevels(String productType);
+
 }

+ 10 - 0
zkqy-custom-business/src/main/java/com/zkqy/business/service/IProductWarehousingRecordService.java

@@ -1,6 +1,8 @@
 package com.zkqy.business.service;
 
 import java.util.List;
+import java.util.Map;
+
 import com.zkqy.business.domain.ProductWarehousingRecord;
 import com.zkqy.business.domain.vo.ProductCodeListVO;
 import org.apache.ibatis.annotations.Param;
@@ -76,4 +78,12 @@ public interface IProductWarehousingRecordService
      */
     ProductWarehousingRecord selectProductWarehousingRecordWhetherExist(String qrCode,String qrCodeId);
 
+    /**
+     * 统计产量---年月日季度查询
+     * @param timeType
+     * @param timeParam
+     * @return
+     */
+    Map<String,Object> productionStatistics(@Param("timeType") String timeType, @Param("timeParam") String timeParam);
+
 }

+ 39 - 0
zkqy-custom-business/src/main/java/com/zkqy/business/service/ISaleOrderService.java

@@ -124,4 +124,43 @@ public interface ISaleOrderService {
      */
     int updateOrder(SaleOrder saleOrder);
 
+    /**
+     * 查询销售单下单前10名客户信息单据数量货品总量
+     */
+    List<Map<String, Object>> saleOrderTop10List();
+
+    /**
+     * 统计客户单量和每个货品的数量月、季度、年度进行筛选,默认年度
+     */
+    Map<String, Object> customerStatistics(Map<String, Object> map);
+
+    /**
+     * 按品钟查询已售货品数量最多得产品、年-月-日-季度筛选
+     */
+    List<Map<String, Object>> mostItemsSold(Map<String, Object> map);
+
+    /**
+     * 统计各销售员当月销售单量和单据货品总数量可选择日、月、季度、年度进行筛选
+     */
+    List<Map<String, Object>> saleOrderCountBySalesman(Map<String, Object> map,Long tenantId);
+
+    /**
+     * 销售品类占比  各个已销售的产品中各类产品的占用百分比
+     */
+    List<Map<String, Object>> productPercentage();
+
+    /**
+     * 销售统计(产销比例)已销售的产品和生产产品的比较、可选择日、月、季度、年度进行筛选
+     */
+    Map<String, Object> productionMarketingRatio(Map<String, Object> map);
+
+    /**
+     * 销售排行   按时间可以进行查询、默认当月、可选择日、月、季度、年度进行筛选
+     */
+    List<Map<String,Object>> saleOrderRanking(Map<String, Object> map);
+
+    /**
+     * 当月快销产品统计、可选择日、月、季度、年度进行筛选
+     */
+    List<Map<String,Object>> fastSellingProduct(Map<String, Object> map);
 }

+ 22 - 0
zkqy-custom-business/src/main/java/com/zkqy/business/service/impl/ProductInventoryServiceImpl.java

@@ -1,6 +1,7 @@
 package com.zkqy.business.service.impl;
 
 import java.text.DecimalFormat;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -396,6 +397,27 @@ public class ProductInventoryServiceImpl implements IProductInventoryService {
         return productInventoryMapper.batchInsertProductInventory(productInventoryList);
     }
 
+    @Override
+    public Map<String, Object> statisticsSuttleByLevels(String productType) {
+        //品名
+        List<String> productNameList = new ArrayList<>();
+        //产品详情
+        List<Map<String, Object>> productDetailList = new ArrayList<>();
+
+        List<Map<String, Object>> mapList = productInventoryMapper.statisticsSuttleByLevels(productType);
+        for (Map<String, Object> map : mapList){
+            productNameList.add(map.get("name").toString());
+            Map<String,Object> productDetail = new HashMap<>();
+            productDetail.put("name",map.get("name"));
+            productDetail.put("data",map.get("suttle"));
+            productDetailList.add(productDetail);
+        }
+        Map<String,Object> result = new HashMap<>();
+        result.put("products",productNameList);
+        result.put("output",productDetailList);
+        return result;
+    }
+
 
     //保留两位小数
     public Double handlingWeight(Double weight) {

+ 27 - 0
zkqy-custom-business/src/main/java/com/zkqy/business/service/impl/ProductWarehousingRecordServiceImpl.java

@@ -1,6 +1,9 @@
 package com.zkqy.business.service.impl;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import com.zkqy.business.domain.vo.ProductCodeListVO;
 import com.zkqy.common.utils.DateUtils;
@@ -105,4 +108,28 @@ public class ProductWarehousingRecordServiceImpl implements IProductWarehousingR
     public ProductWarehousingRecord selectProductWarehousingRecordWhetherExist(String qrCode, String qrCodeId) {
         return productWarehousingRecordMapper.selectProductWarehousingRecordWhetherExist(qrCode,qrCodeId);
     }
+
+    @Override
+    public Map<String,Object> productionStatistics(String timeType, String timeParam) {
+        List<Map<String, Object>> mapList = productWarehousingRecordMapper.productionStatistics(timeType, timeParam);
+        //品名
+        List<String> productNameList = new ArrayList<>();
+        //产品详情
+        List<Map<String, Object>> productDetailList = new ArrayList<>();
+
+        for (Map<String, Object> map : mapList){
+            productNameList.add(map.get("name").toString());
+            Map<String,Object> productDetail = new HashMap<>();
+            productDetail.put("name",map.get("name"));
+            productDetail.put("data",map.get("suttle"));
+            productDetail.put("spec",map.get("spec"));
+            productDetail.put("levels",map.get("levels"));
+            productDetail.put("productColour",map.get("productColour"));
+            productDetailList.add(productDetail);
+        }
+        Map<String,Object> result = new HashMap<>();
+        result.put("products",productNameList);
+        result.put("output",productDetailList);
+        return result;
+    }
 }

+ 455 - 0
zkqy-custom-business/src/main/java/com/zkqy/business/service/impl/SaleOrderServiceImpl.java

@@ -1,5 +1,6 @@
 package com.zkqy.business.service.impl;
 
+import java.text.DecimalFormat;
 import java.util.*;
 
 import com.zkqy.business.domain.ProductInvoice;
@@ -9,9 +10,11 @@ import com.zkqy.business.mapper.ProductInvoiceMapper;
 import com.zkqy.business.mapper.SaleCraftMapper;
 import com.zkqy.business.mapper.SaleProductsMapper;
 import com.zkqy.common.core.domain.entity.SysRole;
+import com.zkqy.common.core.domain.entity.SysUser;
 import com.zkqy.common.utils.DateUtils;
 import com.zkqy.common.utils.SecurityUtils;
 import com.zkqy.common.utils.bean.BeanUtils;
+import com.zkqy.system.service.ISysUserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.zkqy.business.mapper.SaleOrderMapper;
@@ -39,6 +42,9 @@ public class SaleOrderServiceImpl implements ISaleOrderService {
     @Autowired
     private ProductInvoiceMapper productInvoiceMapper;
 
+    @Autowired
+    private ISysUserService iSysUserService;
+
     /**
      * 查询销售订单
      *
@@ -323,4 +329,453 @@ public class SaleOrderServiceImpl implements ISaleOrderService {
         return saleOrderMapper.updateSaleOrder(saleOrder);
     }
 
+    @Override
+    public List<Map<String, Object>> saleOrderTop10List() {
+        List<Map<String, Object>> list = new ArrayList<>();
+        //查询下单前10名客户编号
+        List<String> customerNoList = saleOrderMapper.saleOrderTop10CustomerNoList();
+        if(customerNoList.size() > 0){
+            //查询销售单数量
+            List<Map<String, Object>> saleOrderList = saleOrderMapper.saleOrderTop10List(customerNoList);
+            //查询零售单数量
+            List<Map<String, Object>> retailList = saleOrderMapper.saleRetailOrderTop10List(customerNoList);
+
+            for (Map<String, Object> map : saleOrderList){
+
+                Map<String, Object> result = new HashMap<>();
+                result.put("customerNo",map.get("customerNo"));
+                result.put("customerName",map.get("customerName"));
+//                result.put("orderCount",map.get("orderCount"));
+                Long orderCount = (Long) map.get("orderCount");
+                Double weight = (Double) map.get("weight");
+                for (Map<String, Object> retail : retailList){
+                    if(map.get("customerNo").toString().equals(retail.get("customerNo").toString())){
+                        weight = weight + (Double) retail.get("weight");
+                        map.put("weight",handlingWeight(weight));
+                        orderCount += (Long) retail.get("orderCount");
+                        map.put("orderCount",orderCount);
+                    }
+                }
+                result.put("weight",handlingWeight(weight));
+                result.put("orderCount",orderCount);
+                list.add(result);
+            }
+        }
+
+        return list;
+    }
+
+    @Override
+    public Map<String, Object> customerStatistics(Map<String, Object> map) {
+        Map<String, Object> result = new HashMap<>();
+        //销售单数量
+        Map<String, Object> saleOrderCount = saleOrderMapper.selectSaleOrderCountByCustomerNo(map.get("customerNo").toString(),map.get("timeType").toString(),map.get("timeParam").toString());
+        //零售单数量
+        Map<String, Object> retailOrderCount = saleOrderMapper.selectRetailOrderCountByCustomerNo(map.get("customerNo").toString(),map.get("timeType").toString(),map.get("timeParam").toString());
+
+        Long saleCount = saleOrderCount.get("orderCount") == null ? 0L : (Long) saleOrderCount.get("orderCount");
+        Long retailCount = retailOrderCount.get("orderCount") == null ? 0L : (Long) retailOrderCount.get("orderCount");
+
+        result.put("orderCount",saleCount + retailCount);
+
+
+//        result.put("orderCount",saleOrderCount);
+
+        //各个货品重量
+        //销售单
+        List<Map<String, Object>> saleList = saleOrderMapper.selectSaleOrderProductCountByCustomerNo(map.get("customerNo").toString(),map.get("timeType").toString(), map.get("timeParam").toString());
+        //零售单
+        List<Map<String, Object>> retailList = saleOrderMapper.selectRetailOrderProductCountByCustomerNo(map.get("customerNo").toString(),map.get("timeType").toString(), map.get("timeParam").toString());
+
+
+        List<Map<String, Object>> addList = new ArrayList<>();
+
+        //筛选出销售单中不存在的零售单货品
+        for (Map<String, Object> retailItem : retailList){
+            String saleProductId = retailItem.get("productId").toString();
+            String saleProductColour = retailItem.get("productColour").toString();
+            String customerNo = retailItem.get("customerNo").toString();
+            boolean exists = saleList.stream()
+                    .anyMatch(saleItem ->
+                            saleProductId.equals(saleItem.get("productId").toString()) &&
+                                    saleProductColour.equals(saleItem.get("productColour").toString()) &&
+                                    customerNo.equals(saleItem.get("customerNo").toString())
+                    );
+            if(!exists){
+                addList.add(retailItem);
+            }
+
+        }
+
+        for (Map<String, Object> saleItem : saleList){
+            String saleProductId = saleItem.get("productId").toString();
+            String saleProductColour = saleItem.get("productColour").toString();
+            String customerNo = saleItem.get("customerNo").toString();
+            Double weight = (Double) saleItem.get("weight");
+
+            for (Map<String, Object> retailItem : retailList){
+                if(retailItem.get("productId").toString().equals(saleProductId) && retailItem.get("productColour").toString().equals(saleProductColour) && customerNo.equals(retailItem.get("customerNo").toString())){
+                    Double weight1 = (Double) retailItem.get("weight");
+                    weight += weight1;
+                    saleItem.put("weight",handlingWeight(weight));
+                    break;
+                }
+            }
+
+        }
+        if(addList.size() > 0){
+            saleList.addAll(addList);
+        }
+
+
+
+
+        result.put("productInfo",saleList);
+
+        return result;
+//        return saleOrderCount;
+    }
+
+//    查询所有客户订单数量及货品明细
+//    @Override
+//    public List<Map<String, Object>> customerStatistics(Map<String, Object> map) {
+//        Map<String, Object> result = new HashMap<>();
+//        //销售单数量
+//        List<Map<String, Object>> saleOrderCount = saleOrderMapper.selectSaleOrderCountByCustomerNo(map.get("timeType").toString(),map.get("timeParam").toString());
+//        //零售单数量
+//        List<Map<String, Object>> retailOrderCount = saleOrderMapper.selectRetailOrderCountByCustomerNo(map.get("timeType").toString(),map.get("timeParam").toString());
+//
+//        List<Map<String, Object>> addCountList = new ArrayList<>();
+//        for (Map<String, Object> retailItem : retailOrderCount){
+//            String customerNo = retailItem.get("customerNo").toString();
+//            boolean exists = saleOrderCount.stream()
+//                    .anyMatch(saleItem ->
+//                            customerNo.equals(saleItem.get("customerNo").toString()));
+//            if(!exists){
+//                addCountList.add(retailItem);
+//            }
+//
+//        }
+//
+//        for (Map<String, Object> saleItem : saleOrderCount){
+//            String customerNo = saleItem.get("customerNo").toString();
+//            Long orderCount = (Long) saleItem.get("orderCount");
+//            for (Map<String, Object> retailItem : retailOrderCount){
+//                if(customerNo.equals(retailItem.get("customerNo").toString())){
+//                    orderCount = orderCount + (Long) retailItem.get("orderCount");
+//                    saleItem.put("orderCount",orderCount);
+//                    break;
+//                }
+//            }
+//        }
+//        if(addCountList.size()>0){
+//            saleOrderCount.addAll(addCountList);
+//        }
+//
+//
+////        result.put("orderCount",saleOrderCount);
+//
+//        //各个货品重量
+//        //销售单
+//        List<Map<String, Object>> saleList = saleOrderMapper.selectSaleOrderProductCountByCustomerNo(map.get("timeType").toString(), map.get("timeParam").toString());
+//        //零售单
+//        List<Map<String, Object>> retailList = saleOrderMapper.selectRetailOrderProductCountByCustomerNo(map.get("timeType").toString(), map.get("timeParam").toString());
+//
+//
+//        List<Map<String, Object>> addList = new ArrayList<>();
+//
+//        //筛选出销售单中不存在的零售单货品
+//        for (Map<String, Object> retailItem : retailList){
+//            String saleProductId = retailItem.get("productId").toString();
+//            String saleProductColour = retailItem.get("productColour").toString();
+//            String customerNo = retailItem.get("customerNo").toString();
+//            boolean exists = saleList.stream()
+//                    .anyMatch(saleItem ->
+//                            saleProductId.equals(saleItem.get("productId").toString()) &&
+//                                    saleProductColour.equals(saleItem.get("productColour").toString()) &&
+//                                    customerNo.equals(saleItem.get("customerNo").toString())
+//                    );
+//            if(!exists){
+//                addList.add(retailItem);
+//            }
+//
+//        }
+//
+//        for (Map<String, Object> saleItem : saleList){
+//            String saleProductId = saleItem.get("productId").toString();
+//            String saleProductColour = saleItem.get("productColour").toString();
+//            String customerNo = saleItem.get("customerNo").toString();
+//            Double weight = (Double) saleItem.get("weight");
+//
+//            for (Map<String, Object> retailItem : retailList){
+//                if(retailItem.get("productId").toString().equals(saleProductId) && retailItem.get("productColour").toString().equals(saleProductColour) && customerNo.equals(retailItem.get("customerNo").toString())){
+//                    Double weight1 = (Double) retailItem.get("weight");
+//                    weight += weight1;
+//                    saleItem.put("weight",handlingWeight(weight));
+//                    break;
+//                }
+//            }
+//
+//        }
+//        if(addList.size() > 0){
+//            saleList.addAll(addList);
+//        }
+//
+//        for (Map<String, Object> sale : saleOrderCount){
+//            String customerNo = sale.get("customerNo").toString();
+//            List<Map<String, Object>> productList = new ArrayList<>();
+//            for (Map<String, Object> saleItem : saleList){
+//                if(customerNo.equals(saleItem.get("customerNo").toString())){
+//                    productList.add(saleItem);
+//                }
+//            }
+//            if (productList.size() > 0){
+//                sale.put("productInfo",productList);
+//            }
+//
+//        }
+//
+//
+//
+////        result.put("productInfo",saleList);
+//
+//        return saleOrderCount;
+//    }
+
+    @Override
+    public List<Map<String, Object>> mostItemsSold(Map<String, Object> map) {
+        List<Map<String, Object>> mapList = saleOrderMapper.selectMaxProductCountByproductType(map.get("productType").toString(), map.get("timeType").toString(), map.get("timeParam").toString());
+        return mapList;
+    }
+
+    @Override
+    public List<Map<String, Object>> saleOrderCountBySalesman(Map<String, Object> map,Long tenantId) {
+        Map<String, Object> result = new HashMap<>();
+        //销售单量
+        List<Map<String, Object>> saleCount = saleOrderMapper.saleOrderCountBySalesman(map.get("timeType").toString(), map.get("timeParam").toString());
+        //零售单量
+        List<Map<String, Object>> retailCount = saleOrderMapper.retailOrderCountBySalesman(map.get("timeType").toString(), map.get("timeParam").toString());
+        //销售单货品总量
+        List<Map<String, Object>> saleProductCount = saleOrderMapper.saleOrderProductCountBySalesman(map.get("timeType").toString(), map.get("timeParam").toString());
+        //零售单货品总量
+        List<Map<String, Object>> retailProductCount = saleOrderMapper.retailOrderProductCountBySalesman(map.get("timeType").toString(), map.get("timeParam").toString());
+
+        List<Map<String, Object>> addList = new ArrayList<>();
+        for (Map<String, Object> retailItem : retailCount){
+            String saleSalesman = retailItem.get("saleId").toString();
+            boolean exists = saleCount.stream()
+                    .anyMatch(saleItem ->
+                            saleSalesman.equals(saleItem.get("saleId").toString())
+                    );
+            if(!exists){
+                addList.add(retailItem);
+            }
+        }
+
+        for (Map<String, Object> saleItem : saleCount){
+            String saleId = saleItem.get("saleId").toString();
+            Long orderCount = (Long) saleItem.get("orderCount");
+
+            for (Map<String, Object> retailItem : retailCount){
+                if(retailItem.get("saleId").toString().equals(saleId)){
+                    Long orderCount1 = (Long) retailItem.get("orderCount");
+                    orderCount += orderCount1;
+                    saleItem.put("orderCount",orderCount);
+                    break;
+                }
+            }
+
+        }
+        if(addList.size() > 0){
+            saleCount.addAll(addList);
+        }
+        List<Map<String, Object>> addList1 = new ArrayList<>();
+        for (Map<String, Object> retailItem : retailProductCount){
+            String saleSalesman = retailItem.get("saleId").toString();
+            boolean exists = saleProductCount.stream()
+                    .anyMatch(saleItem ->
+                            saleSalesman.equals(saleItem.get("saleId").toString())
+                    );
+            if(!exists){
+                addList1.add(retailItem);
+            }
+        }
+
+        for (Map<String, Object> saleItem : saleProductCount){
+            String saleId = saleItem.get("saleId").toString();
+            Double weight = (Double) saleItem.get("weight");
+            for (Map<String, Object> retailItem : retailProductCount){
+                if(retailItem.get("saleId").toString().equals(saleId)){
+                    Double weight1 = (Double) retailItem.get("weight");
+                    weight += weight1;
+                    saleItem.put("weight",handlingWeight(weight));
+                }
+            }
+        }
+        if (addList1.size() > 0){
+            saleProductCount.addAll(addList1);
+        }
+
+        List<SysUser> salesmanList = iSysUserService.selectUserListByRoleKey("salesman", tenantId);
+        for (Map<String, Object> saleItem : saleCount){
+            String saleId = saleItem.get("saleId").toString();
+            for (Map<String, Object> retailItem : saleProductCount){
+                if(retailItem.get("saleId").toString().equals(saleId)){
+                    saleItem.put("weight",retailItem.get("weight"));
+                    break;
+                }
+            }
+            for (SysUser sysUser : salesmanList){
+                if(sysUser.getUserId().toString().equals(saleId)){
+                    saleItem.put("salesman",sysUser.getNickName());
+                    break;
+                }
+            }
+        }
+//        result.put("saleCount",saleCount);
+//        result.put("saleProductCount",saleProductCount);
+
+        return saleCount;
+    }
+
+    @Override
+    public List<Map<String, Object>> productPercentage() {
+        //销售单各分类货品总量
+        List<Map<String, Object>> saleWeight = saleOrderMapper.saleOrderProductWeightByProductType();
+        //零售单各分类货品总量
+        List<Map<String, Object>> retailWeight = saleOrderMapper.retailOrderProductWeightByProductType();
+
+        List<Map<String, Object>> addList = new ArrayList<>();
+
+        for (Map<String, Object> retailItem : retailWeight){
+            String productType = retailItem.get("productType").toString();
+            boolean exists = saleWeight.stream()
+                    .anyMatch(saleItem ->
+                            productType.equals(saleItem.get("productType").toString())
+                    );
+            if(!exists){
+                addList.add(retailItem);
+            }
+        }
+        for (Map<String, Object> saleItem : saleWeight){
+            String productType = saleItem.get("productType").toString();
+            Double weight = (Double) saleItem.get("weight");
+            for (Map<String, Object> retailItem : retailWeight){
+                if(retailItem.get("productType").toString().equals(productType)){
+                    Double weight1 = (Double) retailItem.get("weight");
+                    weight += weight1;
+                    saleItem.put("weight",handlingWeight(weight));
+                }
+            }
+        }
+        if (addList.size() > 0){
+            saleWeight.addAll(addList);
+        }
+
+        // 计算总重量
+        double totalWeight = saleWeight.stream()
+                .mapToDouble(entry -> (Double) entry.get("weight"))
+                .sum();
+
+        // 计算每个 productType 的重量百分比
+        for (Map<String, Object> entry : saleWeight) {
+            double weight = (Double) entry.get("weight");
+            double percentage = (weight / totalWeight) * 100;
+            double roundedPercentage = Math.round(percentage * 100.0) / 100.0; // 四舍五入到两位小数
+            entry.put("percentage", roundedPercentage);
+        }
+
+
+        return saleWeight;
+    }
+
+    @Override
+    public Map<String, Object> productionMarketingRatio(Map<String, Object> map) {
+        //销售单销量
+        Map<String, Object> saleOrderSaleVolume = saleOrderMapper.saleOrderSaleVolume(map.get("timeType").toString(), map.get("timeParam").toString());
+        //零售单销量
+        Map<String, Object> retailOrderSaleVolume = saleOrderMapper.retailOrderSaleVolume(map.get("timeType").toString(), map.get("timeParam").toString());
+        //产量
+        Map<String, Object> productionVolume = saleOrderMapper.productionVolume(map.get("timeType").toString(), map.get("timeParam").toString());
+
+        Double saleWeight = (Double)saleOrderSaleVolume.get("weight");
+        double sale = saleWeight != null ? saleWeight : 0.0;
+        Double retailWeight = (Double)retailOrderSaleVolume.get("weight");
+        double retail = retailWeight != null ? retailWeight : 0.0;
+
+        Double productionWeight = (Double)productionVolume.get("weight");
+        double production = productionWeight != null ? productionWeight : 0.0;
+        Double totalWeight = sale + retail + production;
+
+        //销售比例
+        Double salesProportion = ((sale + retail) / totalWeight) * 100;
+        Double roundedPercentage = Math.round(salesProportion * 100.0) / 100.0;
+        //生产比例
+        Double productionProportion = (production / totalWeight) * 100;
+        Double roundedPercentage1 = Math.round(productionProportion * 100.0) / 100.0;
+
+        if(roundedPercentage > 0){
+
+        }
+
+        Map<String, Object> result = new HashMap<>();
+        result.put("salesProportion",roundedPercentage);
+        result.put("productionProportion",roundedPercentage1);
+        return result;
+    }
+
+    @Override
+    public List<Map<String, Object>> saleOrderRanking(Map<String, Object> map) {
+        return saleOrderMapper.saleOrderRanking(map.get("timeType").toString(), map.get("timeParam").toString());
+    }
+
+    @Override
+    public List<Map<String, Object>> fastSellingProduct(Map<String, Object> map) {
+        //零售单
+        List<Map<String, Object>> retailList = saleOrderMapper.retailFastSellingProduct(map.get("timeType").toString(), map.get("timeParam").toString());
+        //销售单
+        List<Map<String, Object>> saleList = saleOrderMapper.saleFastSellingProduct(map.get("timeType").toString(), map.get("timeParam").toString());
+
+        List<Map<String, Object>> addList = new ArrayList<>();
+        for (Map<String, Object> retailItem : retailList){
+            String productId = retailItem.get("productId").toString();
+            String productColour = retailItem.get("productColour").toString();
+            boolean exists = saleList.stream()
+                    .anyMatch(saleItem ->
+                            productId.equals(saleItem.get("productId").toString()) &&
+                                    productColour.equals(saleItem.get("productColour").toString())
+                    );
+            if(!exists){
+                addList.add(retailItem);
+            }
+        }
+
+        for (Map<String, Object> saleItem : saleList){
+            String productId = saleItem.get("productId").toString();
+            String productColour = saleItem.get("productColour").toString();
+            Double weight = (Double) saleItem.get("weight");
+            for (Map<String, Object> retailItem : retailList){
+                if(retailItem.get("productId").toString().equals(productId) && retailItem.get("productColour").toString().equals(productColour)){
+                    Double weight1 = (Double) retailItem.get("weight");
+                    weight += weight1;
+                    saleItem.put("weight",handlingWeight(weight));
+                }
+            }
+        }
+        if (addList.size() > 0){
+            saleList.addAll(addList);
+        }
+
+        saleList.sort(Comparator.comparing((Map<String, Object> o) -> (Double) o.get("weight"))
+                .reversed());
+        return saleList;
+    }
+
+
+    //保留两位小数
+    public Double handlingWeight(Double weight) {
+        DecimalFormat df = new DecimalFormat("0.00");
+        return Double.parseDouble(df.format(weight));
+    }
+
 }

+ 13 - 0
zkqy-custom-business/src/main/resources/mapper/business/ProductInventoryMapper.xml

@@ -359,4 +359,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
          group by product_id,lot_num,product_colour
     </select>
 
+    <select id="statisticsSuttleByLevels" resultType="map">
+        SELECT
+        pi.levels as name,
+        TRUNCATE(sum(pi.total_suttle),2) as suttle
+        FROM
+        {DBNAME}.product_inventory pi
+        LEFT JOIN {DBNAME}.production p ON pi.product_id = p.id
+        where pi.del_flag = '0'
+        <if test="productType != null">and p.product_type = #{productType}</if>
+        group by pi.levels
+
+    </select>
+
 </mapper>

+ 49 - 0
zkqy-custom-business/src/main/resources/mapper/business/ProductWarehousingRecordMapper.xml

@@ -276,4 +276,53 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         where qr_code_id = #{qrCodeId}
     </delete>
 
+    <select id="productionStatistics" resultType="map">
+        SELECT
+            a.*
+        FROM
+            (
+                SELECT
+                    p.id,
+                    p.product_name as name,
+                    p.product_specifications as spec,
+--                     pr.levels,
+                    TRUNCATE(sum( pr.suttle ),2) as suttle,
+                    <if test="timeType == 'days'">
+                        DATE( pr.warehousing_time ) AS days,
+                    </if>
+                    <if test="timeType == 'months'">
+                        DATE_FORMAT( pr.warehousing_time, '%Y-%m' ) AS months,
+                    </if>
+                    <if test="timeType == 'quarters'">
+                        CONCAT(YEAR ( pr.warehousing_time ),'-',QUARTER ( pr.warehousing_time )) AS quarters,
+                    </if>
+                    <if test="timeType == 'years'">
+                        YEAR ( pr.warehousing_time ) AS years,
+                    </if>
+                    pr.product_colour as productColour
+                FROM
+                {DBNAME}.product_warehousing_record pr
+		LEFT JOIN {DBNAME}.production p ON pr.product_id = p.id
+        WHERE
+            pr.del_flag = '0'
+        GROUP BY
+            pr.product_id,
+--             pr.levels,
+            pr.product_colour
+            ) AS a
+        WHERE
+            <if test="timeType == 'days'">
+                days = #{timeParam}
+            </if>
+            <if test="timeType == 'months'">
+                months = #{timeParam}
+            </if>
+            <if test="timeType == 'quarters'">
+                quarters = #{timeParam}
+            </if>
+            <if test="timeType == 'years'">
+                years = #{timeParam}
+            </if>
+    </select>
+
 </mapper>

+ 622 - 0
zkqy-custom-business/src/main/resources/mapper/business/SaleOrderMapper.xml

@@ -229,6 +229,7 @@
             <if test="earnestMoney != null">earnest_money = #{earnestMoney},</if>
             <if test="deliveryDate != null">delivery_date = #{deliveryDate},</if>
             <if test="lotNumber != null">lot_number = #{lotNumber},</if>
+            <if test="completionTime != null">completion_time = #{completionTime},</if>
         </trim>
         where id = #{id}
     </update>
@@ -344,4 +345,625 @@
         order by so.id desc
     </select>
 
+<!--    <select id="aa">-->
+<!--        SELECT-->
+<!--            so.sale_custom_no,-->
+<!--            COUNT(*) AS order_count,-->
+<!--            s1.weight-->
+<!--        FROM-->
+<!--            sale_order so-->
+<!--                LEFT JOIN (-->
+<!--                SELECT TRUNCATE-->
+<!--                           ( sum( sp.product_number ), 2 ) AS weight,-->
+<!--                       so.sale_custom_no-->
+<!--                FROM-->
+<!--                    sale_products sp-->
+<!--                        LEFT JOIN sale_order so ON sp.sale_order_no = so.sale_no-->
+<!--                        AND so.del_flag = '0'-->
+<!--                        AND sale_no IN (-->
+<!--                            SELECT-->
+<!--                                sale_no-->
+<!--                            FROM-->
+<!--                                sale_order-->
+<!--                            WHERE-->
+<!--                                sale_order_technology_no != 'retailOrder'-->
+<!--                    AND sale_custom_no IN ( 16, 15, 14 ))-->
+<!--        WHERE-->
+<!--            sp.del_flag = '0'-->
+<!--        GROUP BY-->
+<!--            so.sale_custom_no-->
+<!--            ) s1 ON so.sale_custom_no = s1.sale_custom_no-->
+<!--        WHERE-->
+<!--            so.del_flag = '0'-->
+<!--        GROUP BY-->
+<!--            so.sale_custom_no-->
+<!--        ORDER BY-->
+<!--            order_count DESC-->
+<!--            LIMIT 10;-->
+<!--    </select>-->
+
+    <select id="saleOrderTop10List" parameterType="string" resultType="map">
+        SELECT
+            so.sale_custom_no as customerNo,
+            c.custom_name as customerName,
+            COUNT(*) AS orderCount,
+            s1.weight
+        FROM
+            {DBNAME}.sale_order so
+                LEFT JOIN
+            (
+                SELECT TRUNCATE( sum( sp.product_number ), 2 ) AS weight,so.sale_custom_no FROM {DBNAME}.sale_products sp LEFT JOIN {DBNAME}.sale_order so ON sp.sale_order_no = so.sale_no AND so.del_flag ='0'
+                    AND sale_no IN (SELECT sale_no FROM {DBNAME}.sale_order WHERE sale_order_technology_no != 'retailOrder' and del_flag = '0' AND sale_custom_no IN
+                    <foreach collection="list" item="customerNo" open="(" separator="," close=")">
+                        #{customerNo}
+                    </foreach>
+                    ) WHERE
+            sp.del_flag = '0' GROUP BY so.sale_custom_no
+            ) s1 ON so.sale_custom_no = s1.sale_custom_no
+            left join {DBNAME}.customer c on so.sale_custom_no = c.custom_no and c.del_flag = '0'
+        WHERE
+            so.del_flag = '0' and so.sale_order_technology_no != 'retailOrder'
+        GROUP BY
+            so.sale_custom_no
+        ORDER BY
+        orderCount DESC
+            LIMIT 10
+    </select>
+
+    <select id="saleRetailOrderTop10List" parameterType="string" resultType="map">
+        SELECT
+            so.sale_custom_no as customerNo,
+            c.custom_name as customerName,
+            COUNT(*) AS orderCount,
+            sum(por.suttle) as weight
+        FROM
+        {DBNAME}.sale_order so
+                LEFT JOIN {DBNAME}.product_invoice pi ON so.sale_no = pi.sale_order_no AND pi.del_flag = '0'
+                left join {DBNAME}.product_outbound_record por on por.notice_number = pi.notice_number AND por.del_flag = '0'
+                left join {DBNAME}.customer c on so.sale_custom_no = c.custom_no and c.del_flag = '0'
+        WHERE
+            so.sale_order_technology_no = 'retailOrder'
+          AND so.del_flag = '0'
+          and so.`status` = '6'
+          AND so.sale_custom_no IN
+            <foreach collection="list" item="customerNo" open="(" separator="," close=")">
+                #{customerNo}
+            </foreach>
+        group by so.sale_custom_no
+    </select>
+<!--    <select id="saleRetailOrderTop10List" parameterType="string" resultType="map">-->
+<!--        SELECT-->
+<!--            so.sale_custom_no as customerNo,-->
+<!--            c.custom_name as customerName,-->
+<!--            COUNT(*) AS orderCount,-->
+<!--            por.weight-->
+<!--        FROM-->
+<!--            {DBNAME}.sale_order so left join {DBNAME}.product_invoice pi on so.sale_no = pi.sale_order_no-->
+<!--                          left join-->
+<!--            (-->
+<!--                select sum(por.suttle) as weight,por.notice_number from {DBNAME}.product_outbound_record por-->
+<!--                 left join {DBNAME}.product_invoice pi on por.notice_number = pi.notice_number and pi.del_flag = '0'-->
+<!--                where por.del_flag = '0' group by pi.customer_id-->
+<!--            ) as por on por.notice_number = pi.notice_number-->
+<!--                          left join {DBNAME}.customer c on so.sale_custom_no = c.custom_no and c.del_flag = '0'-->
+<!--        WHERE-->
+<!--            pi.del_flag = '0'-->
+<!--          and so.sale_order_technology_no = 'retailOrder'-->
+<!--          AND so.del_flag = '0'-->
+<!--          and so.`status` = '6'-->
+<!--          AND so.sale_custom_no IN-->
+<!--        <foreach collection="list" item="customerNo" open="(" separator="," close=")">-->
+<!--            #{customerNo}-->
+<!--        </foreach>-->
+<!--        group by so.sale_custom_no-->
+<!--    </select>-->
+
+    <select id="saleOrderTop10CustomerNoList" resultType="string">
+        SELECT
+            sale_custom_no as customerNo
+        FROM
+            {DBNAME}.sale_order
+        WHERE
+            del_flag = '0'
+        GROUP BY
+            sale_custom_no
+        ORDER BY
+            COUNT(*) DESC
+            LIMIT 10
+    </select>
+
+    <select id="selectSaleOrderCountByCustomerNo" resultType="map">
+        SELECT
+            COUNT(*) AS orderCount,
+        so.sale_custom_no as customerNo,
+               c.custom_name as customerName
+        FROM
+        {DBNAME}.sale_order so left join {DBNAME}.customer c on so.sale_custom_no = c.custom_no and c.del_flag = '0'
+        WHERE
+        so.del_flag = '0'
+          AND so.sale_order_technology_no != 'retailOrder' and so.sale_custom_no = #{customerNo}
+        <if test="timeType == 'days'">
+            and DATE( so.sale_date ) = #{timeParam}
+        </if>
+        <if test="timeType == 'months'">
+            and DATE_FORMAT( so.sale_date, '%Y-%m' ) = #{timeParam}
+        </if>
+        <if test="timeType == 'quarters'">
+            and CONCAT(YEAR ( so.sale_date ),'-',QUARTER ( so.sale_date )) = #{timeParam}
+        </if>
+        <if test="timeType == 'years'">
+            and YEAR ( so.sale_date ) = #{timeParam}
+        </if>
+--         group by so.sale_custom_no
+    </select>
+
+    <select id="selectRetailOrderCountByCustomerNo" resultType="map">
+        SELECT
+        COUNT(*) AS orderCount,
+        so.sale_custom_no AS customerNo,
+        c.custom_name as customerName
+        FROM
+        {DBNAME}.sale_order so left join {DBNAME}.customer c on so.sale_custom_no = c.custom_no and c.del_flag = '0'
+        WHERE
+        so.del_flag = '0'
+        AND so.sale_order_technology_no != 'retailOrder'
+        and so.`status` = '6'
+        and so.sale_custom_no = #{customerNo}
+        <if test="timeType == 'days'">
+            and DATE( so.sale_date ) = #{timeParam}
+        </if>
+        <if test="timeType == 'months'">
+            and DATE_FORMAT( so.sale_date, '%Y-%m' ) = #{timeParam}
+        </if>
+        <if test="timeType == 'quarters'">
+            and CONCAT(YEAR ( so.sale_date ),'-',QUARTER ( so.sale_date )) = #{timeParam}
+        </if>
+        <if test="timeType == 'years'">
+            and YEAR ( so.sale_date ) = #{timeParam}
+        </if>
+--         group by so.sale_custom_no
+    </select>
+
+    <select id="selectSaleOrderProductCountByCustomerNo" resultType="map">
+        SELECT
+        p.id as productId,
+        p.product_name as productName,
+        TRUNCATE(sum(sp.product_number),2) as weight,
+        CONCAT(m.materie_encoding,m.materie_color_number) as productColour,
+        so.sale_custom_no as customerNo
+        FROM
+        {DBNAME}.sale_order so
+        LEFT JOIN {DBNAME}.sale_products sp ON so.sale_no = sp.sale_order_no AND sp.del_flag = '0'
+        left join {DBNAME}.production p on sp.product_no = p.product_no and p.del_flag = '0'
+        left join {DBNAME}.materiel m on m.materiel_code = sp.colour_number and m.del_flag = '0'
+
+        where  so.sale_order_technology_no != 'retailOrder' and so.del_flag = '0' and so.sale_custom_no = #{customerNo}
+        <if test="timeType == 'days'">
+            and DATE( so.sale_date ) = #{timeParam}
+        </if>
+        <if test="timeType == 'months'">
+            and DATE_FORMAT( so.sale_date, '%Y-%m' ) = #{timeParam}
+        </if>
+        <if test="timeType == 'quarters'">
+            and CONCAT(YEAR ( so.sale_date ),'-',QUARTER ( so.sale_date )) = #{timeParam}
+        </if>
+        <if test="timeType == 'years'">
+            and YEAR ( so.sale_date ) = #{timeParam}
+        </if>
+        group by sp.product_no,sp.colour_number
+--                  ,so.sale_custom_no
+    </select>
+
+    <select id="selectRetailOrderProductCountByCustomerNo" resultType="map">
+        SELECT
+            por.product_id as productId,
+            p.product_name as productName,
+            TRUNCATE(sum(por.suttle),2) as weight,
+            por.product_colour as productColour,
+            so.sale_custom_no as customerNo
+        FROM
+            {DBNAME}.sale_order so
+                LEFT JOIN {DBNAME}.product_invoice pi ON so.sale_no = pi.sale_order_no and pi.del_flag = '0'
+                left join {DBNAME}.product_outbound_record por on por.notice_number = pi.notice_number and por.del_flag = '0'
+                left join {DBNAME}.production p on p.id = por.product_id
+        where  so.sale_order_technology_no = 'retailOrder' and so.del_flag = '0' and so.`status` = '6' and so.sale_custom_no = #{customerNo}
+        <if test="timeType == 'days'">
+            and DATE( so.sale_date ) = #{timeParam}
+        </if>
+        <if test="timeType == 'months'">
+            and DATE_FORMAT( so.sale_date, '%Y-%m' ) = #{timeParam}
+        </if>
+        <if test="timeType == 'quarters'">
+            and CONCAT(YEAR ( so.sale_date ),'-',QUARTER ( so.sale_date )) = #{timeParam}
+        </if>
+        <if test="timeType == 'years'">
+            and YEAR ( so.sale_date ) = #{timeParam}
+        </if>
+        group by por.product_id,por.product_colour
+--                  ,so.sale_custom_no
+    </select>
+
+    <select id="selectMaxProductCountByproductType" resultType="map">
+        SELECT
+            productIno.*,
+        TRUNCATE(sum(weight1),2) as weight
+        FROM
+            (
+                SELECT
+                    so.sale_no as saleNo,
+                    por.product_id as productId,
+                    p.product_name as productName,
+                    TRUNCATE(sum(por.suttle),2) as weight1,
+                    por.product_colour as productColour,
+                    DATE( so.sale_date ) AS days,
+            DATE_FORMAT( so.sale_date, '%Y-%m' ) AS months,
+            CONCAT(YEAR ( so.sale_date ),'-',QUARTER ( so.sale_date )) AS quarters,
+            YEAR ( so.sale_date ) AS years
+            FROM
+        {DBNAME}.sale_order so
+			LEFT JOIN {DBNAME}.product_invoice pi ON so.sale_no = pi.sale_order_no AND pi.del_flag = '0'
+            left join {DBNAME}.product_outbound_record por on por.notice_number = pi.notice_number and por.del_flag = '0'
+            left join {DBNAME}.production p on p.id = por.product_id
+        where  so.sale_order_technology_no = 'retailOrder' and so.del_flag = '0' and so.`status` = '6' and p.product_type = #{productType}
+        group by por.product_id,por.product_colour,por.notice_number
+
+        UNION ALL
+
+        SELECT
+            sp.sale_order_no as saleNo,
+            p.id  as productId,
+            p.product_name as productName,
+            sp.product_number as weight1,
+            CONCAT(m.materie_encoding,m.materie_color_number) as productColour,
+            DATE( so.sale_date ) AS days,
+            DATE_FORMAT( so.sale_date, '%Y-%m' ) AS months,
+            CONCAT(YEAR ( so.sale_date ),'-',QUARTER ( so.sale_date )) AS quarters,
+            YEAR ( so.sale_date ) AS years
+        FROM
+        {DBNAME}.sale_order so left join {DBNAME}.sale_products sp on so.sale_no = sp.sale_order_no and sp.del_flag = '0'
+            left join {DBNAME}.production p on sp.product_no = p.product_no and p.del_flag = '0'
+            left join {DBNAME}.materiel m on m.materiel_code = sp.colour_number and m.del_flag = '0'
+        WHERE
+            so.sale_order_technology_no != 'retailOrder'
+          AND so.del_flag = '0'
+          AND so.`status` = '6' and p.product_type = #{productType}
+            ) as productIno
+            <where>
+                <if test="timeType == 'days'">
+                    days = #{timeParam}
+                </if>
+                <if test="timeType == 'months'">
+                    months = #{timeParam}
+                </if>
+                <if test="timeType == 'quarters'">
+                    quarters = #{timeParam}
+                </if>
+                <if test="timeType == 'years'">
+                    years = #{timeParam}
+                </if>
+            </where>
+        group by productId,productColour
+        ORDER BY weight DESC
+            LIMIT 10;
+    </select>
+
+    <select id="saleOrderProductCountBySalesman" resultType="map">
+        SELECT
+            TRUNCATE( sum( sp.product_number ), 2 ) AS weight,
+            so.create_by_id as saleId
+        FROM {DBNAME}.sale_products sp LEFT JOIN {DBNAME}.sale_order so ON sp.sale_order_no = so.sale_no AND so.del_flag ='0'
+        WHERE sp.del_flag = '0'  AND so.sale_no
+            IN (SELECT sale_no FROM {DBNAME}.sale_order WHERE sale_order_technology_no != 'retailOrder' and del_flag = '0' )
+
+            <if test="timeType == 'days'">
+                and DATE( so.sale_date ) = #{timeParam}
+            </if>
+            <if test="timeType == 'months'">
+                and DATE_FORMAT( so.sale_date, '%Y-%m' ) = #{timeParam}
+            </if>
+            <if test="timeType == 'quarters'">
+                and CONCAT(YEAR ( so.sale_date ),'-',QUARTER ( so.sale_date )) = #{timeParam}
+            </if>
+            <if test="timeType == 'years'">
+                and YEAR ( so.sale_date ) = #{timeParam}
+            </if>
+
+        group by so.create_by_id
+    </select>
+
+    <select id="retailOrderProductCountBySalesman" resultType="map">
+        SELECT
+            TRUNCATE(sum( por.suttle ),2) AS weight,
+            so.create_by_id as saleId
+        FROM
+            {DBNAME}.product_outbound_record por
+                LEFT JOIN {DBNAME}.product_invoice pi ON por.notice_number = pi.notice_number AND pi.del_flag = '0'
+                left join {DBNAME}.sale_order so on pi.sale_order_no = so.sale_no and so.del_flag = '0' and so.`status` = '6' and so.sale_order_technology_no = 'retailOrder'
+        WHERE
+            por.del_flag = '0'
+        <if test="timeType == 'days'">
+            and DATE( so.sale_date ) = #{timeParam}
+        </if>
+        <if test="timeType == 'months'">
+            and  DATE_FORMAT( so.sale_date, '%Y-%m' ) = #{timeParam}
+        </if>
+        <if test="timeType == 'quarters'">
+            and CONCAT(YEAR ( so.sale_date ),'-',QUARTER ( so.sale_date )) = #{timeParam}
+        </if>
+        <if test="timeType == 'years'">
+            and YEAR ( so.sale_date ) = #{timeParam}
+        </if>
+        GROUP BY
+            so.create_by_id
+    </select>
+
+    <select id="saleOrderCountBySalesman" resultType="map">
+        SELECT
+            count( 1 ) as orderCount,
+            create_by_id as saleId
+        FROM
+            {DBNAME}.sale_order
+        WHERE
+            del_flag = '0'
+          AND sale_order_technology_no != 'retailOrder'
+        <if test="timeType == 'days'">
+            and DATE( sale_date ) = #{timeParam}
+        </if>
+        <if test="timeType == 'months'">
+            and  DATE_FORMAT( sale_date, '%Y-%m' ) = #{timeParam}
+        </if>
+        <if test="timeType == 'quarters'">
+            and CONCAT(YEAR ( sale_date ),'-',QUARTER ( sale_date )) = #{timeParam}
+        </if>
+        <if test="timeType == 'years'">
+            and YEAR ( sale_date ) = #{timeParam}
+        </if>
+        GROUP BY
+            create_by_id
+    </select>
+
+    <select id="retailOrderCountBySalesman" resultType="map">
+        SELECT
+            count( 1 ) as orderCount,
+            create_by_id as saleId
+        FROM
+            {DBNAME}.sale_order
+        WHERE
+            del_flag = '0'
+          AND `status` = '6'
+          AND sale_order_technology_no = 'retailOrder'
+        <if test="timeType == 'days'">
+            and DATE( sale_date ) = #{timeParam}
+        </if>
+        <if test="timeType == 'months'">
+            and  DATE_FORMAT( sale_date, '%Y-%m' ) = #{timeParam}
+        </if>
+        <if test="timeType == 'quarters'">
+            and CONCAT(YEAR ( sale_date ),'-',QUARTER ( sale_date )) = #{timeParam}
+        </if>
+        <if test="timeType == 'years'">
+            and YEAR ( sale_date ) = #{timeParam}
+        </if>
+        GROUP BY
+            create_by_id
+    </select>
+
+    <select id="saleOrderProductWeightByProductType" resultType="map">
+        SELECT
+            TRUNCATE(sum(sp.product_number),2) as weight,
+            p.product_type as productType
+        FROM
+            {DBNAME}.sale_order so left join {DBNAME}.sale_products sp on so.sale_no = sp.sale_order_no and sp.del_flag = '0'
+                          left join {DBNAME}.production p on p.product_no = sp.product_no and p.del_flag = '0'
+        WHERE
+            so.sale_order_technology_no != 'retailOrder'
+	AND so.del_flag = '0'
+	AND so.`status` = '6'
+        group by p.product_type
+    </select>
+
+    <select id="retailOrderProductWeightByProductType" resultType="map">
+        SELECT
+            TRUNCATE(sum( por.suttle ),2) AS weight,
+            p.product_type as productType
+        FROM
+            {DBNAME}.product_outbound_record por
+                LEFT JOIN {DBNAME}.product_invoice pi ON por.notice_number = pi.notice_number AND pi.del_flag = '0'
+                left join {DBNAME}.sale_order so on pi.sale_order_no = so.sale_no and so.del_flag = '0' and so.`status` = '6' and so.sale_order_technology_no = 'retailOrder'
+                left join {DBNAME}.production p on p.id = por.product_id
+        where por.del_flag = '0'
+        group by p.product_type
+    </select>
+
+    <select id="saleOrderSaleVolume" resultType="map">
+        SELECT
+        IFNULL(TRUNCATE( sum( sp.product_number ), 2 ),0) AS weight
+        FROM
+            {DBNAME}.sale_order so left join {DBNAME}.sale_products sp on so.sale_no = sp.sale_order_no and sp.del_flag = '0'
+                          left join {DBNAME}.production p on p.product_no = sp.product_no and p.del_flag = '0'
+        WHERE
+            so.sale_order_technology_no != 'retailOrder'
+	AND so.del_flag = '0'
+	AND so.`status` = '6'
+
+        <if test="timeType == 'days'">
+            and DATE( so.sale_date ) = #{timeParam}
+        </if>
+        <if test="timeType == 'months'">
+            and  DATE_FORMAT( so.sale_date, '%Y-%m' ) = #{timeParam}
+        </if>
+        <if test="timeType == 'quarters'">
+            and CONCAT(YEAR ( so.sale_date ),'-',QUARTER ( so.sale_date )) = #{timeParam}
+        </if>
+        <if test="timeType == 'years'">
+            and YEAR ( so.sale_date ) = #{timeParam}
+        </if>
+    </select>
+
+    <select id="retailOrderSaleVolume" resultType="map">
+        SELECT
+        IFNULL(TRUNCATE( sum( por.suttle ), 2 ),0) AS weight
+        FROM
+            {DBNAME}.product_outbound_record por
+                LEFT JOIN {DBNAME}.product_invoice pi ON por.notice_number = pi.notice_number AND pi.del_flag = '0'
+                left join {DBNAME}.sale_order so on pi.sale_order_no = so.sale_no and so.del_flag = '0' and so.`status` = '6' and so.sale_order_technology_no = 'retailOrder'
+                left join {DBNAME}.production p on p.id = por.product_id
+        where por.del_flag = '0'
+        <if test="timeType == 'days'">
+            and DATE( so.sale_date ) = #{timeParam}
+        </if>
+        <if test="timeType == 'months'">
+            and  DATE_FORMAT( so.sale_date, '%Y-%m' ) = #{timeParam}
+        </if>
+        <if test="timeType == 'quarters'">
+            and CONCAT(YEAR ( so.sale_date ),'-',QUARTER ( so.sale_date )) = #{timeParam}
+        </if>
+        <if test="timeType == 'years'">
+            and YEAR ( so.sale_date ) = #{timeParam}
+        </if>
+    </select>
+
+    <select id="productionVolume" resultType="map">
+        SELECT
+        IFNULL(TRUNCATE( sum( suttle ), 2 ),0) AS weight
+        FROM
+            {DBNAME}.product_warehousing_record
+        WHERE
+            del_flag = '0'
+        <if test="timeType == 'days'">
+           and DATE( warehousing_time ) = #{timeParam}
+        </if>
+        <if test="timeType == 'months'">
+           and DATE_FORMAT( warehousing_time, '%Y-%m' ) = #{timeParam}
+        </if>
+        <if test="timeType == 'quarters'">
+           and CONCAT(YEAR ( warehousing_time ),'-',QUARTER ( warehousing_time )) = #{timeParam}
+        </if>
+        <if test="timeType == 'years'">
+           and YEAR ( warehousing_time ) = #{timeParam}
+        </if>
+    </select>
+
+    <select id="saleOrderRanking" resultType="map">
+        select a.* from
+                       (
+                           SELECT
+                               so.sale_no as saleNo,
+                               por.product_id as productId,
+                               p.product_name as productName,
+                               TRUNCATE(sum(por.suttle),2) as weight,
+                               por.product_colour as productColour,
+                               DATE( so.sale_date ) AS days,
+                       DATE_FORMAT( so.sale_date, '%Y-%m' ) AS months,
+                       CONCAT(YEAR ( so.sale_date ),'-',QUARTER ( so.sale_date )) AS quarters,
+                       YEAR ( so.sale_date ) AS years
+            FROM
+        {DBNAME}.sale_order so
+			LEFT JOIN {DBNAME}.product_invoice pi ON so.sale_no = pi.sale_order_no AND pi.del_flag = '0'
+            left join {DBNAME}.product_outbound_record por on por.notice_number = pi.notice_number and por.del_flag = '0'
+            left join {DBNAME}.production p on p.id = por.product_id
+        where  so.sale_order_technology_no = 'retailOrder' and so.del_flag = '0' and so.`status` = '6'
+
+
+        group by so.sale_no
+
+        UNION ALL
+
+        SELECT
+            sp.sale_order_no as saleNo,
+            p.id  as productId,
+            p.product_name as productName,
+            sum(sp.product_number) as weight,
+            CONCAT(m.materie_encoding,m.materie_color_number) as productColour,
+            DATE( so.sale_date ) AS days,
+            DATE_FORMAT( so.sale_date, '%Y-%m' ) AS months,
+            CONCAT(YEAR ( so.sale_date ),'-',QUARTER ( so.sale_date )) AS quarters,
+            YEAR ( so.sale_date ) AS years
+        FROM
+            {DBNAME}.sale_order so left join {DBNAME}.sale_products sp on so.sale_no = sp.sale_order_no and sp.del_flag = '0'
+            left join {DBNAME}.production p on sp.product_no = p.product_no and p.del_flag = '0'
+            left join {DBNAME}.materiel m on m.materiel_code = sp.colour_number and m.del_flag = '0'
+        WHERE
+            so.sale_order_technology_no != 'retailOrder'
+          AND so.del_flag = '0'
+        group by so.sale_no
+
+            ) as a
+        <where>
+            <if test="timeType == 'days'">
+                days = #{timeParam}
+            </if>
+            <if test="timeType == 'months'">
+                months = #{timeParam}
+            </if>
+            <if test="timeType == 'quarters'">
+                quarters = #{timeParam}
+            </if>
+            <if test="timeType == 'years'">
+                years = #{timeParam}
+            </if>
+        </where>
+
+        ORDER BY weight DESC
+            LIMIT 10
+    </select>
+
+    <select id="retailFastSellingProduct" resultType="map">
+        SELECT
+            por.product_id as productId,
+            p.product_name as productName,
+            TRUNCATE(sum(por.suttle),2) as weight,
+            por.product_colour as productColour,
+            p.product_specifications as spec
+        FROM
+        {DBNAME}.sale_order so
+            LEFT JOIN {DBNAME}.product_invoice pi ON so.sale_no = pi.sale_order_no AND pi.del_flag = '0'
+            left join {DBNAME}.product_outbound_record por on por.notice_number = pi.notice_number and por.del_flag = '0'
+            left join {DBNAME}.production p on p.id = por.product_id
+        where  so.sale_order_technology_no = 'retailOrder' and so.del_flag = '0' and so.`status` = '6'
+        <if test="timeType == 'days'">
+            and DATE( so.sale_date ) = #{timeParam}
+        </if>
+        <if test="timeType == 'months'">
+            and  DATE_FORMAT( so.sale_date, '%Y-%m' ) = #{timeParam}
+        </if>
+        <if test="timeType == 'quarters'">
+            and CONCAT(YEAR ( so.sale_date ),'-',QUARTER ( so.sale_date )) = #{timeParam}
+        </if>
+        <if test="timeType == 'years'">
+            and YEAR ( so.sale_date ) = #{timeParam}
+        </if>
+        group by por.product_id,por.product_colour
+    </select>
+
+    <select id="saleFastSellingProduct" resultType="map">
+        SELECT
+            p.id as productId,
+            p.product_name as productName,
+            TRUNCATE(sum(sp.product_number),2) as weight,
+            CONCAT(m.materie_encoding,m.materie_color_number) as productColour,
+            p.product_specifications as spec
+        FROM
+            {DBNAME}.sale_order so
+                LEFT JOIN {DBNAME}.sale_products sp ON sp.sale_order_no = so.sale_no AND sp.del_flag = '0'
+                left join {DBNAME}.production p on sp.product_no = p.product_no and p.del_flag = '0'
+                left join {DBNAME}.materiel m on sp.colour_number = m.materiel_code and m.del_flag = '0'
+        WHERE
+            so.del_flag = '0'
+          AND so.sale_order_technology_no != 'retailOrder'
+        <if test="timeType == 'days'">
+            and DATE( so.sale_date ) = #{timeParam}
+        </if>
+        <if test="timeType == 'months'">
+            and  DATE_FORMAT( so.sale_date, '%Y-%m' ) = #{timeParam}
+        </if>
+        <if test="timeType == 'quarters'">
+            and CONCAT(YEAR ( so.sale_date ),'-',QUARTER ( so.sale_date )) = #{timeParam}
+        </if>
+        <if test="timeType == 'years'">
+            and YEAR ( so.sale_date ) = #{timeParam}
+        </if>
+        group by sp.product_no,sp.colour_number
+    </select>
+
 </mapper>

+ 107 - 0
zkqy-ui/src/api/statisticalAnalysis/index.js

@@ -0,0 +1,107 @@
+import request from '@/utils/request'
+
+// 产量统计-年月日季度
+export function productionStatistics(data) {
+  return request({
+    url: '/system/ProductWarehousingRecord/productionStatistics',
+    method: 'get',
+    params: data,
+  })
+}
+
+//查询产品类型
+export function getProductType(data) {
+  return request({
+    url: '/system/productCode/list',
+    method: 'get',
+    params: data,
+  })
+}
+
+//根据类型获取各个等级库存数量
+export function statisticsSuttleByLevels(data) {
+  return request({
+    url: '/system/ProductInventory/statisticsSuttleByLevels',
+    method: 'get',
+    params: data,
+  })
+}
+
+//根据类型获取各个等级库存数量
+export function productionMarketingRatio(data) {
+  return request({
+    url: '/system/order/productionMarketingRatio',
+    method: 'post',
+    data: data,
+  })
+}
+
+//销售排行   按时间可以进行查询、默认当月、可选择日、月、季度、年度进行筛选
+export function saleOrderRanking(data) {
+  return request({
+    url: '/system/order/saleOrderRanking',
+    method: 'post',
+    data: data,
+  })
+}
+
+//销售品类占比  各个已销售的产品中各类产品的占用百分比√
+export function productPercentage() {
+  return request({
+    url: '/system/order/productPercentage',
+    method: 'get',
+  })
+}
+
+//客户订单排行表,排行前10名和单据总量和货品总数量
+export function customerOrderRanking() {
+  return request({
+    url: '/system/order/saleOrderTop10List',
+    method: 'get',
+  })
+}
+
+//按客户统计  统计客户单量和每个货品的数量
+export function customerOrderStatistics(data) {
+  return request({
+    url: '/system/order/customerOrderStatistics',
+    method: 'post',
+    data: data,
+  })
+}
+
+//当月快销产品统计、可选择日、月、季度、年度进行筛选
+export function fastSellingProduct(data) {
+  return request({
+    url: '/system/order/fastSellingProduct',
+    method: 'post',
+    data: data,
+  })
+}
+
+//当月快销产品统计、可选择日、月、季度、年度进行筛选
+export function saleOrderCountBySalesman(data) {
+  return request({
+    url: '/system/order/saleOrderCountBySalesman',
+    method: 'post',
+    data: data,
+  })
+}
+
+//按品种统计   已销售产品的单据中销售量大的产品做排行、月、季度、年度进行筛选
+export function mostItemsSold(data) {
+  return request({
+    url: '/system/order/mostItemsSold',
+    method: 'post',
+    data: data,
+  })
+}
+
+//查询客户
+export function getCustomerList(data) {
+  return request({
+    url: '/system/customer/list',
+    method: 'get',
+    params: data,
+  })
+}

+ 1 - 1
zkqy-ui/src/views/orderMange/customerMange/index.vue

@@ -603,7 +603,7 @@ export default {
     handleAdd() {
       this.reset();
       this.open = true;
-      this.title = "添加客户11111";
+      this.title = "添加客户";
       this.form.customNo=this.generateClientId();
     },
     /** 修改按钮操作 */

+ 1 - 0
zkqy-ui/src/views/orderMange/index.vue

@@ -3480,6 +3480,7 @@ export default {
             id: row.id,
             status: 6,
             saleNo: row.saleNo,
+            completionTime: new Date(),
           };
           let res = await updateOrder(payload);
           if (res.code == 200) {

+ 2 - 1
zkqy-ui/src/views/orderMange/retailMange/index.vue

@@ -446,7 +446,7 @@
                     :name="'productName-' + scope.$index"
                     style="margin: 0px; padding: 0px"
                   >
-                    <!-- 
+                    <!--
                     @change="
                         handleProductChange(scope.row.productNo, scope.row)
                       "
@@ -1115,6 +1115,7 @@ export default {
         id: row.id,
         status: 6,
         saleNo: row.saleNo,
+        completionTime: new Date(),
       };
       let res = await updateOrder(payload);
       if (res.code == 200) {

+ 239 - 0
zkqy-ui/src/views/orderMange/statisticalAnalysis/ProductionSalesRatio.vue

@@ -0,0 +1,239 @@
+<template>
+  <div>
+    <el-form inline>
+      <el-form-item label="日期类型">
+        <el-select v-model="selectedType" @change="onTypeChange" placeholder="请选择" size="mini" style="width: 80px;">
+          <el-option label="日" value="days"></el-option>
+          <el-option label="月" value="months"></el-option>
+          <el-option label="季度" value="quarters"></el-option>
+          <el-option label="年" value="years"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="选择时间">
+        <el-date-picker
+          v-if="selectedType === 'days'"
+          v-model="selectedDate"
+          type="date"
+          placeholder="选择日期"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'months'"
+          v-model="selectedDate"
+          type="month"
+          placeholder="选择月份"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'quarters'"
+          v-model="selectedDate"
+          type="month"
+          placeholder="选择季度"
+          size="mini"
+          @change="fetchData"
+          :picker-options="quarterShortcuts"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'years'"
+          v-model="selectedDate"
+          type="year"
+          placeholder="选择年份"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+      </el-form-item>
+    </el-form>
+    <div id="pieChart" style="width: 480px; height: 300px;"></div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+import { productionMarketingRatio } from "@/api/statisticalAnalysis/index";
+
+export default {
+  name: 'ProductionSalesRatio',
+  data() {
+    return {
+      selectedType: 'months',
+      selectedDate: new Date(),
+      chart: null,
+      salesProportion: 19.06,
+      productionProportion: 80.94,
+      quarterShortcuts: {
+        shortcuts: [
+          {
+            text: '第一季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 0, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第二季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 3, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第三季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 6, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第四季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 9, 1);
+              picker.$emit('pick', start);
+            },
+          },
+        ],
+      },
+    };
+  },
+  mounted() {
+    this.chart = echarts.init(document.getElementById('pieChart'));
+    this.initChart();
+    this.fetchData();
+  },
+  methods: {
+    onTypeChange() {
+      this.selectedDate = '';
+      this.chart.clear();
+    },
+    fetchData() {
+      let timeParam;
+      if (this.selectedType === 'years') {
+        timeParam = this.selectedDate.getFullYear();
+      } else if (this.selectedType === 'months') {
+        const year = this.selectedDate.getFullYear();
+        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2); // 获取月份并补零
+        timeParam = `${year}-${month}`;
+      } else if (this.selectedType === 'days') {
+        const year = this.selectedDate.getFullYear();
+        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2);
+        const day = ('0' + this.selectedDate.getDate()).slice(-2); // 获取日期并补零
+        timeParam = `${year}-${month}-${day}`;
+      } else if (this.selectedType === 'quarters') {
+        const month = this.selectedDate.getMonth();
+        // 计算季度,可以通过除以3并向上取整得到
+        const year = this.selectedDate.getFullYear();
+        const quarters = Math.ceil((month + 1) / 3);
+        timeParam = `${year}-${quarters}`;
+      }
+      let payload = {
+        timeType: this.selectedType,
+        timeParam: timeParam
+      };
+
+      productionMarketingRatio(payload).then(response => {
+        this.salesProportion = response.data.salesProportion;
+        this.productionProportion = response.data.productionProportion;
+        this.updateChart();
+      })
+    },
+    initChart() {
+      const option = {
+        title: {
+          text: '产销比例',
+          left: 'center'
+        },
+        tooltip: {
+          trigger: 'item',
+          formatter: '{a} <br/>{b}:  ({d}%)'
+        },
+        legend: {
+          orient: 'vertical',
+          left: 'left',
+          data: ['销售占比', '生产占比']
+        },
+        series: [
+          {
+            name: '产销比例',
+            type: 'pie',
+            radius: '50%',
+            data: [
+              { value: this.salesProportion, name: '销售占比' },
+              { value: this.productionProportion, name: '生产占比' }
+            ],
+            label: {
+              normal: {
+                formatter: params => {
+                  return `${params.name}: ${params.value} `;
+                },
+                position: 'inside'
+              }
+            },
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
+              }
+            }
+          }
+        ]
+      };
+      this.chart.setOption(option);
+    },
+    updateChart() {
+      const option = {
+        title: {
+          text: '产销比例',
+          left: 'center'
+        },
+        tooltip: {
+          trigger: 'item',
+          formatter: '{a} <br/>{b}: ({d}%)'
+        },
+        legend: {
+          orient: 'vertical',
+          left: 'left',
+          data: ['销售占比', '生产占比']
+        },
+        series: [
+          {
+            name: '产销比例',
+            type: 'pie',
+            radius: '50%',
+            data: [
+              { value: this.salesProportion, name: '销售占比' },
+              { value: this.productionProportion, name: '生产占比' }
+            ],
+            label: {
+              normal: {
+                formatter: params => {
+                  console.log('params====',params)
+                  return `${params.name}: ${params.value}`;
+                },
+                position: 'inside'
+              }
+            },
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
+              }
+            }
+          }
+        ]
+      };
+      this.chart.setOption(option);
+    }
+  }
+};
+</script>
+
+<style scoped>
+#pieChart {
+  width: 480px;
+  height: 300px;
+}
+</style>
+

+ 265 - 0
zkqy-ui/src/views/orderMange/statisticalAnalysis/customerOrderRanking.vue

@@ -0,0 +1,265 @@
+<template>
+  <div>
+    <div id="customerOrderChart" style="width: 730px; height: 300px;"></div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+import { customerOrderRanking } from "@/api/statisticalAnalysis/index";
+
+export default {
+  name: 'CustomerOrderRanking',
+  data() {
+    return {
+      chart: null,
+      customerNames: [],
+      orderCounts: [],
+      productWeights: [],
+    };
+  },
+  mounted() {
+    this.chart = echarts.init(document.getElementById('customerOrderChart'));
+    this.fetchData();
+  },
+  methods: {
+    fetchData() {
+      customerOrderRanking().then(response => {
+        const data = response.data.sort((a, b) => a.orderCount - b.orderCount);;
+        this.customerNames = data.map(item => item.customerName);
+        this.orderCounts = data.map(item => item.orderCount);
+        this.productWeights = data.map(item => item.weight);
+        this.updateChart();
+      });
+    },
+    updateChart() {
+      const option = {
+        title: {
+          text: '客户订单排行前10名',
+          left: 'center'
+        },
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          },
+          formatter: (params) => {
+
+            const item = this.customerNames[params[0].dataIndex];
+            const item1 = this.orderCounts[params[0].dataIndex];
+            const item2 = this.productWeights[params[0].dataIndex];
+            return `${item}<br/>单据数量: ${item1}<br/>货品总量: ${item2}`;
+          }
+        },
+
+        grid: {
+          left: '2%',
+          top:'1%',
+          right: '5%',
+          bottom: '0%',
+          containLabel: true
+        },
+        xAxis: [{
+          show: false,
+        }],
+        yAxis: [
+          {
+            axisTick:'none',
+            axisLine:'none',
+            offset:'7',
+            axisLabel: {
+              textStyle: {
+                color: '#000000',
+                fontSize:'12',
+              }
+            },
+            data: this.customerNames
+          },
+          {
+            axisTick:'none',
+            axisLine:'none',
+            axisLabel: {
+              textStyle: {
+                color: '#000000',
+                fontSize:'12',
+              }
+            },
+            data: this.orderCounts
+          },
+          {
+            name:'单位:件',
+            nameGap:'50',
+            offset:'7',
+            nameTextStyle:{
+              color: '#000000',
+              fontSize:'12',
+            },
+            axisLine:{
+              lineStyle:{
+                color:'rgba(0,0,0,0)'
+              }
+            },
+            data: [],
+          }
+        ],
+        series: [
+          {
+            name: '单据总量',
+            type: 'bar',
+            yAxisIndex: 0,
+            data: this.productWeights,
+            label:{
+              normal:{
+                show:true,
+                position:'insideRight',
+                // formatter:function(param){
+                //   return param.value + '%';
+                // },
+                textStyle:{
+                  color: '#000000',
+                  fontSize:'12',
+                }
+              }
+            },
+            barWidth: 15,
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [{
+                  offset: 0,
+                  color: '#03c893'
+                },
+                  {
+                    offset: 1,
+                    color: '#0091ff'
+                  }
+                ]),
+                barBorderRadius: 15,
+              }
+            },
+            z: 2
+          },
+        ]
+      };
+      this.chart.setOption(option);
+    }
+  }
+};
+</script>
+
+<style scoped>
+#customerOrderChart {
+  width: 730px;
+  height: 300px;
+}
+</style>
+
+<!--<template>-->
+<!--  <div>-->
+<!--    <div id="customerOrderChart" style="width: 100%; height: 400px;"></div>-->
+<!--  </div>-->
+<!--</template>-->
+
+<!--<script>-->
+<!--import * as echarts from 'echarts';-->
+<!--import { customerOrderRanking } from "@/api/statisticalAnalysis/index";-->
+
+<!--export default {-->
+<!--  name: 'CustomerOrderRanking',-->
+<!--  data() {-->
+<!--    return {-->
+<!--      chart: null,-->
+<!--      customerNames: [],-->
+<!--      orderCounts: [],-->
+<!--      productWeights: [],-->
+<!--    };-->
+<!--  },-->
+<!--  mounted() {-->
+<!--    this.chart = echarts.init(document.getElementById('customerOrderChart'));-->
+<!--    this.fetchData();-->
+<!--  },-->
+<!--  methods: {-->
+<!--    fetchData() {-->
+<!--      customerOrderRanking().then(response => {-->
+<!--        const data = response.data.sort((a, b) => b.orderCount - a.orderCount);;-->
+<!--        this.customerNames = data.map(item => item.customerName);-->
+<!--        this.orderCounts = data.map(item => item.orderCount);-->
+<!--        this.productWeights = data.map(item => item.weight);-->
+<!--        this.updateChart();-->
+<!--      });-->
+<!--    },-->
+<!--    updateChart() {-->
+<!--      const option = {-->
+<!--        title: {-->
+<!--          text: '客户订单排行前10名',-->
+<!--          left: 'center'-->
+<!--        },-->
+<!--        tooltip: {-->
+<!--          trigger: 'axis',-->
+<!--          axisPointer: {-->
+<!--            type: 'shadow'-->
+<!--          }-->
+<!--        },-->
+<!--        legend: {-->
+<!--          data: ['单据总量', '货品总数量'],-->
+<!--          top: '10%'-->
+<!--        },-->
+<!--        grid: {-->
+<!--          left: '3%',-->
+<!--          right: '4%',-->
+<!--          bottom: '3%',-->
+<!--          containLabel: true-->
+<!--        },-->
+<!--        xAxis: {-->
+<!--          type: 'category',-->
+<!--          data: this.customerNames,-->
+<!--          axisLabel: {-->
+<!--            interval: 0, // 强制显示所有标签-->
+<!--            rotate: 45 // 旋转角度-->
+<!--          }-->
+<!--        },-->
+<!--        yAxis: [-->
+<!--          {-->
+<!--            type: 'value',-->
+<!--            name: '单据总量',-->
+<!--            position: 'left'-->
+<!--          },-->
+<!--          {-->
+<!--            type: 'value',-->
+<!--            name: '货品总数量',-->
+<!--            position: 'right'-->
+<!--          }-->
+<!--        ],-->
+<!--        series: [-->
+<!--          {-->
+<!--            name: '单据总量',-->
+<!--            type: 'bar',-->
+<!--            data: this.orderCounts,-->
+<!--            label: {-->
+<!--              show: true,-->
+<!--              position: 'inside'-->
+<!--            }-->
+<!--          },-->
+<!--          {-->
+<!--            name: '货品总数量',-->
+<!--            type: 'line',-->
+<!--            yAxisIndex: 1,-->
+<!--            data: this.productWeights,-->
+<!--            label: {-->
+<!--              show: true,-->
+<!--              position: 'top'-->
+<!--            }-->
+<!--          }-->
+<!--        ]-->
+<!--      };-->
+<!--      this.chart.setOption(option);-->
+<!--    }-->
+<!--  }-->
+<!--};-->
+<!--</script>-->
+
+<!--<style scoped>-->
+<!--#customerOrderChart {-->
+<!--  width: 100%;-->
+<!--  height: 400px;-->
+<!--}-->
+<!--</style>-->

+ 601 - 0
zkqy-ui/src/views/orderMange/statisticalAnalysis/customerStatistics.vue

@@ -0,0 +1,601 @@
+<template>
+  <div>
+    <el-form inline>
+      <el-form-item label="选择客户">
+        <el-select v-model="customerNo" @change="fetchData" placeholder="请选择客户类型" size="mini" style="width: 120px;">
+          <el-option
+            v-for="item in customerList"
+            :key="item.id"
+            :label="item.customName"
+            :value="item.customNo"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="日期类型">
+        <el-select v-model="selectedType" @change="onTypeChange" placeholder="请选择" size="mini" style="width: 80px;">
+          <el-option label="日" value="days"></el-option>
+          <el-option label="月" value="months"></el-option>
+          <el-option label="季度" value="quarters"></el-option>
+          <el-option label="年" value="years"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="选择时间">
+        <el-date-picker
+          v-if="selectedType === 'days'"
+          v-model="selectedDate"
+          type="date"
+          placeholder="选择日期"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'months'"
+          v-model="selectedDate"
+          type="month"
+          placeholder="选择月份"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'quarters'"
+          v-model="selectedDate"
+          type="month"
+          placeholder="选择季度"
+          size="mini"
+          @change="fetchData"
+          :picker-options="quarterShortcuts"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'years'"
+          v-model="selectedDate"
+          type="year"
+          placeholder="选择年份"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+      </el-form-item>
+    </el-form>
+    <div id="barChart5" style="width: 730px; height: 300px;"></div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+import {getCustomerList, customerOrderStatistics} from "@/api/statisticalAnalysis/index";
+
+export default {
+  name: 'CustomerStatistics',
+  data() {
+    return {
+      customerNo:null,
+      customerList: [],
+      selectedType: 'months',
+      selectedDate: new Date(),
+      orderCount: 0,
+      chart: null,
+      chartData: [],
+      quarterShortcuts: {
+        shortcuts: [
+          {
+            text: '第一季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 0, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第二季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 3, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第三季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 6, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第四季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 9, 1);
+              picker.$emit('pick', start);
+            },
+          },
+        ],
+      },
+    };
+  },
+  created() {
+    this.fetchCustomerList();
+    this.fetchData();
+  },
+  mounted() {
+    this.chart = echarts.init(document.getElementById('barChart5'));
+    this.initChart();
+  },
+  methods: {
+    fetchCustomerList() {
+      let payload = {
+        // codeType: 'type',
+        isEnablePaging: false
+      };
+      getCustomerList(payload).then(response => {
+        this.customerList = response.rows;
+        if (this.customerList.length > 0) {
+          this.customerNo = this.customerList[0].customNo;
+          this.fetchData(); // 获取默认产品类型的数据并更新图表
+        }
+      });
+    },
+    onTypeChange() {
+      this.selectedDate = '';
+      this.chart.clear();
+    },
+    fetchData() {
+      let timeParam;
+      if (this.selectedType === 'years') {
+        timeParam = this.selectedDate.getFullYear();
+      } else if (this.selectedType === 'months') {
+        const year = this.selectedDate.getFullYear();
+        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2); // 获取月份并补零
+        timeParam = `${year}-${month}`;
+      } else if (this.selectedType === 'days') {
+        const year = this.selectedDate.getFullYear();
+        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2);
+        const day = ('0' + this.selectedDate.getDate()).slice(-2); // 获取日期并补零
+        timeParam = `${year}-${month}-${day}`;
+      } else if (this.selectedType === 'quarters') {
+        const month = this.selectedDate.getMonth();
+        // 计算季度,可以通过除以3并向上取整得到
+        const year = this.selectedDate.getFullYear();
+        const quarters = Math.ceil((month + 1) / 3);
+        timeParam = `${year}-${quarters}`;
+      }
+      if (!this.customerNo) return;
+      let payload = {
+        timeType: this.selectedType,
+        timeParam: timeParam,
+        customerNo: this.customerNo
+      };
+      customerOrderStatistics(payload).then(response => {
+        this.orderCount = response.data.orderCount;
+        this.chartData = response.data.productInfo;
+        this.updateChart();
+      })
+    },
+    initChart() {
+      this.updateChart();
+    },
+    updateChart() {
+      const option = {
+        title: {
+          text: `订单数量: ${this.orderCount}`,
+          left: 'center',
+          top: 'top'
+        },
+        grid: {
+          left: 15,
+          top: 20,
+          right: 15,
+          bottom: 0,
+          containLabel: true
+        },
+        tooltip: {
+          show: true,
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          },
+          formatter: (params) => {
+            const item = this.chartData[params[0].dataIndex];
+            return `${item.productName}<br/>重量: ${item.weight}<br/>色号: ${item.productColour}`;
+          }
+        },
+        xAxis: {
+          // type: 'category',
+          data: this.chartData.map(item => item.productName),
+          // axisLabel: {
+          //   rotate: 45, // 旋转角度,根据实际情况调整
+          //   fontSize: 9 // 字体大小
+          // }
+          //坐标轴
+          axisLine: {
+            lineStyle: {
+              color: "#3eb2e8",
+            },
+          },
+          //坐标值标注
+          axisLabel: {
+            show: true,
+            textStyle: {
+              color: "#000000",
+            },
+          },
+        },
+        yAxis: {
+          //坐标轴
+          axisLine: {
+            show: false,
+          },
+          //坐标值标注
+          axisLabel: {
+            show: true,
+            textStyle: {
+              color: "#000000",
+            },
+          },
+          //分格线
+          splitLine: {
+            lineStyle: {
+              color: "#4784e8",
+            },
+          },
+        },
+        series: [
+          {
+            name: '重量',
+            tooltip: {
+              show: true,
+            },
+            type: 'bar',
+            barWidth: 24.5,
+            data: this.chartData.map(item => item.weight),
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(
+                  0,
+                  1,
+                  0,
+                  0,
+                  [
+                    {
+                      offset: 0,
+                      color: "#0B4EC3", // 0% 处的颜色
+                    },
+                    {
+                      offset: 0.6,
+                      color: "#138CEB", // 60% 处的颜色
+                    },
+                    {
+                      offset: 1,
+                      color: "#17AAFE", // 100% 处的颜色
+                    },
+                  ],
+                  false
+                ),
+              },
+            },
+            barGap: 0,
+          },
+          {
+            type: "bar",
+            barWidth: 8,
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(
+                  0,
+                  1,
+                  0,
+                  0,
+                  [
+                    {
+                      offset: 0,
+                      color: "#09337C", // 0% 处的颜色
+                    },
+                    {
+                      offset: 0.6,
+                      color: "#0761C0", // 60% 处的颜色
+                    },
+                    {
+                      offset: 1,
+                      color: "#0575DE", // 100% 处的颜色
+                    },
+                  ],
+                  false
+                ),
+              },
+            },
+            barGap: 0,
+            data: this.chartData.map(item => item.weight),
+          },
+          {
+            name: "b",
+            tooltip: {
+              show: false,
+            },
+            type: "pictorialBar",
+            itemStyle: {
+              borderWidth: 1,
+              borderColor: "#0571D5",
+              color: "#1779E0",
+            },
+            symbol: "path://M 0,0 l 120,0 l -30,60 l -120,0 z",
+            symbolSize: ["33", "8"],
+            symbolOffset: ["0", "-5"],
+            //symbolRotate: -5,
+            symbolPosition: "end",
+            data: this.chartData.map(item => item.weight),
+            z: 3,
+          },
+        ]
+      };
+      this.chart.setOption(option);
+    }
+  }
+};
+</script>
+
+<style scoped>
+#barChart5 {
+  width: 730px;
+  height: 300px;
+}
+</style>
+
+<!--<template>-->
+<!--  <div>-->
+<!--    <el-form inline>-->
+<!--      <el-form-item label="选择客户">-->
+<!--        <el-select v-model="customerNo" @change="fetchData" placeholder="请选择产品类型">-->
+<!--          <el-option-->
+<!--            v-for="item in customerList"-->
+<!--            :key="item.id"-->
+<!--            :label="item.customName"-->
+<!--            :value="item.customNo"-->
+<!--          ></el-option>-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="选择统计类型">-->
+<!--        <el-select v-model="selectedType" @change="onTypeChange" placeholder="请选择">-->
+<!--          <el-option label="日" value="days"></el-option>-->
+<!--          <el-option label="月" value="months"></el-option>-->
+<!--          <el-option label="季度" value="quarters"></el-option>-->
+<!--          <el-option label="年" value="years"></el-option>-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="选择时间">-->
+<!--        <el-date-picker-->
+<!--          v-if="selectedType === 'days'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="date"-->
+<!--          placeholder="选择日期"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'months'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="month"-->
+<!--          placeholder="选择月份"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'quarters'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="month"-->
+<!--          placeholder="选择季度"-->
+<!--          @change="fetchData"-->
+<!--          :picker-options="quarterShortcuts"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'years'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="year"-->
+<!--          placeholder="选择年份"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--      </el-form-item>-->
+<!--    </el-form>-->
+<!--    <div id="barChart5" style="width: 100%; height: 400px;"></div>-->
+<!--  </div>-->
+<!--</template>-->
+
+<!--<script>-->
+<!--import * as echarts from 'echarts';-->
+<!--import {getCustomerList, customerOrderStatistics} from "@/api/statisticalAnalysis/index";-->
+
+<!--export default {-->
+<!--  name: 'CustomerStatistics',-->
+<!--  data() {-->
+<!--    return {-->
+<!--      customerNo:null,-->
+<!--      customerList: [],-->
+<!--      selectedType: 'months',-->
+<!--      selectedDate: new Date(),-->
+<!--      orderCount: 0,-->
+<!--      chart: null,-->
+<!--      chartData: [],-->
+<!--      quarterShortcuts: {-->
+<!--        shortcuts: [-->
+<!--          {-->
+<!--            text: '第一季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 0, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第二季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 3, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第三季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 6, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第四季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 9, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--        ],-->
+<!--      },-->
+<!--    };-->
+<!--  },-->
+<!--  created() {-->
+<!--    this.fetchCustomerList();-->
+<!--    this.fetchData();-->
+<!--  },-->
+<!--  mounted() {-->
+<!--    this.chart = echarts.init(document.getElementById('barChart5'));-->
+<!--    this.initChart();-->
+<!--  },-->
+<!--  methods: {-->
+<!--    fetchCustomerList() {-->
+<!--      let payload = {-->
+<!--        // codeType: 'type',-->
+<!--        isEnablePaging: false-->
+<!--      };-->
+<!--      getCustomerList(payload).then(response => {-->
+<!--        this.customerList = response.rows;-->
+<!--        if (this.customerList.length > 0) {-->
+<!--          this.customerNo = this.customerList[0].customNo;-->
+<!--          this.fetchData(); // 获取默认产品类型的数据并更新图表-->
+<!--        }-->
+<!--      });-->
+<!--    },-->
+<!--    onTypeChange() {-->
+<!--      this.selectedDate = '';-->
+<!--      this.chart.clear();-->
+<!--    },-->
+<!--    fetchData() {-->
+<!--      let timeParam;-->
+<!--      if (this.selectedType === 'years') {-->
+<!--        timeParam = this.selectedDate.getFullYear();-->
+<!--      } else if (this.selectedType === 'months') {-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2); // 获取月份并补零-->
+<!--        timeParam = `${year}-${month}`;-->
+<!--      } else if (this.selectedType === 'days') {-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2);-->
+<!--        const day = ('0' + this.selectedDate.getDate()).slice(-2); // 获取日期并补零-->
+<!--        timeParam = `${year}-${month}-${day}`;-->
+<!--      } else if (this.selectedType === 'quarters') {-->
+<!--        const month = this.selectedDate.getMonth();-->
+<!--        // 计算季度,可以通过除以3并向上取整得到-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const quarters = Math.ceil((month + 1) / 3);-->
+<!--        timeParam = `${year}-${quarters}`;-->
+<!--      }-->
+<!--      if (!this.customerNo) return;-->
+<!--      let payload = {-->
+<!--        timeType: this.selectedType,-->
+<!--        timeParam: timeParam,-->
+<!--        customerNo: this.customerNo-->
+<!--      };-->
+<!--      customerOrderStatistics(payload).then(response => {-->
+<!--        this.orderCount = response.data.orderCount;-->
+<!--        this.chartData = response.data.productInfo;-->
+<!--        this.updateChart();-->
+<!--      })-->
+<!--    },-->
+<!--    initChart() {-->
+<!--      const option = {-->
+<!--        title: {-->
+<!--          text: `订单数量: ${this.orderCount}`,-->
+<!--          left: 'center',-->
+<!--          top: 'top'-->
+<!--        },-->
+<!--        tooltip: {-->
+<!--          trigger: 'axis',-->
+<!--          axisPointer: {-->
+<!--            type: 'shadow'-->
+<!--          },-->
+<!--          formatter: (params) => {-->
+<!--            console.log("159",params)-->
+<!--            const item = this.chartData[params[0].dataIndex];-->
+<!--            console.log("169",item)-->
+<!--            return `${item.productName}<br/>重量: ${item.weight}<br/>色号: ${item.productColour}`;-->
+<!--          }-->
+<!--        },-->
+<!--        xAxis: {-->
+<!--          type: 'category',-->
+<!--          data: this.chartData.map(item => item.productName),-->
+<!--          axisLabel: {-->
+<!--            rotate: 45, // 旋转角度,根据实际情况调整-->
+<!--            fontSize: 9 // 字体大小-->
+<!--          }-->
+<!--        },-->
+<!--        yAxis: {-->
+<!--          type: 'value',-->
+<!--          name: '重量'-->
+<!--        },-->
+<!--        series: [-->
+<!--          {-->
+<!--            name: '重量',-->
+<!--            type: 'bar',-->
+<!--            data: this.chartData.map(item => item.weight),-->
+<!--            label: {-->
+<!--              show: true,-->
+<!--              position: 'top'-->
+<!--            }-->
+<!--          }-->
+<!--        ]-->
+<!--      };-->
+<!--      this.chart.setOption(option);-->
+<!--    },-->
+<!--    updateChart() {-->
+<!--      const option = {-->
+<!--        title: {-->
+<!--          text: `订单数量: ${this.orderCount}`,-->
+<!--          left: 'center',-->
+<!--          top: 'top'-->
+<!--        },-->
+<!--        tooltip: {-->
+<!--          trigger: 'axis',-->
+<!--          axisPointer: {-->
+<!--            type: 'shadow'-->
+<!--          },-->
+<!--          formatter: (params) => {-->
+<!--            console.log("159",params)-->
+<!--            const item = this.chartData[params[0].dataIndex];-->
+<!--            console.log("169",item)-->
+<!--            return `${item.productName}<br/>重量: ${item.weight}<br/>色号: ${item.productColour}`;-->
+<!--          }-->
+<!--        },-->
+<!--        xAxis: {-->
+<!--          type: 'category',-->
+<!--          data: this.chartData.map(item => item.productName),-->
+<!--          axisLabel: {-->
+<!--            rotate: 45, // 旋转角度,根据实际情况调整-->
+<!--            fontSize: 9 // 字体大小-->
+<!--          }-->
+<!--        },-->
+<!--        yAxis: {-->
+<!--          type: 'value',-->
+<!--          name: '重量'-->
+<!--        },-->
+<!--        series: [-->
+<!--          {-->
+<!--            name: '重量',-->
+<!--            type: 'bar',-->
+<!--            data: this.chartData.map(item => item.weight),-->
+<!--            label: {-->
+<!--              show: true,-->
+<!--              position: 'top'-->
+<!--            }-->
+<!--          }-->
+<!--        ]-->
+<!--      };-->
+<!--      this.chart.setOption(option);-->
+<!--    }-->
+<!--  }-->
+<!--};-->
+<!--</script>-->
+
+<!--<style scoped>-->
+<!--#barChart5 {-->
+<!--  width: 100%;-->
+<!--  height: 400px;-->
+<!--}-->
+<!--</style>-->

+ 467 - 0
zkqy-ui/src/views/orderMange/statisticalAnalysis/fastSellingProduct.vue

@@ -0,0 +1,467 @@
+<template>
+  <div>
+    <el-form inline>
+      <el-form-item label="日期类型">
+        <el-select v-model="selectedType" @change="onTypeChange" placeholder="请选择" size="mini" style="width: 80px;">
+          <el-option label="日" value="days"></el-option>
+          <el-option label="月" value="months"></el-option>
+          <el-option label="季度" value="quarters"></el-option>
+          <el-option label="年" value="years"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="选择时间">
+        <el-date-picker
+          v-if="selectedType === 'days'"
+          v-model="selectedDate"
+          type="date"
+          placeholder="选择日期"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'months'"
+          v-model="selectedDate"
+          type="month"
+          placeholder="选择月份"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'quarters'"
+          v-model="selectedDate"
+          type="month"
+          placeholder="选择季度"
+          size="mini"
+          @change="fetchData"
+          :picker-options="quarterShortcuts"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'years'"
+          v-model="selectedDate"
+          type="year"
+          placeholder="选择年份"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+      </el-form-item>
+    </el-form>
+    <div id="barChart2" style="width: 480px; height: 300px;"></div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+import { fastSellingProduct } from "@/api/statisticalAnalysis/index";
+
+export default {
+  name: 'SaleOrderRanking',
+  data() {
+    return {
+      selectedType: 'months',
+      selectedDate: new Date(),
+      chart: null,
+      chartData: [],
+      quarterShortcuts: {
+        shortcuts: [
+          {
+            text: '第一季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 0, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第二季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 3, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第三季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 6, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第四季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 9, 1);
+              picker.$emit('pick', start);
+            },
+          },
+        ],
+      },
+    };
+  },
+  created() {
+    this.fetchData();
+  },
+  mounted() {
+    this.chart = echarts.init(document.getElementById('barChart2'));
+    this.initChart();
+  },
+  methods: {
+    onTypeChange() {
+      this.selectedDate = '';
+      this.chart.clear();
+    },
+    fetchData() {
+      let timeParam;
+      if (this.selectedType === 'years') {
+        timeParam = this.selectedDate.getFullYear();
+      } else if (this.selectedType === 'months') {
+        const year = this.selectedDate.getFullYear();
+        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2); // 获取月份并补零
+        timeParam = `${year}-${month}`;
+      } else if (this.selectedType === 'days') {
+        const year = this.selectedDate.getFullYear();
+        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2);
+        const day = ('0' + this.selectedDate.getDate()).slice(-2); // 获取日期并补零
+        timeParam = `${year}-${month}-${day}`;
+      } else if (this.selectedType === 'quarters') {
+        const month = this.selectedDate.getMonth();
+        // 计算季度,可以通过除以3并向上取整得到
+        const year = this.selectedDate.getFullYear();
+        const quarters = Math.ceil((month + 1) / 3);
+        timeParam = `${year}-${quarters}`;
+      }
+      let payload = {
+        timeType: this.selectedType,
+        timeParam: timeParam
+      };
+
+      fastSellingProduct(payload).then(response => {
+        // 假设从后端获取到的数据结构与初始数据结构相同
+        this.chartData = response.data.sort((a, b) => a.weight - b.weight); // 按weight排序
+        this.updateChart();
+      })
+    },
+    initChart() {
+     this.updateChart();
+    },
+    updateChart() {
+      const option = {
+        title: {
+          text: '快销产品',
+          left: 'center'
+        },
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          },
+          formatter: (params) => {
+            console.log('item',params)
+            const item = this.chartData[params[0].dataIndex];
+            return `${item.productName}<br/>规格: ${item.spec}<br/>重量: ${item.weight}<br/>色号: ${item.productColour}`;
+          }
+        },
+        grid: {
+          left: 15,
+          top: 10,
+          right: 15,
+          bottom: 0,
+          containLabel: true
+        },
+        xAxis: {
+          show: false,
+          type: "value",
+        },
+        yAxis: [
+          {
+            type: 'category',
+            data: this.chartData.map(item => item.productName),
+            axisLabel: {
+              show: true,
+              textStyle: {
+                color: "#000000",
+                fontSize: 12
+              },
+            },
+            splitLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            axisLine: {
+              show: false,
+            },
+          },
+        ],
+        series: [
+          {
+            name: '重量',
+            type: 'bar',
+            zlevel: 1,
+            label: {
+              show: true,
+              position: 'right',
+              padding: 6,
+              color: '#4e84a1',
+              fontSize: 12,
+              formatter: '{c}'
+
+            },
+            itemStyle: {
+              normal: {
+                barBorderRadius: 30,
+                color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{
+                  offset: 0,
+                  color: "rgb(57,89,255,1)",
+                },
+                  {
+                    offset: 1,
+                    color: "rgb(46,200,207,1)",
+                  },
+                ]),
+              },
+            },
+            barWidth: 10,
+            data: this.chartData.map(item => item.weight)
+          }
+        ]
+      };
+      this.chart.setOption(option);
+    }
+  }
+};
+</script>
+
+<style scoped>
+#barChart2 {
+  width: 480px;
+  height: 300px;
+}
+</style>
+
+
+<!--<template>-->
+<!--  <div>-->
+<!--    <el-form inline>-->
+<!--      <el-form-item label="选择统计类型">-->
+<!--        <el-select v-model="selectedType" @change="onTypeChange" placeholder="请选择">-->
+<!--          <el-option label="日" value="days"></el-option>-->
+<!--          <el-option label="月" value="months"></el-option>-->
+<!--          <el-option label="季度" value="quarters"></el-option>-->
+<!--          <el-option label="年" value="years"></el-option>-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="选择时间">-->
+<!--        <el-date-picker-->
+<!--          v-if="selectedType === 'days'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="date"-->
+<!--          placeholder="选择日期"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'months'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="month"-->
+<!--          placeholder="选择月份"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'quarters'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="month"-->
+<!--          placeholder="选择季度"-->
+<!--          @change="fetchData"-->
+<!--          :picker-options="quarterShortcuts"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'years'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="year"-->
+<!--          placeholder="选择年份"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--      </el-form-item>-->
+<!--    </el-form>-->
+<!--    <div id="barChart2" style="width: 100%; height: 400px;"></div>-->
+<!--  </div>-->
+<!--</template>-->
+
+<!--<script>-->
+<!--import * as echarts from 'echarts';-->
+<!--import { fastSellingProduct } from "@/api/statisticalAnalysis/index";-->
+
+<!--export default {-->
+<!--  name: 'SaleOrderRanking',-->
+<!--  data() {-->
+<!--    return {-->
+<!--      selectedType: 'months',-->
+<!--      selectedDate: new Date(),-->
+<!--      chart: null,-->
+<!--      chartData: [],-->
+<!--      quarterShortcuts: {-->
+<!--        shortcuts: [-->
+<!--          {-->
+<!--            text: '第一季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 0, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第二季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 3, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第三季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 6, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第四季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 9, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--        ],-->
+<!--      },-->
+<!--    };-->
+<!--  },-->
+<!--  created() {-->
+<!--    this.fetchData();-->
+<!--  },-->
+<!--  mounted() {-->
+<!--    this.chart = echarts.init(document.getElementById('barChart2'));-->
+<!--    this.initChart();-->
+<!--  },-->
+<!--  methods: {-->
+<!--    onTypeChange() {-->
+<!--      this.selectedDate = '';-->
+<!--      this.chart.clear();-->
+<!--    },-->
+<!--    fetchData() {-->
+<!--      let timeParam;-->
+<!--      if (this.selectedType === 'years') {-->
+<!--        timeParam = this.selectedDate.getFullYear();-->
+<!--      } else if (this.selectedType === 'months') {-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2); // 获取月份并补零-->
+<!--        timeParam = `${year}-${month}`;-->
+<!--      } else if (this.selectedType === 'days') {-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2);-->
+<!--        const day = ('0' + this.selectedDate.getDate()).slice(-2); // 获取日期并补零-->
+<!--        timeParam = `${year}-${month}-${day}`;-->
+<!--      } else if (this.selectedType === 'quarters') {-->
+<!--        const month = this.selectedDate.getMonth();-->
+<!--        // 计算季度,可以通过除以3并向上取整得到-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const quarters = Math.ceil((month + 1) / 3);-->
+<!--        timeParam = `${year}-${quarters}`;-->
+<!--      }-->
+<!--      let payload = {-->
+<!--        timeType: this.selectedType,-->
+<!--        timeParam: timeParam-->
+<!--      };-->
+
+<!--      fastSellingProduct(payload).then(response => {-->
+<!--        // 假设从后端获取到的数据结构与初始数据结构相同-->
+<!--        this.chartData = response.data.sort((a, b) => a.weight - b.weight); // 按weight排序-->
+<!--        this.updateChart();-->
+<!--      })-->
+<!--    },-->
+<!--    initChart() {-->
+<!--      const option = {-->
+<!--        title: {-->
+<!--          text: '快销产品',-->
+<!--          left: 'center'-->
+<!--        },-->
+<!--        tooltip: {-->
+<!--          trigger: 'axis',-->
+<!--          axisPointer: {-->
+<!--            type: 'shadow'-->
+<!--          },-->
+<!--          formatter: (params) => {-->
+<!--            const item = this.chartData[params[0].dataIndex];-->
+<!--            return `${item.productName}<br/>规格: ${item.spec}<br/>重量: ${item.weight}<br/>色号: ${item.productColour}`;-->
+<!--          }-->
+<!--        },-->
+<!--        xAxis: {-->
+<!--          type: 'value',-->
+<!--          boundaryGap: [0, 0.01]-->
+<!--        },-->
+<!--        yAxis: {-->
+<!--          type: 'category',-->
+<!--          data: this.chartData.map(item => item.productName),-->
+<!--          axisLabel: {-->
+<!--            rotate: 45, // 旋转角度,根据实际情况调整-->
+<!--            fontSize: 9, // 字体大小-->
+<!--            interval: 0, // 是否全部显示标签,可能会导致图表过密,根据情况调整-->
+<!--            overflow: 'break' // 或者其他处理溢出方式,如 'break' 自动换行-->
+<!--          }-->
+<!--        },-->
+<!--        series: [-->
+<!--          {-->
+<!--            name: '重量',-->
+<!--            type: 'bar',-->
+<!--            data: this.chartData.map(item => item.weight),-->
+<!--          }-->
+<!--        ]-->
+<!--      };-->
+<!--      this.chart.setOption(option);-->
+<!--    },-->
+<!--    updateChart() {-->
+<!--      const option = {-->
+<!--        title: {-->
+<!--          text: '快销产品',-->
+<!--          left: 'center'-->
+<!--        },-->
+<!--        tooltip: {-->
+<!--          trigger: 'axis',-->
+<!--          axisPointer: {-->
+<!--            type: 'shadow'-->
+<!--          },-->
+<!--          formatter: (params) => {-->
+<!--            const item = this.chartData[params[0].dataIndex];-->
+<!--            return `${item.productName}<br/>规格: ${item.spec}<br/>重量: ${item.weight}<br/>色号: ${item.productColour}`;-->
+<!--          }-->
+<!--        },-->
+<!--        xAxis: {-->
+<!--          type: 'value',-->
+<!--          boundaryGap: [0, 0.01]-->
+<!--        },-->
+<!--        yAxis: {-->
+<!--          type: 'category',-->
+<!--          data: this.chartData.map(item => item.productName),-->
+<!--          axisLabel: {-->
+<!--            rotate: 45, // 旋转角度,根据实际情况调整-->
+<!--            fontSize: 9, // 字体大小-->
+<!--            interval: 0, // 是否全部显示标签,可能会导致图表过密,根据情况调整-->
+<!--            overflow: 'break' // 或者其他处理溢出方式,如 'break' 自动换行-->
+<!--          }-->
+<!--        },-->
+<!--        series: [-->
+<!--          {-->
+<!--            name: '重量',-->
+<!--            type: 'bar',-->
+<!--            data: this.chartData.map(item => item.weight)-->
+<!--          }-->
+<!--        ]-->
+<!--      };-->
+<!--      this.chart.setOption(option);-->
+<!--    }-->
+<!--  }-->
+<!--};-->
+<!--</script>-->
+
+<!--<style scoped>-->
+<!--#barChart2 {-->
+<!--  width: 120%;-->
+<!--  height: 400px;-->
+<!--}-->
+<!--</style>-->
+

+ 87 - 0
zkqy-ui/src/views/orderMange/statisticalAnalysis/index.vue

@@ -0,0 +1,87 @@
+<template>
+  <div>
+    <el-row>
+      <el-col :span="8">
+        <el-card class="box-card" style="margin-left: 20px;margin-top: 20px">
+          <!--产量统计-->
+          <div>
+            <child-component2></child-component2>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="8">
+        <el-card class="box-card" style="margin-left: 20px;margin-top: 20px">
+          <!--销售统计-产销比例-->
+          <div>
+            <child-component3></child-component3>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="8">
+        <el-card class="box-card" style="margin-left: 20px;margin-top: 20px;margin-right: 20px">
+          <!-- 销售排行 -->
+          <div>
+            <child-component4></child-component4>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <el-row>
+      <el-col :span="8">
+        <el-card class="box-card" style="margin-left: 20px;margin-top: 20px">
+          <!-- 销售品类占比 -->
+          <div style="float: left;padding-bottom: 60px">
+            <child-component5></child-component5>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="8">
+        <el-card class="box-card" style="margin-left: 20px;margin-top: 20px">
+          <!-- 质检优质品统计产品等级 -->
+          <div style="float: left">
+            <child-component1></child-component1>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="8">
+        <el-card class="box-card" style="margin-left: 20px;margin-top: 20px;margin-right: 20px">
+          <!-- 快销产品统计 -->
+          <div style="float: left">
+            <child-component6></child-component6>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import ChildComponent1 from './peoductLevel.vue';
+import ChildComponent2 from './yield.vue';
+import ChildComponent3 from './ProductionSalesRatio.vue';
+import ChildComponent4 from './saleOrderRanking.vue';
+import ChildComponent5 from './saleCategoryProportion.vue';
+import ChildComponent6 from './fastSellingProduct.vue'
+
+export default {
+  name: 'ParentComponent',
+  components: {
+    ChildComponent1,
+    ChildComponent2,
+    ChildComponent3,
+    ChildComponent4,
+    ChildComponent5,
+    ChildComponent6
+  }
+};
+</script>
+
+<style scoped>
+.box-card {
+  box-shadow: 10px 10px 5px #e0e0e0;
+  background-color: #fff;
+  border-radius: 10px;
+}
+
+</style>

+ 286 - 0
zkqy-ui/src/views/orderMange/statisticalAnalysis/peoductLevel.vue

@@ -0,0 +1,286 @@
+<template>
+  <div>
+    <!-- 表单容器 -->
+    <el-form inline>
+      <el-form-item label="选择产品类型">
+        <el-select v-model="selectedProductType" @change="fetchData" placeholder="请选择产品类型" size="mini" style="width: 180px;">
+          <el-option
+            v-for="item in productTypes"
+            :key="item.id"
+            :label="item.codeName"
+            :value="item.codeName"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+    </el-form>
+
+    <!-- 图表容器 -->
+    <div id="main1" style="width: 480px; height: 300px;"></div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+import 'element-ui/lib/theme-chalk/index.css';
+import {getProductType, statisticsSuttleByLevels} from "@/api/statisticalAnalysis/index";
+
+export default {
+  name: 'peoductLevel',
+  data() {
+    return {
+      selectedProductType:null,
+      productTypes: [],
+      chart: null,
+      chartData: {}
+    };
+  },
+  created() {
+    // 确保 productTypes 已经被填充后再设置 selectedProductType
+    this.fetchProductTypes();
+  },
+  mounted() {
+    this.chart = echarts.init(document.getElementById('main1'));
+    this.initChart();
+  },
+  methods: {
+    fetchProductTypes() {
+      let payload = {
+        codeType: 'type',
+        isEnablePaging: false
+      };
+      // 调用后台接口获取产品类型列表
+      getProductType(payload).then(response => {
+        this.productTypes = response.rows;
+        if (this.productTypes.length > 0) {
+          this.selectedProductType = this.productTypes[0].codeName;
+          this.fetchData(); // 获取默认产品类型的数据并更新图表
+        }
+      });
+    },
+    fetchData() {
+
+      console.log('selectedProductType:', this.selectedProductType)
+      if (!this.selectedProductType) return;
+
+      let payload = {
+        productType: this.selectedProductType
+      };
+
+      statisticsSuttleByLevels(payload).then(response => {
+        this.chartData = response.data;
+        this.updateChart();
+      });
+    },
+    initChart() {
+      this.updateChart();
+    },
+    updateChart() {
+      if (!this.chartData.output) return;
+
+      const option = {
+        title: {
+          text: '产品等级统计',
+          left: 'center'
+        },
+        color: ['#FD9133', '#47F6A2', '#37D2D4', '#3493FF'],
+        tooltip: {
+          trigger: 'item',
+          formatter: (params) => {
+            return `${params.name}<br/>产量: ${params.data.value}`;
+          }
+        },
+        legend: {
+          itemWidth: 20,// 标志图形的长度
+          itemHeight: 10,// 标志图形的宽度
+          orient: 'vertical',
+          // left: 'left'
+          top: '20%',
+          bottom: '50%',
+          x: '5%',
+          textStyle: {
+            color: '#000000',
+            fontSize: 12,
+
+          },
+          data: this.chartData.products,
+        },
+        series: [
+          {
+            name: '产量',
+            type: 'pie',
+            radius: ['50%', '30%'],
+            center: ['50%', '52%'],
+            labelLine: {
+              normal: {
+                length: 50,
+                lineStyle: {
+                  type: 'solid',
+                  color: '#000000'
+                }
+              }
+
+            },
+            data: this.chartData.output.map(item => ({
+              value: item.data,
+              name: item.name
+            })),
+            label: {
+              normal: {
+                formatter: '{b}: {c}',
+                borderWidth: 0,
+                borderRadius: 4,
+                padding: [0,0],
+                height: 20,
+                fontSize: 12,
+                align: 'center',
+                color: '#000000',
+              }
+            },
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
+              }
+            }
+          },
+        ]
+      };
+      this.chart.setOption(option);
+    }
+  }
+};
+</script>
+
+<style scoped>
+#main1 {
+  width: 480px;
+  height: 300px;
+}
+</style>
+
+<!--<template>-->
+<!--  <div>-->
+<!--    &lt;!&ndash; 表单容器 &ndash;&gt;-->
+<!--    <el-form inline>-->
+<!--      <el-form-item label="选择产品类型">-->
+<!--        <el-select v-model="selectedProductType" @change="fetchData" placeholder="请选择产品类型">-->
+<!--          <el-option-->
+<!--            v-for="item in productTypes"-->
+<!--            :key="item.id"-->
+<!--            :label="item.codeName"-->
+<!--            :value="item.codeName"-->
+<!--          ></el-option>-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+<!--    </el-form>-->
+
+<!--    &lt;!&ndash; 图表容器 &ndash;&gt;-->
+<!--    <div id="main1" style="width: 600px; height: 400px;"></div>-->
+<!--  </div>-->
+<!--</template>-->
+
+<!--<script>-->
+<!--import * as echarts from 'echarts';-->
+<!--import 'element-ui/lib/theme-chalk/index.css';-->
+<!--import {getProductType, statisticsSuttleByLevels} from "@/api/statisticalAnalysis/index";-->
+
+<!--export default {-->
+<!--  name: 'peoductLevel',-->
+<!--  data() {-->
+<!--    return {-->
+<!--      selectedProductType:null,-->
+<!--      productTypes: [],-->
+<!--      chart: null,-->
+<!--      chartData: {}-->
+<!--    };-->
+<!--  },-->
+<!--  created() {-->
+<!--    // 确保 productTypes 已经被填充后再设置 selectedProductType-->
+<!--    this.fetchProductTypes();-->
+<!--  },-->
+<!--  mounted() {-->
+<!--    this.chart = echarts.init(document.getElementById('main1'));-->
+<!--    this.initChart();-->
+<!--  },-->
+<!--  methods: {-->
+<!--    fetchProductTypes() {-->
+<!--      let payload = {-->
+<!--          codeType: 'type',-->
+<!--          isEnablePaging: false-->
+<!--      };-->
+<!--      // 调用后台接口获取产品类型列表-->
+<!--      getProductType(payload).then(response => {-->
+<!--        this.productTypes = response.rows;-->
+<!--        if (this.productTypes.length > 0) {-->
+<!--          this.selectedProductType = this.productTypes[0].codeName;-->
+<!--          this.fetchData(); // 获取默认产品类型的数据并更新图表-->
+<!--        }-->
+<!--      });-->
+<!--    },-->
+<!--    fetchData() {-->
+
+<!--      console.log('selectedProductType:', this.selectedProductType)-->
+<!--      if (!this.selectedProductType) return;-->
+
+<!--      let payload = {-->
+<!--        productType: this.selectedProductType-->
+<!--      };-->
+
+<!--      statisticsSuttleByLevels(payload).then(response => {-->
+<!--        this.chartData = response.data;-->
+<!--        this.updateChart();-->
+<!--      });-->
+<!--    },-->
+<!--    initChart() {-->
+<!--      this.updateChart();-->
+<!--    },-->
+<!--    updateChart() {-->
+<!--      if (!this.chartData.output) return;-->
+
+<!--      const option = {-->
+<!--        title: {-->
+<!--          text: '产品等级统计',-->
+<!--          left: 'center'-->
+<!--        },-->
+<!--        tooltip: {-->
+<!--          trigger: 'item',-->
+<!--          formatter: (params) => {-->
+<!--            return `${params.name}<br/>产量: ${params.data.value}`;-->
+<!--          }-->
+<!--        },-->
+<!--        legend: {-->
+<!--          orient: 'vertical',-->
+<!--          left: 'left'-->
+<!--        },-->
+<!--        series: [-->
+<!--          {-->
+<!--            name: '产量',-->
+<!--            type: 'pie',-->
+<!--            radius: '50%',-->
+<!--            data: this.chartData.output.map(item => ({-->
+<!--              value: item.data,-->
+<!--              name: item.name-->
+<!--            })),-->
+<!--            emphasis: {-->
+<!--              itemStyle: {-->
+<!--                shadowBlur: 10,-->
+<!--                shadowOffsetX: 0,-->
+<!--                shadowColor: 'rgba(0, 0, 0, 0.5)'-->
+<!--              }-->
+<!--            }-->
+<!--          }-->
+<!--        ]-->
+<!--      };-->
+<!--      this.chart.setOption(option);-->
+<!--    }-->
+<!--  }-->
+<!--};-->
+<!--</script>-->
+
+<!--<style scoped>-->
+<!--#main1 {-->
+<!--  width: 100%;-->
+<!--  height: 400px;-->
+<!--}-->
+<!--</style>-->

+ 544 - 0
zkqy-ui/src/views/orderMange/statisticalAnalysis/productsSoldRanking.vue

@@ -0,0 +1,544 @@
+<template>
+  <div>
+    <el-form inline>
+      <el-form-item label="选择产品类型">
+        <el-select v-model="selectedProductType" @change="fetchData" placeholder="选择类型" size="mini" style="width: 120px;">
+          <el-option
+            v-for="item in productTypes"
+            :key="item.id"
+            :label="item.codeName"
+            :value="item.codeName"
+          ></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="日期类型">
+        <el-select v-model="selectedType" @change="onTypeChange" placeholder="请选择" size="mini" style="width: 80px;">
+          <el-option label="日" value="days"></el-option>
+          <el-option label="月" value="months"></el-option>
+          <el-option label="季度" value="quarters"></el-option>
+          <el-option label="年" value="years"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="选择时间">
+        <el-date-picker
+          v-if="selectedType === 'days'"
+          v-model="selectedDate"
+          type="date"
+          placeholder="选择日期"
+          @change="fetchData"
+          size="mini"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'months'"
+          v-model="selectedDate"
+          type="month"
+          placeholder="选择月份"
+          @change="fetchData"
+          size="mini"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'quarters'"
+          v-model="selectedDate"
+          type="month"
+          placeholder="选择季度"
+          @change="fetchData"
+          size="mini"
+          :picker-options="quarterShortcuts"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'years'"
+          v-model="selectedDate"
+          type="year"
+          placeholder="选择年份"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+      </el-form-item>
+    </el-form>
+    <div id="barChart3" style="width: 730px; height: 300px;"></div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+import {getProductType, mostItemsSold} from "@/api/statisticalAnalysis/index";
+
+export default {
+  name: 'ProductSoldRanking',
+  data() {
+    return {
+      selectedProductType:null,
+      productTypes: [],
+      selectedType: 'months',
+      selectedDate: new Date(),
+      chart: null,
+      chartData: [],
+      quarterShortcuts: {
+        shortcuts: [
+          {
+            text: '第一季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 0, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第二季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 3, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第三季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 6, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第四季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 9, 1);
+              picker.$emit('pick', start);
+            },
+          },
+        ],
+      },
+    };
+  },
+  created() {
+    this.fetchProductTypes();
+    this.fetchData();
+  },
+  mounted() {
+    this.chart = echarts.init(document.getElementById('barChart3'));
+    this.initChart();
+  },
+  methods: {
+    fetchProductTypes() {
+      let payload = {
+        codeType: 'type',
+        isEnablePaging: false
+      };
+      // 调用后台接口获取产品类型列表
+      getProductType(payload).then(response => {
+        this.productTypes = response.rows;
+        if (this.productTypes.length > 0) {
+          this.selectedProductType = this.productTypes[0].codeName;
+          this.fetchData(); // 获取默认产品类型的数据并更新图表
+        }
+      });
+    },
+    onTypeChange() {
+      this.selectedDate = '';
+      this.chart.clear();
+    },
+    fetchData() {
+      let timeParam;
+      if (this.selectedType === 'years') {
+        timeParam = this.selectedDate.getFullYear();
+      } else if (this.selectedType === 'months') {
+        const year = this.selectedDate.getFullYear();
+        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2); // 获取月份并补零
+        timeParam = `${year}-${month}`;
+      } else if (this.selectedType === 'days') {
+        const year = this.selectedDate.getFullYear();
+        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2);
+        const day = ('0' + this.selectedDate.getDate()).slice(-2); // 获取日期并补零
+        timeParam = `${year}-${month}-${day}`;
+      } else if (this.selectedType === 'quarters') {
+        const month = this.selectedDate.getMonth();
+        // 计算季度,可以通过除以3并向上取整得到
+        const year = this.selectedDate.getFullYear();
+        const quarters = Math.ceil((month + 1) / 3);
+        timeParam = `${year}-${quarters}`;
+      }
+      if (!this.selectedProductType) return;
+      let payload = {
+        timeType: this.selectedType,
+        timeParam: timeParam,
+        productType: this.selectedProductType
+      };
+
+      mostItemsSold(payload).then(response => {
+        // 假设从后端获取到的数据结构与初始数据结构相同
+        this.chartData = response.data.sort((a, b) => a.weight - b.weight); // 按weight排序
+        this.updateChart();
+      })
+    },
+    initChart() {
+      this.updateChart();
+    },
+    updateChart() {
+      const option = {
+        title: {
+          text: '销售排行',
+          left: 'center'
+        },
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          },
+          formatter: (params) => {
+            const item = this.chartData[params[0].dataIndex];
+            return `${item.productName}<br/>重量: ${item.weight}<br/>色号: ${item.productColour}`;
+          }
+        },
+        grid: {
+          left: 15,
+          top: 10,
+          right: 35,
+          bottom: 0,
+          containLabel: true
+        },
+        xAxis: {
+          show: false,
+          type: "value",
+        },
+        yAxis: [
+          {
+            type: 'category',
+
+            data: this.chartData.map(item => item.productName),
+            inverse: true,
+            axisLabel: {
+              show: true,
+              textStyle: {
+                color: "#000000",
+                fontSize: 12
+              },
+            },
+            splitLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            axisLine: {
+              show: false,
+            },
+            // axisLabel: {
+            //   rotate: 45, // 旋转角度,根据实际情况调整
+            //   fontSize: 9, // 字体大小
+            //   interval: 0, // 是否全部显示标签,可能会导致图表过密,根据情况调整
+            //   overflow: 'break' // 或者其他处理溢出方式,如 'break' 自动换行
+            // }
+          },
+          // {
+          //   type: "category",
+          //   inverse: true,
+          //   axisTick: "none",
+          //   axisLine: "none",
+          //   show: true,
+          //   axisLabel: {
+          //     textStyle: {
+          //       color: "#000000",
+          //       fontSize: 15,
+          //     },
+          //   },
+          //   data: this.chartData.map(item => item.weight),
+          // },
+        ],
+        series: [
+          {
+            name: '重量',
+            type: 'bar',
+            zlevel: 1,
+            label: {
+              show: true,
+              position: 'right',
+              padding: 6,
+              color: '#4e84a1',
+              fontSize: 12,
+              formatter: '{c}'
+
+            },
+            itemStyle: {
+              normal: {
+                barBorderRadius: 30,
+                color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{
+                  offset: 0,
+                  color: "rgb(57,89,255,1)",
+                },
+                  {
+                    offset: 1,
+                    color: "rgb(46,200,207,1)",
+                  },
+                ]),
+              },
+            },
+            barWidth: 10,
+            data: this.chartData.map(item => item.weight)
+          }
+        ]
+      };
+      this.chart.setOption(option);
+    }
+  }
+};
+</script>
+
+<style scoped>
+#barChart3 {
+  width: 730px;
+  height: 300px;
+}
+</style>
+
+<!--<template>-->
+<!--  <div>-->
+<!--    <el-form inline>-->
+<!--      <el-form-item label="选择产品类型">-->
+<!--        <el-select v-model="selectedProductType" @change="fetchData" placeholder="请选择产品类型">-->
+<!--          <el-option-->
+<!--            v-for="item in productTypes"-->
+<!--            :key="item.id"-->
+<!--            :label="item.codeName"-->
+<!--            :value="item.codeName"-->
+<!--          ></el-option>-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="选择统计类型">-->
+<!--        <el-select v-model="selectedType" @change="onTypeChange" placeholder="请选择">-->
+<!--          <el-option label="日" value="days"></el-option>-->
+<!--          <el-option label="月" value="months"></el-option>-->
+<!--          <el-option label="季度" value="quarters"></el-option>-->
+<!--          <el-option label="年" value="years"></el-option>-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="选择时间">-->
+<!--        <el-date-picker-->
+<!--          v-if="selectedType === 'days'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="date"-->
+<!--          placeholder="选择日期"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'months'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="month"-->
+<!--          placeholder="选择月份"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'quarters'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="month"-->
+<!--          placeholder="选择季度"-->
+<!--          @change="fetchData"-->
+<!--          :picker-options="quarterShortcuts"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'years'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="year"-->
+<!--          placeholder="选择年份"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--      </el-form-item>-->
+<!--    </el-form>-->
+<!--    <div id="barChart3" style="width: 100%; height: 400px;"></div>-->
+<!--  </div>-->
+<!--</template>-->
+
+<!--<script>-->
+<!--import * as echarts from 'echarts';-->
+<!--import {getProductType, mostItemsSold} from "@/api/statisticalAnalysis/index";-->
+
+<!--export default {-->
+<!--  name: 'ProductSoldRanking',-->
+<!--  data() {-->
+<!--    return {-->
+<!--      selectedProductType:null,-->
+<!--      productTypes: [],-->
+<!--      selectedType: 'months',-->
+<!--      selectedDate: new Date(),-->
+<!--      chart: null,-->
+<!--      chartData: [],-->
+<!--      quarterShortcuts: {-->
+<!--        shortcuts: [-->
+<!--          {-->
+<!--            text: '第一季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 0, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第二季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 3, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第三季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 6, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第四季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 9, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--        ],-->
+<!--      },-->
+<!--    };-->
+<!--  },-->
+<!--  created() {-->
+<!--    this.fetchProductTypes();-->
+<!--    this.fetchData();-->
+<!--  },-->
+<!--  mounted() {-->
+<!--    this.chart = echarts.init(document.getElementById('barChart3'));-->
+<!--    this.initChart();-->
+<!--  },-->
+<!--  methods: {-->
+<!--    fetchProductTypes() {-->
+<!--      let payload = {-->
+<!--        codeType: 'type',-->
+<!--        isEnablePaging: false-->
+<!--      };-->
+<!--      // 调用后台接口获取产品类型列表-->
+<!--      getProductType(payload).then(response => {-->
+<!--        this.productTypes = response.rows;-->
+<!--        if (this.productTypes.length > 0) {-->
+<!--          this.selectedProductType = this.productTypes[0].codeName;-->
+<!--          this.fetchData(); // 获取默认产品类型的数据并更新图表-->
+<!--        }-->
+<!--      });-->
+<!--    },-->
+<!--    onTypeChange() {-->
+<!--      this.selectedDate = '';-->
+<!--      this.chart.clear();-->
+<!--    },-->
+<!--    fetchData() {-->
+<!--      let timeParam;-->
+<!--      if (this.selectedType === 'years') {-->
+<!--        timeParam = this.selectedDate.getFullYear();-->
+<!--      } else if (this.selectedType === 'months') {-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2); // 获取月份并补零-->
+<!--        timeParam = `${year}-${month}`;-->
+<!--      } else if (this.selectedType === 'days') {-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2);-->
+<!--        const day = ('0' + this.selectedDate.getDate()).slice(-2); // 获取日期并补零-->
+<!--        timeParam = `${year}-${month}-${day}`;-->
+<!--      } else if (this.selectedType === 'quarters') {-->
+<!--        const month = this.selectedDate.getMonth();-->
+<!--        // 计算季度,可以通过除以3并向上取整得到-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const quarters = Math.ceil((month + 1) / 3);-->
+<!--        timeParam = `${year}-${quarters}`;-->
+<!--      }-->
+<!--      if (!this.selectedProductType) return;-->
+<!--      let payload = {-->
+<!--        timeType: this.selectedType,-->
+<!--        timeParam: timeParam,-->
+<!--        productType: this.selectedProductType-->
+<!--      };-->
+
+<!--      mostItemsSold(payload).then(response => {-->
+<!--        // 假设从后端获取到的数据结构与初始数据结构相同-->
+<!--        this.chartData = response.data.sort((a, b) => a.weight - b.weight); // 按weight排序-->
+<!--        this.updateChart();-->
+<!--      })-->
+<!--    },-->
+<!--    initChart() {-->
+<!--      const option = {-->
+<!--        title: {-->
+<!--          text: '销售排行',-->
+<!--          left: 'center'-->
+<!--        },-->
+<!--        tooltip: {-->
+<!--          trigger: 'axis',-->
+<!--          axisPointer: {-->
+<!--            type: 'shadow'-->
+<!--          },-->
+<!--          formatter: (params) => {-->
+<!--            const item = this.chartData[params[0].dataIndex];-->
+<!--            return `${item.productName}<br/>重量: ${item.weight}<br/>色号: ${item.productColour}`;-->
+<!--          }-->
+<!--        },-->
+<!--        xAxis: {-->
+<!--          type: 'value',-->
+<!--          boundaryGap: [0, 0.01]-->
+<!--        },-->
+<!--        yAxis: {-->
+<!--          type: 'category',-->
+<!--          data: this.chartData.map(item => item.productName),-->
+<!--          axisLabel: {-->
+<!--            rotate: 45, // 旋转角度,根据实际情况调整-->
+<!--            fontSize: 9, // 字体大小-->
+<!--            interval: 0, // 是否全部显示标签,可能会导致图表过密,根据情况调整-->
+<!--            overflow: 'break' // 或者其他处理溢出方式,如 'break' 自动换行-->
+<!--          }-->
+<!--        },-->
+<!--        series: [-->
+<!--          {-->
+<!--            name: '重量',-->
+<!--            type: 'bar',-->
+<!--            data: this.chartData.map(item => item.weight),-->
+<!--          }-->
+<!--        ]-->
+<!--      };-->
+<!--      this.chart.setOption(option);-->
+<!--    },-->
+<!--    updateChart() {-->
+<!--      const option = {-->
+<!--        title: {-->
+<!--          text: '销售排行',-->
+<!--          left: 'center'-->
+<!--        },-->
+<!--        tooltip: {-->
+<!--          trigger: 'axis',-->
+<!--          axisPointer: {-->
+<!--            type: 'shadow'-->
+<!--          },-->
+<!--          formatter: (params) => {-->
+<!--            const item = this.chartData[params[0].dataIndex];-->
+<!--            return `${item.productName}<br/>重量: ${item.weight}<br/>色号: ${item.productColour}`;-->
+<!--          }-->
+<!--        },-->
+<!--        xAxis: {-->
+<!--          type: 'value',-->
+<!--          boundaryGap: [0, 0.01]-->
+<!--        },-->
+<!--        yAxis: {-->
+<!--          type: 'category',-->
+<!--          data: this.chartData.map(item => item.productName),-->
+<!--          axisLabel: {-->
+<!--            rotate: 45, // 旋转角度,根据实际情况调整-->
+<!--            fontSize: 9, // 字体大小-->
+<!--            interval: 0, // 是否全部显示标签,可能会导致图表过密,根据情况调整-->
+<!--            overflow: 'break' // 或者其他处理溢出方式,如 'break' 自动换行-->
+<!--          }-->
+<!--        },-->
+<!--        series: [-->
+<!--          {-->
+<!--            name: '重量',-->
+<!--            type: 'bar',-->
+<!--            data: this.chartData.map(item => item.weight)-->
+<!--          }-->
+<!--        ]-->
+<!--      };-->
+<!--      this.chart.setOption(option);-->
+<!--    }-->
+<!--  }-->
+<!--};-->
+<!--</script>-->
+
+<!--<style scoped>-->
+<!--#barChart3 {-->
+<!--  width: 120%;-->
+<!--  height: 400px;-->
+<!--}-->
+<!--</style>-->

+ 259 - 0
zkqy-ui/src/views/orderMange/statisticalAnalysis/saleCategoryProportion.vue

@@ -0,0 +1,259 @@
+<template>
+  <div>
+    <div id="pieChart1" style="width: 480px; height: 300px;"></div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+import { productPercentage } from "@/api/statisticalAnalysis/index";
+
+export default {
+  name: 'saleCategoryProportion',
+  data() {
+    return {
+      selectedType: 'months',
+      selectedDate: new Date(),
+      chart: null,
+      productData: [],
+    };
+  },
+  mounted() {
+    this.chart = echarts.init(document.getElementById('pieChart1'));
+    this.initChart();
+    this.fetchData();
+  },
+  methods: {
+    onTypeChange() {
+      this.selectedDate = '';
+      this.chart.clear();
+    },
+    fetchData() {
+      productPercentage().then(response => {
+        this.productData = response.data.map(item => ({
+          value: item.percentage,
+          name: item.productType,
+          weight: item.weight,
+        }));
+        this.updateChart();
+      });
+    },
+    initChart() {
+      const option = {
+        title: {
+          text: '销售品类占比',
+          // subtext: '已销售产品',
+          left: 'center'
+        },
+        color: ['#FD9133', '#47F6A2', '#37D2D4', '#3493FF'],
+        tooltip: {
+          trigger: 'item',
+          formatter: params => {
+            return `${params.seriesName}: ${params.name}<br/>占比:${params.percent}%<br/>重量: ${params.data.weight}`;
+          }
+        },
+        legend: {
+          itemWidth: 20,// 标志图形的长度
+          itemHeight: 10,// 标志图形的宽度
+          orient: 'vertical',
+          // left: 'left',
+          top: '20%',
+          bottom: '50%',
+          x: '5%',
+          textStyle: {
+            color: '#000000',
+            fontSize: 12,
+
+          },
+          data: this.productData.map(item => item.name),
+        },
+        series: [
+          {
+            name: '产品类型',
+            type: 'pie',
+            radius: ['50%', '30%'],
+            center: ['50%', '52%'],
+            labelLine: {
+              normal: {
+                length: 50,
+                lineStyle: {
+                  type: 'solid',
+                  color: '#000000'
+                }
+              }
+
+            },
+            data: this.productData,
+            label: {
+              normal: {
+                formatter: '{b}: {d}%',
+                borderWidth: 0,
+                borderRadius: 4,
+                padding: [0,0],
+                height: 20,
+                fontSize: 12,
+                align: 'center',
+                color: '#000000',
+              }
+            },
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
+              }
+            }
+          },
+          {
+            color: '#0EFCFF',
+            type: 'pie',
+            radius: ['55', '56'],
+            center: ['78%', '52%'],
+            data: [100],
+            label: {
+              show: false
+            }
+          },
+          {
+            type: 'pie',
+            radius: ['25', '26'],
+            center: ['78%', '52%'],
+            data: [100],
+            label: {
+              show: false
+            }
+          }
+        ]
+      };
+      this.chart.setOption(option);
+    },
+    updateChart() {
+      const option = {
+        legend: {
+          data: this.productData.map(item => item.name),
+        },
+        series: [
+          {
+            data: this.productData,
+          }
+        ]
+      };
+      this.chart.setOption(option);
+    }
+  }
+};
+</script>
+
+<style scoped>
+#pieChart1 {
+  width: 480px;
+  height: 300px;
+}
+</style>
+
+<!--<template>-->
+<!--  <div>-->
+<!--    <div id="pieChart1" style="width: 600px; height: 400px;"></div>-->
+<!--  </div>-->
+<!--</template>-->
+
+<!--<script>-->
+<!--import * as echarts from 'echarts';-->
+<!--import { productPercentage } from "@/api/statisticalAnalysis/index";-->
+
+<!--export default {-->
+<!--  name: 'saleCategoryProportion',-->
+<!--  data() {-->
+<!--    return {-->
+<!--      selectedType: 'months',-->
+<!--      selectedDate: new Date(),-->
+<!--      chart: null,-->
+<!--      productData: [],-->
+<!--    };-->
+<!--  },-->
+<!--  mounted() {-->
+<!--    this.chart = echarts.init(document.getElementById('pieChart1'));-->
+<!--    this.initChart();-->
+<!--    this.fetchData();-->
+<!--  },-->
+<!--  methods: {-->
+<!--    onTypeChange() {-->
+<!--      this.selectedDate = '';-->
+<!--      this.chart.clear();-->
+<!--    },-->
+<!--    fetchData() {-->
+<!--      productPercentage().then(response => {-->
+<!--        this.productData = response.data.map(item => ({-->
+<!--          value: item.percentage,-->
+<!--          name: item.productType,-->
+<!--          weight: item.weight,-->
+<!--        }));-->
+<!--        this.updateChart();-->
+<!--      });-->
+<!--    },-->
+<!--    initChart() {-->
+<!--      const option = {-->
+<!--        title: {-->
+<!--          text: '销售品类占比',-->
+<!--          // subtext: '已销售产品',-->
+<!--          left: 'center'-->
+<!--        },-->
+<!--        tooltip: {-->
+<!--          trigger: 'item',-->
+<!--          formatter: params => {-->
+<!--            return `${params.seriesName}: ${params.name}<br/>占比:${params.percent}%<br/>重量: ${params.data.weight}`;-->
+<!--          }-->
+<!--        },-->
+<!--        legend: {-->
+<!--          orient: 'vertical',-->
+<!--          left: 'left',-->
+<!--          data: this.productData.map(item => item.name),-->
+<!--        },-->
+<!--        series: [-->
+<!--          {-->
+<!--            name: '产品类型',-->
+<!--            type: 'pie',-->
+<!--            radius: '55%',-->
+<!--            center: ['50%', '60%'],-->
+<!--            data: this.productData,-->
+<!--            label: {-->
+<!--              normal: {-->
+<!--                formatter: '{b}: {d}%',-->
+<!--                position: 'inside'-->
+<!--              }-->
+<!--            },-->
+<!--            emphasis: {-->
+<!--              itemStyle: {-->
+<!--                shadowBlur: 10,-->
+<!--                shadowOffsetX: 0,-->
+<!--                shadowColor: 'rgba(0, 0, 0, 0.5)'-->
+<!--              }-->
+<!--            }-->
+<!--          }-->
+<!--        ]-->
+<!--      };-->
+<!--      this.chart.setOption(option);-->
+<!--    },-->
+<!--    updateChart() {-->
+<!--      const option = {-->
+<!--        legend: {-->
+<!--          data: this.productData.map(item => item.name),-->
+<!--        },-->
+<!--        series: [-->
+<!--          {-->
+<!--            data: this.productData,-->
+<!--          }-->
+<!--        ]-->
+<!--      };-->
+<!--      this.chart.setOption(option);-->
+<!--    }-->
+<!--  }-->
+<!--};-->
+<!--</script>-->
+
+<!--<style scoped>-->
+<!--#pieChart1 {-->
+<!--  width: 100%;-->
+<!--  height: 400px;-->
+<!--}-->
+<!--</style>-->

+ 70 - 0
zkqy-ui/src/views/orderMange/statisticalAnalysis/saleIndex.vue

@@ -0,0 +1,70 @@
+<template>
+  <div style="overflow: hidden">
+    <!-- 销售统计 -->
+    <el-row>
+      <el-col :span="12">
+        <el-card class="box-card" style="margin-left: 20px;margin-top: 20px">
+          <div style="margin-left: 15px">
+            <child-component3></child-component3>
+          </div>
+        </el-card>
+      </el-col>
+
+      <!-- 按品种统计  已销售产品的单据中销售量大的产品做排行 -->
+      <el-col :span="12">
+        <el-card class="box-card" style="margin-left: 20px;margin-top: 20px;margin-right: 20px">
+          <div>
+            <child-component4></child-component4>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <el-row>
+      <!-- 客户订单排行表,排行前10名和单据总量和货品总数量 -->
+      <el-col :span="12">
+        <el-card class="box-card" style="margin-left: 20px;margin-top: 20px;padding-top: 40px;padding-bottom: 18px">
+          <div>
+            <child-component1></child-component1>
+          </div>
+        </el-card>
+      </el-col>
+      <!-- 按客户统计订单数数量和货品总量 -->
+      <el-col :span="12">
+        <el-card class="box-card" style="margin-left: 20px;margin-top: 20px;margin-right: 20px">
+          <div>
+            <child-component2></child-component2>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+
+  </div>
+</template>
+
+<script>
+import ChildComponent1 from './customerOrderRanking.vue';
+import ChildComponent2 from './customerStatistics.vue';
+import ChildComponent3 from './salesStatistics.vue';
+import ChildComponent4 from './productsSoldRanking.vue';
+
+export default {
+  name: 'customerParentComponent',
+  components: {
+    ChildComponent1,
+    ChildComponent2,
+    ChildComponent3,
+    ChildComponent4
+  }
+};
+</script>
+
+<style scoped>
+.box-card {
+  box-shadow: 10px 10px 5px #e0e0e0;
+  background-color: #fff;
+  border-radius: 10px;
+}
+
+</style>

+ 445 - 0
zkqy-ui/src/views/orderMange/statisticalAnalysis/saleOrderRanking.vue

@@ -0,0 +1,445 @@
+<template>
+  <div>
+    <el-form inline>
+      <el-form-item label="日期类型">
+        <el-select v-model="selectedType" @change="onTypeChange" placeholder="请选择" size="mini" style="width: 80px;">
+          <el-option label="日" value="days"></el-option>
+          <el-option label="月" value="months"></el-option>
+          <el-option label="季度" value="quarters"></el-option>
+          <el-option label="年" value="years"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="选择时间">
+        <el-date-picker
+          v-if="selectedType === 'days'"
+          v-model="selectedDate"
+          type="date"
+          placeholder="选择日期"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'months'"
+          v-model="selectedDate"
+          type="month"
+          placeholder="选择月份"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'quarters'"
+          v-model="selectedDate"
+          type="month"
+          placeholder="选择季度"
+          size="mini"
+          @change="fetchData"
+          :picker-options="quarterShortcuts"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'years'"
+          v-model="selectedDate"
+          type="year"
+          placeholder="选择年份"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+      </el-form-item>
+    </el-form>
+    <div id="barChart" style="width: 480px; height: 300px;"></div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+import { saleOrderRanking } from "@/api/statisticalAnalysis/index";
+
+export default {
+  name: 'SaleOrderRanking',
+  data() {
+    return {
+      selectedType: 'months',
+      selectedDate: new Date(),
+      chart: null,
+      chartData: [],
+      quarterShortcuts: {
+        shortcuts: [
+          {
+            text: '第一季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 0, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第二季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 3, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第三季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 6, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第四季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 9, 1);
+              picker.$emit('pick', start);
+            },
+          },
+        ],
+      },
+    };
+  },
+  created() {
+    this.fetchData();
+  },
+  mounted() {
+    this.chart = echarts.init(document.getElementById('barChart'));
+    this.initChart();
+  },
+  methods: {
+    onTypeChange() {
+      this.selectedDate = '';
+      this.chart.clear();
+    },
+    fetchData() {
+      let timeParam;
+      if (this.selectedType === 'years') {
+        timeParam = this.selectedDate.getFullYear();
+      } else if (this.selectedType === 'months') {
+        const year = this.selectedDate.getFullYear();
+        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2); // 获取月份并补零
+        timeParam = `${year}-${month}`;
+      } else if (this.selectedType === 'days') {
+        const year = this.selectedDate.getFullYear();
+        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2);
+        const day = ('0' + this.selectedDate.getDate()).slice(-2); // 获取日期并补零
+        timeParam = `${year}-${month}-${day}`;
+      } else if (this.selectedType === 'quarters') {
+        const month = this.selectedDate.getMonth();
+        // 计算季度,可以通过除以3并向上取整得到
+        const year = this.selectedDate.getFullYear();
+        const quarters = Math.ceil((month + 1) / 3);
+        timeParam = `${year}-${quarters}`;
+      }
+      let payload = {
+        timeType: this.selectedType,
+        timeParam: timeParam
+      };
+
+      saleOrderRanking(payload).then(response => {
+        this.chartData = response.data.sort((a, b) => a.weight - b.weight); // 按weight排序
+        this.updateChart();
+      })
+    },
+    initChart() {
+      this.updateChart();
+    },
+    updateChart() {
+      const option = {
+        title: {
+          text: '销售排行',
+          left: 'center'
+        },
+        tooltip: {
+          trigger: 'axis',
+        },
+        grid: {
+          top: '10%',
+          left: '90',
+          right: '50',
+          bottom: '10%',
+        },
+        xAxis: {
+          min: 0,
+          //max: 12000,
+          splitLine: {
+            show: false
+          },
+          axisTick: {
+            show: false
+          },
+          axisLine: {
+            show: false
+
+          },
+          axisLabel: {
+            show: false
+          }
+        },
+        yAxis: {
+          // type: 'category',
+          data: this.chartData.map(item => item.saleNo),
+          axisTick: {
+            show: false
+          },
+          axisLine: {
+            show: false
+          },
+          axisLabel: {
+            color: '#000000',
+            // rotate: 45, // 旋转角度,根据实际情况调整
+            fontSize: 10, // 字体大小
+            interval: 0, // 是否全部显示标签,可能会导致图表过密,根据情况调整
+            overflow: 'break' // 或者其他处理溢出方式,如 'break' 自动换行
+          }
+        },
+        series: [
+          {
+            name: '重量',
+            type: 'bar',
+            data: this.chartData.map(item => item.weight),
+            label: {
+              show: true,
+              zlevel: 10000,
+              position: 'right',
+              padding: 6,
+              color: '#4e84a1',
+              fontSize: 12,
+              formatter: '{c}'
+
+            },
+            itemStyle: {
+              barBorderRadius: 25,
+              color:'#3facff'
+            },
+            barWidth: '15',
+            z: 6
+          }
+        ]
+      };
+      this.chart.setOption(option);
+    }
+  }
+};
+</script>
+
+<style scoped>
+#barChart {
+  width: 480px;
+  height: 300px;
+}
+</style>
+
+<!--<template>-->
+<!--  <div>-->
+<!--    <el-form inline>-->
+<!--      <el-form-item label="选择统计类型">-->
+<!--        <el-select v-model="selectedType" @change="onTypeChange" placeholder="请选择">-->
+<!--          <el-option label="日" value="days"></el-option>-->
+<!--          <el-option label="月" value="months"></el-option>-->
+<!--          <el-option label="季度" value="quarters"></el-option>-->
+<!--          <el-option label="年" value="years"></el-option>-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="选择时间">-->
+<!--        <el-date-picker-->
+<!--          v-if="selectedType === 'days'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="date"-->
+<!--          placeholder="选择日期"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'months'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="month"-->
+<!--          placeholder="选择月份"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'quarters'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="month"-->
+<!--          placeholder="选择季度"-->
+<!--          @change="fetchData"-->
+<!--          :picker-options="quarterShortcuts"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'years'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="year"-->
+<!--          placeholder="选择年份"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--      </el-form-item>-->
+<!--    </el-form>-->
+<!--    <div id="barChart" style="width: 100%; height: 400px;"></div>-->
+<!--  </div>-->
+<!--</template>-->
+
+<!--<script>-->
+<!--import * as echarts from 'echarts';-->
+<!--import { saleOrderRanking } from "@/api/statisticalAnalysis/index";-->
+
+<!--export default {-->
+<!--  name: 'SaleOrderRanking',-->
+<!--  data() {-->
+<!--    return {-->
+<!--      selectedType: 'months',-->
+<!--      selectedDate: new Date(),-->
+<!--      chart: null,-->
+<!--      chartData: [],-->
+<!--      quarterShortcuts: {-->
+<!--        shortcuts: [-->
+<!--          {-->
+<!--            text: '第一季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 0, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第二季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 3, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第三季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 6, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第四季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 9, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--        ],-->
+<!--      },-->
+<!--    };-->
+<!--  },-->
+<!--  created() {-->
+<!--    this.fetchData();-->
+<!--  },-->
+<!--  mounted() {-->
+<!--    this.chart = echarts.init(document.getElementById('barChart'));-->
+<!--    this.initChart();-->
+<!--  },-->
+<!--  methods: {-->
+<!--    onTypeChange() {-->
+<!--      this.selectedDate = '';-->
+<!--      this.chart.clear();-->
+<!--    },-->
+<!--    fetchData() {-->
+<!--      let timeParam;-->
+<!--      if (this.selectedType === 'years') {-->
+<!--        timeParam = this.selectedDate.getFullYear();-->
+<!--      } else if (this.selectedType === 'months') {-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2); // 获取月份并补零-->
+<!--        timeParam = `${year}-${month}`;-->
+<!--      } else if (this.selectedType === 'days') {-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2);-->
+<!--        const day = ('0' + this.selectedDate.getDate()).slice(-2); // 获取日期并补零-->
+<!--        timeParam = `${year}-${month}-${day}`;-->
+<!--      } else if (this.selectedType === 'quarters') {-->
+<!--        const month = this.selectedDate.getMonth();-->
+<!--        // 计算季度,可以通过除以3并向上取整得到-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const quarters = Math.ceil((month + 1) / 3);-->
+<!--        timeParam = `${year}-${quarters}`;-->
+<!--      }-->
+<!--      let payload = {-->
+<!--        timeType: this.selectedType,-->
+<!--        timeParam: timeParam-->
+<!--      };-->
+
+<!--      saleOrderRanking(payload).then(response => {-->
+<!--        this.chartData = response.data.sort((a, b) => a.weight - b.weight); // 按weight排序-->
+<!--        this.updateChart();-->
+<!--      })-->
+<!--    },-->
+<!--    initChart() {-->
+<!--      const option = {-->
+<!--        title: {-->
+<!--          text: '销售排行',-->
+<!--          left: 'center'-->
+<!--        },-->
+<!--        tooltip: {-->
+<!--          trigger: 'axis',-->
+<!--          axisPointer: {-->
+<!--            type: 'shadow'-->
+<!--          }-->
+<!--        },-->
+<!--        xAxis: {-->
+<!--          type: 'value',-->
+<!--          boundaryGap: [0, 0.01]-->
+<!--        },-->
+<!--        yAxis: {-->
+<!--          type: 'category',-->
+<!--          data: this.chartData.map(item => item.saleNo),-->
+<!--          axisLabel: {-->
+<!--            rotate: 45, // 旋转角度,根据实际情况调整-->
+<!--            fontSize: 9, // 字体大小-->
+<!--            interval: 0, // 是否全部显示标签,可能会导致图表过密,根据情况调整-->
+<!--            overflow: 'break' // 或者其他处理溢出方式,如 'break' 自动换行-->
+<!--          }-->
+<!--        },-->
+<!--        series: [-->
+<!--          {-->
+<!--            name: '重量',-->
+<!--            type: 'bar',-->
+<!--            data: this.chartData.map(item => item.weight),-->
+<!--          }-->
+<!--        ]-->
+<!--      };-->
+<!--      this.chart.setOption(option);-->
+<!--    },-->
+<!--    updateChart() {-->
+<!--      const option = {-->
+<!--        title: {-->
+<!--          text: '销售排行',-->
+<!--          left: 'center'-->
+<!--        },-->
+<!--        tooltip: {-->
+<!--          trigger: 'axis',-->
+<!--          axisPointer: {-->
+<!--            type: 'shadow'-->
+<!--          }-->
+<!--        },-->
+<!--        xAxis: {-->
+<!--          type: 'value',-->
+<!--          boundaryGap: [0, 0.01]-->
+<!--        },-->
+<!--        yAxis: {-->
+<!--          type: 'category',-->
+<!--          data: this.chartData.map(item => item.saleNo),-->
+<!--          axisLabel: {-->
+<!--            rotate: 45, // 旋转角度,根据实际情况调整-->
+<!--            fontSize: 9, // 字体大小-->
+<!--            interval: 0, // 是否全部显示标签,可能会导致图表过密,根据情况调整-->
+<!--            overflow: 'break' // 或者其他处理溢出方式,如 'break' 自动换行-->
+<!--          }-->
+<!--        },-->
+<!--        series: [-->
+<!--          {-->
+<!--            name: '重量',-->
+<!--            type: 'bar',-->
+<!--            data: this.chartData.map(item => item.weight)-->
+<!--          }-->
+<!--        ]-->
+<!--      };-->
+<!--      this.chart.setOption(option);-->
+<!--    }-->
+<!--  }-->
+<!--};-->
+<!--</script>-->
+
+<!--<style scoped>-->
+<!--#barChart {-->
+<!--  width: 120%;-->
+<!--  height: 400px;-->
+<!--}-->
+<!--</style>-->

+ 543 - 0
zkqy-ui/src/views/orderMange/statisticalAnalysis/salesStatistics.vue

@@ -0,0 +1,543 @@
+<template>
+  <div>
+    <el-form inline>
+      <el-form-item label="日期类型">
+        <el-select v-model="selectedType" @change="onTypeChange" size="mini" placeholder="请选择" style="width: 80px;">
+          <el-option label="日" value="days"></el-option>
+          <el-option label="月" value="months"></el-option>
+          <el-option label="季度" value="quarters"></el-option>
+          <el-option label="年" value="years"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="选择时间">
+        <el-date-picker
+          v-if="selectedType === 'days'"
+          v-model="selectedDate"
+          type="date"
+          placeholder="选择日期"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'months'"
+          v-model="selectedDate"
+          type="month"
+          placeholder="选择月份"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'quarters'"
+          v-model="selectedDate"
+          type="month"
+          placeholder="选择季度"
+          size="mini"
+          @change="fetchData"
+          :picker-options="quarterShortcuts"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'years'"
+          v-model="selectedDate"
+          type="year"
+          placeholder="选择年份"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+      </el-form-item>
+    </el-form>
+    <div id="customerOrderChart1" style="width: 730px; height: 300px;"></div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+import { saleOrderCountBySalesman } from "@/api/statisticalAnalysis/index";
+
+export default {
+  name: 'salesStatistics',
+  data() {
+    return {
+      selectedType: 'months',
+      selectedDate: new Date(),
+      chart: null,
+      customerNames: [],
+      orderCounts: [],
+      productWeights: [],
+      quarterShortcuts: {
+        shortcuts: [
+          {
+            text: '第一季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 0, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第二季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 3, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第三季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 6, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第四季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 9, 1);
+              picker.$emit('pick', start);
+            },
+          },
+        ],
+      },
+    };
+  },
+  mounted() {
+    this.chart = echarts.init(document.getElementById('customerOrderChart1'));
+    this.fetchData();
+  },
+  methods: {
+    onTypeChange() {
+      this.selectedDate = '';
+      this.chart.clear();
+    },
+    fetchData() {
+      let timeParam;
+      if (this.selectedType === 'years') {
+        timeParam = this.selectedDate.getFullYear();
+      } else if (this.selectedType === 'months') {
+        const year = this.selectedDate.getFullYear();
+        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2); // 获取月份并补零
+        timeParam = `${year}-${month}`;
+      } else if (this.selectedType === 'days') {
+        const year = this.selectedDate.getFullYear();
+        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2);
+        const day = ('0' + this.selectedDate.getDate()).slice(-2); // 获取日期并补零
+        timeParam = `${year}-${month}-${day}`;
+      } else if (this.selectedType === 'quarters') {
+        const month = this.selectedDate.getMonth();
+        // 计算季度,可以通过除以3并向上取整得到
+        const year = this.selectedDate.getFullYear();
+        const quarters = Math.ceil((month + 1) / 3);
+        timeParam = `${year}-${quarters}`;
+      }
+      let payload = {
+        timeType: this.selectedType,
+        timeParam: timeParam
+      };
+      saleOrderCountBySalesman(payload).then(response => {
+        const data = response.data;
+        this.customerNames = data.map(item => item.salesman || "Admin");
+        this.orderCounts = data.map(item => item.orderCount);
+        this.productWeights = data.map(item => item.weight);
+        this.updateChart();
+      });
+    },
+    updateChart() {
+      const option = {
+        title: {
+          text: '销售统计',
+          left: 'center'
+        },
+        tooltip: {
+          show: true,
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          }
+        },
+        legend: {
+          data: ['单据总量', '货品总数量'],
+          top: '10%'
+        },
+
+        grid: {
+          left: 15,
+          top: 50,
+          right: 15,
+          bottom: 20,
+          containLabel: true
+        },
+        xAxis: [
+          {
+            type: 'category',
+            boundaryGap: true,
+            data: this.customerNames,
+            axisLine: {
+              //坐标轴轴线相关设置。数学上的x轴
+              show: true,
+              lineStyle: {
+                color: "#000000",
+              },
+            },
+            axisLabel: {
+              interval: 0,
+              color: "#000000",
+              rotate: 45,
+              fontSize: 12,
+            },
+            axisTick: {
+              show: false,
+            },
+
+
+            // axisLabel: {
+            //   interval: 0, // 强制显示所有标签
+            //   rotate: 45 // 旋转角度
+            // }
+          }
+        ],
+        yAxis: [
+          {
+            type: 'value',
+            name: '单据总量',
+            position: 'left'
+          },
+          {
+            type: 'value',
+            name: '货品总数量',
+            position: 'right'
+          },
+          {
+            type: "value",
+            splitLine: {
+              show: true,
+              lineStyle: {
+                color: "#0a3256",
+              },
+            },
+            axisLine: {
+              show: false,
+            },
+            axisLabel: {
+              margin: 20,
+              textStyle: {
+                color: "#d1e6eb",
+              },
+            },
+            axisTick: {
+              show: false,
+            },
+          },
+        ],
+        series: [
+          {
+            name: '单据总量',
+            type: 'bar',
+            data: this.orderCounts,
+            // label: {
+            //   show: true,
+            //   position: 'inside'
+            // }
+            label: {
+              show: true,
+              position: "top",
+              formatter: function(param) {
+                return param.value;
+              },
+              textStyle: {
+                color: "#000000",
+              },
+            },
+            barWidth: 12,
+            itemStyle: {
+              color: new echarts.graphic.LinearGradient(0, 0, 1, 1, [{
+                offset: 0,
+                color: "#00FFE3",
+              },
+                {
+                  offset: 1,
+                  color: "#4693EC",
+                },
+              ]),
+              barBorderRadius: [30, 30, 30, 30],
+            }
+          },
+          {
+            name: '货品总数量',
+            type: 'line',
+            yAxisIndex: 1,
+            data: this.productWeights,
+            showAllSymbol: true,
+            symbol: "emptyCircle",
+            symbolSize: 6,
+            lineStyle: {
+              normal: {
+                color: "#28ffb3", // 线条颜色
+              },
+              borderColor: "#f0f",
+            },
+            label: {
+              show: true,
+              position: "top",
+              textStyle: {
+                color: "#000000",
+              },
+            },
+            itemStyle: {
+              normal: {
+                color: "#28ffb3",
+              },
+            },
+            areaStyle: {
+              //区域填充样式
+              normal: {
+                //线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
+                color: new echarts.graphic.LinearGradient(
+                  0,
+                  0,
+                  0,
+                  1,
+                  [{
+                    offset: 0,
+                    color: "rgba(0,154,120,1)",
+                  },
+                    {
+                      offset: 1,
+                      color: "rgba(0,0,0, 0)",
+                    },
+                  ],
+                  false
+                ),
+                shadowColor: "rgba(53,142,215, 0.9)", //阴影颜色
+                shadowBlur: 20, //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
+              },
+            }
+            // label: {
+            //   show: true,
+            //   position: 'top'
+            // }
+          }
+        ]
+      };
+      this.chart.setOption(option);
+    }
+  }
+};
+</script>
+
+<style scoped>
+#customerOrderChart1 {
+  width: 730px;
+  height: 300px;
+}
+</style>
+
+
+<!--<template>-->
+<!--  <div>-->
+<!--    <el-form inline>-->
+<!--      <el-form-item label="选择统计类型">-->
+<!--        <el-select v-model="selectedType" @change="onTypeChange" placeholder="请选择">-->
+<!--          <el-option label="日" value="days"></el-option>-->
+<!--          <el-option label="月" value="months"></el-option>-->
+<!--          <el-option label="季度" value="quarters"></el-option>-->
+<!--          <el-option label="年" value="years"></el-option>-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="选择时间">-->
+<!--        <el-date-picker-->
+<!--          v-if="selectedType === 'days'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="date"-->
+<!--          placeholder="选择日期"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'months'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="month"-->
+<!--          placeholder="选择月份"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'quarters'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="month"-->
+<!--          placeholder="选择季度"-->
+<!--          @change="fetchData"-->
+<!--          :picker-options="quarterShortcuts"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'years'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="year"-->
+<!--          placeholder="选择年份"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--      </el-form-item>-->
+<!--    </el-form>-->
+<!--    <div id="customerOrderChart1" style="width: 100%; height: 400px;"></div>-->
+<!--  </div>-->
+<!--</template>-->
+
+<!--<script>-->
+<!--import * as echarts from 'echarts';-->
+<!--import { saleOrderCountBySalesman } from "@/api/statisticalAnalysis/index";-->
+
+<!--export default {-->
+<!--  name: 'salesStatistics',-->
+<!--  data() {-->
+<!--    return {-->
+<!--      selectedType: 'months',-->
+<!--      selectedDate: new Date(),-->
+<!--      chart: null,-->
+<!--      customerNames: [],-->
+<!--      orderCounts: [],-->
+<!--      productWeights: [],-->
+<!--      quarterShortcuts: {-->
+<!--        shortcuts: [-->
+<!--          {-->
+<!--            text: '第一季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 0, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第二季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 3, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第三季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 6, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第四季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 9, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--        ],-->
+<!--      },-->
+<!--    };-->
+<!--  },-->
+<!--  mounted() {-->
+<!--    this.chart = echarts.init(document.getElementById('customerOrderChart1'));-->
+<!--    this.fetchData();-->
+<!--  },-->
+<!--  methods: {-->
+<!--    onTypeChange() {-->
+<!--      this.selectedDate = '';-->
+<!--      this.chart.clear();-->
+<!--    },-->
+<!--    fetchData() {-->
+<!--      let timeParam;-->
+<!--      if (this.selectedType === 'years') {-->
+<!--        timeParam = this.selectedDate.getFullYear();-->
+<!--      } else if (this.selectedType === 'months') {-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2); // 获取月份并补零-->
+<!--        timeParam = `${year}-${month}`;-->
+<!--      } else if (this.selectedType === 'days') {-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2);-->
+<!--        const day = ('0' + this.selectedDate.getDate()).slice(-2); // 获取日期并补零-->
+<!--        timeParam = `${year}-${month}-${day}`;-->
+<!--      } else if (this.selectedType === 'quarters') {-->
+<!--        const month = this.selectedDate.getMonth();-->
+<!--        // 计算季度,可以通过除以3并向上取整得到-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const quarters = Math.ceil((month + 1) / 3);-->
+<!--        timeParam = `${year}-${quarters}`;-->
+<!--      }-->
+<!--      let payload = {-->
+<!--        timeType: this.selectedType,-->
+<!--        timeParam: timeParam-->
+<!--      };-->
+<!--      saleOrderCountBySalesman(payload).then(response => {-->
+<!--        const data = response.data;-->
+<!--        this.customerNames = data.map(item => item.salesman || "Admin");-->
+<!--        this.orderCounts = data.map(item => item.orderCount);-->
+<!--        this.productWeights = data.map(item => item.weight);-->
+<!--        this.updateChart();-->
+<!--      });-->
+<!--    },-->
+<!--    updateChart() {-->
+<!--      const option = {-->
+<!--        title: {-->
+<!--          text: '销售统计',-->
+<!--          left: 'center'-->
+<!--        },-->
+<!--        tooltip: {-->
+<!--          trigger: 'axis',-->
+<!--          axisPointer: {-->
+<!--            type: 'shadow'-->
+<!--          }-->
+<!--        },-->
+<!--        legend: {-->
+<!--          data: ['单据总量', '货品总数量'],-->
+<!--          top: '10%'-->
+<!--        },-->
+<!--        grid: {-->
+<!--          left: '3%',-->
+<!--          right: '4%',-->
+<!--          bottom: '3%',-->
+<!--          containLabel: true-->
+<!--        },-->
+<!--        xAxis: {-->
+<!--          type: 'category',-->
+<!--          data: this.customerNames,-->
+<!--          axisLabel: {-->
+<!--            interval: 0, // 强制显示所有标签-->
+<!--            rotate: 45 // 旋转角度-->
+<!--          }-->
+<!--        },-->
+<!--        yAxis: [-->
+<!--          {-->
+<!--            type: 'value',-->
+<!--            name: '单据总量',-->
+<!--            position: 'left'-->
+<!--          },-->
+<!--          {-->
+<!--            type: 'value',-->
+<!--            name: '货品总数量',-->
+<!--            position: 'right'-->
+<!--          }-->
+<!--        ],-->
+<!--        series: [-->
+<!--          {-->
+<!--            name: '单据总量',-->
+<!--            type: 'bar',-->
+<!--            data: this.orderCounts,-->
+<!--            label: {-->
+<!--              show: true,-->
+<!--              position: 'inside'-->
+<!--            }-->
+<!--          },-->
+<!--          {-->
+<!--            name: '货品总数量',-->
+<!--            type: 'line',-->
+<!--            yAxisIndex: 1,-->
+<!--            data: this.productWeights,-->
+<!--            label: {-->
+<!--              show: true,-->
+<!--              position: 'top'-->
+<!--            }-->
+<!--          }-->
+<!--        ]-->
+<!--      };-->
+<!--      this.chart.setOption(option);-->
+<!--    }-->
+<!--  }-->
+<!--};-->
+<!--</script>-->
+
+<!--<style scoped>-->
+<!--#customerOrderChart1 {-->
+<!--  width: 100%;-->
+<!--  height: 400px;-->
+<!--}-->
+<!--</style>-->

+ 773 - 0
zkqy-ui/src/views/orderMange/statisticalAnalysis/yield.vue

@@ -0,0 +1,773 @@
+<template>
+  <div>
+    <!-- 表单容器 -->
+    <el-form inline>
+      <el-form-item label="日期类型">
+        <el-select v-model="selectedType" @change="onTypeChange" placeholder="请选择" size="mini" style="width: 80px;">
+          <el-option label="日" value="days"></el-option>
+          <el-option label="月" value="months"></el-option>
+          <el-option label="季度" value="quarters"></el-option>
+          <el-option label="年" value="years"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="选择时间">
+        <el-date-picker
+          v-if="selectedType === 'days'"
+          v-model="selectedDate"
+          type="date"
+          placeholder="选择日期"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'months'"
+          v-model="selectedDate"
+          type="month"
+          placeholder="选择月份"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'quarters'"
+          v-model="selectedDate"
+          type="month"
+          placeholder="选择季度"
+          size="mini"
+          @change="fetchData"
+          :picker-options="quarterShortcuts"
+        ></el-date-picker>
+        <el-date-picker
+          v-else-if="selectedType === 'years'"
+          v-model="selectedDate"
+          type="year"
+          placeholder="选择年份"
+          size="mini"
+          @change="fetchData"
+        ></el-date-picker>
+      </el-form-item>
+    </el-form>
+
+    <!-- 图表容器 -->
+    <div id="main" style="width: 480px; height: 300px;"></div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+import 'element-ui/lib/theme-chalk/index.css';
+import { productionStatistics } from "@/api/statisticalAnalysis/index";
+
+export default {
+  name: 'yield',
+  data() {
+    return {
+      selectedType: 'months',
+      selectedDate: new Date(),
+      chart: null,
+      chartData: {},
+      quarterShortcuts: {
+        shortcuts: [
+          {
+            text: '第一季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 0, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第二季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 3, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第三季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 6, 1);
+              picker.$emit('pick', start);
+            },
+          },
+          {
+            text: '第四季度',
+            onClick(picker) {
+              const start = new Date(new Date().getFullYear(), 9, 1);
+              picker.$emit('pick', start);
+            },
+          },
+        ],
+      },
+    };
+  },
+  mounted() {
+    this.chart = echarts.init(document.getElementById('main'));
+    this.fetchData();
+  },
+  created() {
+    this.fetchData();
+  },
+  methods: {
+    onTypeChange() {
+      this.selectedDate = '';
+      this.chart.clear();
+    },
+    fetchData() {
+      // 模拟从后端获取数据
+      // 实际上应根据selectedType和selectedDate发送请求到后端获取数据
+      let timeParam;
+      if (this.selectedType === 'years') {
+        timeParam = this.selectedDate.getFullYear();
+      } else if (this.selectedType === 'months') {
+        const year = this.selectedDate.getFullYear();
+        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2); // 获取月份并补零
+        timeParam = `${year}-${month}`;
+      } else if (this.selectedType === 'days') {
+        const year = this.selectedDate.getFullYear();
+        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2);
+        const day = ('0' + this.selectedDate.getDate()).slice(-2); // 获取日期并补零
+        timeParam = `${year}-${month}-${day}`;
+      } else if (this.selectedType === 'quarters') {
+        const month = this.selectedDate.getMonth();
+        // 计算季度,可以通过除以3并向上取整得到
+        const year = this.selectedDate.getFullYear();
+        const quarters = Math.ceil((month + 1) / 3);
+        timeParam = `${year}-${quarters}`;
+      }
+      let payload = {
+        timeType: this.selectedType,
+        timeParam: timeParam
+      };
+
+      productionStatistics(payload).then(response => {
+        this.chartData = response.data;
+        this.updateChart();
+      });
+
+    },
+    initChart() {
+      this.updateChart();
+    },
+    updateChart() {
+      // 使用柱状图的配置项
+      const option = {
+        title: {
+          text: '产量统计',
+          left: 'center',
+          top: 'top'
+        },
+        tooltip: {
+          show: true,
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          },
+          formatter: (params) => {
+            const item = this.chartData.output[params[0].dataIndex];
+            return `${item.name}<br/>重量: ${item.data}<br/>色号: ${item.productColour}`;
+          }
+        },
+        grid: {
+          left: 15,
+          top: 20,
+          right: 15,
+          bottom: 0,
+          containLabel: true
+        },
+        xAxis: [{
+          data: this.chartData.output.map(item => item.name),
+          //坐标轴
+          axisLine: {
+            lineStyle: {
+              color: "#3eb2e8",
+            },
+          },
+          //坐标值标注
+          axisLabel: {
+            show: true,
+            fontSize: 10,
+            interval: 0, // 强制显示所有标签
+            rotate: 45, // 旋转角度
+            textStyle: {
+              color: "#000000",
+            },
+          },
+        }],
+        yAxis: {
+          //坐标轴
+          axisLine: {
+            show: false,
+          },
+          //坐标值标注
+          axisLabel: {
+            show: true,
+            textStyle: {
+              color: "#000000",
+            },
+          },
+          //分格线
+          splitLine: {
+            lineStyle: {
+              color: "#4784e8",
+            },
+          },
+        },
+        series: [
+          {
+            name: '重量',
+            tooltip: {
+              show: true,
+            },
+            type: 'bar',
+            barWidth: 24.5,
+            data: this.chartData.output.map(item => item.data),
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(
+                  0,
+                  1,
+                  0,
+                  0,
+                  [
+                    {
+                      offset: 0,
+                      color: "#0B4EC3", // 0% 处的颜色
+                    },
+                    {
+                      offset: 0.6,
+                      color: "#138CEB", // 60% 处的颜色
+                    },
+                    {
+                      offset: 1,
+                      color: "#17AAFE", // 100% 处的颜色
+                    },
+                  ],
+                  false
+                ),
+              },
+            },
+            barGap: 0,
+          },
+          {
+            type: "bar",
+            barWidth: 8,
+            itemStyle: {
+              normal: {
+                color: new echarts.graphic.LinearGradient(
+                  0,
+                  1,
+                  0,
+                  0,
+                  [
+                    {
+                      offset: 0,
+                      color: "#09337C", // 0% 处的颜色
+                    },
+                    {
+                      offset: 0.6,
+                      color: "#0761C0", // 60% 处的颜色
+                    },
+                    {
+                      offset: 1,
+                      color: "#0575DE", // 100% 处的颜色
+                    },
+                  ],
+                  false
+                ),
+              },
+            },
+            barGap: 0,
+            data: this.chartData.output.map(item => item.data),
+          },
+          {
+            name: "b",
+            tooltip: {
+              show: false,
+            },
+            type: "pictorialBar",
+            itemStyle: {
+              borderWidth: 1,
+              borderColor: "#0571D5",
+              color: "#1779E0",
+            },
+            symbol: "path://M 0,0 l 120,0 l -30,60 l -120,0 z",
+            symbolSize: ["33", "8"],
+            symbolOffset: ["0", "-5"],
+            //symbolRotate: -5,
+            symbolPosition: "end",
+            data: this.chartData.output.map(item => item.data),
+            z: 3,
+          },
+        ]
+      };
+      this.chart.setOption(option);
+    }
+  }
+};
+</script>
+
+<style scoped>
+#main {
+  width: 480px;
+  height: 300px;
+}
+</style>
+
+
+
+<!--<template>-->
+<!--  <div>-->
+<!--    &lt;!&ndash; 表单容器 &ndash;&gt;-->
+<!--    <el-form inline>-->
+<!--      <el-form-item label="选择统计类型">-->
+<!--        <el-select v-model="selectedType" @change="onTypeChange" placeholder="请选择">-->
+<!--          <el-option label="日" value="days"></el-option>-->
+<!--          <el-option label="月" value="months"></el-option>-->
+<!--          <el-option label="季度" value="quarters"></el-option>-->
+<!--          <el-option label="年" value="years"></el-option>-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="选择时间">-->
+<!--        <el-date-picker-->
+<!--          v-if="selectedType === 'days'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="date"-->
+<!--          placeholder="选择日期"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'months'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="month"-->
+<!--          placeholder="选择月份"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'quarters'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="month"-->
+<!--          placeholder="选择季度"-->
+<!--          @change="fetchData"-->
+<!--          :picker-options="quarterShortcuts"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'years'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="year"-->
+<!--          placeholder="选择年份"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--      </el-form-item>-->
+<!--    </el-form>-->
+
+<!--    &lt;!&ndash; 图表容器 &ndash;&gt;-->
+<!--    <div id="main" style="width: 600px; height: 400px;"></div>-->
+<!--  </div>-->
+<!--</template>-->
+
+<!--<script>-->
+<!--import * as echarts from 'echarts';-->
+<!--import 'element-ui/lib/theme-chalk/index.css';-->
+<!--import { productionStatistics } from "@/api/statisticalAnalysis/index";-->
+
+<!--export default {-->
+<!--  name: 'yield',-->
+<!--  data() {-->
+<!--    return {-->
+<!--      selectedType: 'months',-->
+<!--      selectedDate: new Date(),-->
+<!--      chart: null,-->
+<!--      chartData: {},-->
+<!--      quarterShortcuts: {-->
+<!--        shortcuts: [-->
+<!--          {-->
+<!--            text: '第一季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 0, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第二季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 3, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第三季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 6, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第四季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 9, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--        ],-->
+<!--      },-->
+<!--    };-->
+<!--  },-->
+<!--  mounted() {-->
+<!--    this.chart = echarts.init(document.getElementById('main'));-->
+<!--    this.fetchData();-->
+<!--  },-->
+<!--  created() {-->
+<!--    this.fetchData();-->
+<!--  },-->
+<!--  methods: {-->
+<!--    onTypeChange() {-->
+<!--      this.selectedDate = '';-->
+<!--      this.chart.clear();-->
+<!--    },-->
+<!--    fetchData() {-->
+<!--      // 模拟从后端获取数据-->
+<!--      // 实际上应根据selectedType和selectedDate发送请求到后端获取数据-->
+<!--      let timeParam;-->
+<!--      if (this.selectedType === 'years') {-->
+<!--        timeParam = this.selectedDate.getFullYear();-->
+<!--      } else if (this.selectedType === 'months') {-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2); // 获取月份并补零-->
+<!--        timeParam = `${year}-${month}`;-->
+<!--      } else if (this.selectedType === 'days') {-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2);-->
+<!--        const day = ('0' + this.selectedDate.getDate()).slice(-2); // 获取日期并补零-->
+<!--        timeParam = `${year}-${month}-${day}`;-->
+<!--      } else if (this.selectedType === 'quarters') {-->
+<!--        const month = this.selectedDate.getMonth();-->
+<!--        // 计算季度,可以通过除以3并向上取整得到-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const quarters = Math.ceil((month + 1) / 3);-->
+<!--        timeParam = `${year}-${quarters}`;-->
+<!--      }-->
+<!--      let payload = {-->
+<!--        timeType: this.selectedType,-->
+<!--        timeParam: timeParam-->
+<!--      };-->
+
+<!--      productionStatistics(payload).then(response => {-->
+<!--        this.chartData = response.data;-->
+<!--        this.updateChart();-->
+<!--      });-->
+
+<!--    },-->
+<!--    initChart() {-->
+<!--      this.updateChart();-->
+<!--    },-->
+<!--    updateChart() {-->
+<!--      // 使用柱状图的配置项-->
+<!--      const option = {-->
+<!--        color: ['#1aa1ff', '#31c17b', '#ff6535'],-->
+<!--        title: {-->
+<!--          text: '产量统计',-->
+<!--          // subtext: 'Fake Data',-->
+<!--          left: 'center',-->
+<!--          textStyle: { // 添加 textStyle 属性-->
+<!--            backgroundColor: 'transparent', // 设置背景颜色为透明-->
+<!--            borderColor: 'transparent' // 设置边框颜色为透明-->
+<!--          }-->
+<!--        },-->
+<!--        tooltip: {-->
+<!--          trigger: 'axis',-->
+<!--          axisPointer: {-->
+<!--            type: 'shadow'-->
+<!--          },-->
+<!--          formatter: (params) => {-->
+<!--            const item = this.chartData.output[params[0].dataIndex];-->
+<!--            return `${item.name}<br/>重量: ${item.data}<br/>色号: ${item.productColour}`;-->
+<!--          }-->
+<!--        },-->
+<!--        grid: {-->
+<!--          left: '0%',-->
+<!--          top:'15px',-->
+<!--          right: '0%',-->
+<!--          bottom: '3%',-->
+<!--          containLabel: true-->
+<!--        },-->
+<!--        // legend: {-->
+<!--        //   data: ['产量']-->
+<!--        // },-->
+<!--        xAxis: {-->
+<!--          type: 'category',-->
+<!--          data: this.chartData.output.map(item => item.name),-->
+<!--          axisLine: {show:false,},-->
+<!--          axisLabel: {-->
+<!--            color: '#000000',-->
+<!--            fontSize: 12,-->
+<!--            interval: 0, // 强制显示所有标签-->
+<!--            rotate: 45 // 旋转角度-->
+<!--          }-->
+<!--        },-->
+<!--        yAxis: {-->
+<!--          type: 'value',-->
+<!--          name: "(人)",-->
+<!--          splitNumber:4,-->
+<!--          nameTextStyle: {-->
+<!--            color: '#000000',-->
+<!--            fontSize: 12-->
+<!--          },-->
+<!--          axisLine: { show:false, },-->
+<!--          axisLabel: {-->
+<!--            color: '#000000',-->
+<!--            fontSize: 12-->
+<!--          },-->
+<!--          splitLine: {-->
+<!--            lineStyle: {-->
+<!--              color: "#595B5D",-->
+<!--              type: "dotted"-->
+<!--            }-->
+<!--          },-->
+<!--        },-->
+<!--        series: [-->
+<!--          {-->
+<!--            name: '产量',-->
+<!--            type: 'bar',-->
+<!--            barWidth: '25%',-->
+<!--            itemStyle: {-->
+
+<!--              normal: {-->
+<!--                barBorderRadius: 50,-->
+<!--                color: function(params) {-->
+<!--                  const colorList = ['#4591e3', '#04b8e5', '#04dde5', '#04e5bd',-->
+<!--                    '#04e57e', '#fedb5b', '#e59e04', '#ff632d', '#ff639e',-->
+<!--                    '#ff82e9', '#b562e4'-->
+<!--                  ];-->
+
+<!--                  return colorList[params.dataIndex]-->
+
+<!--                },-->
+
+<!--                label: {-->
+
+<!--                  show: true,-->
+<!--                  position: 'top',-->
+<!--                  formatter: '{c}',-->
+<!--                  color: 'rgba(255,255,255,.4)',-->
+<!--                  fontSize: 12-->
+<!--                }-->
+
+<!--              }-->
+
+<!--            },-->
+<!--            data: this.chartData.output.map(item => item.data)-->
+<!--          }-->
+<!--        ]-->
+<!--      };-->
+<!--      this.chart.setOption(option);-->
+<!--    }-->
+<!--  }-->
+<!--};-->
+<!--</script>-->
+
+<!--<style scoped>-->
+<!--#main {-->
+<!--  width: 100%;-->
+<!--  height: 400px;-->
+<!--}-->
+<!--</style>-->
+
+
+<!--<template>-->
+<!--  <div>-->
+<!--    &lt;!&ndash; 表单容器 &ndash;&gt;-->
+<!--    <el-form inline>-->
+<!--      <el-form-item label="选择统计类型">-->
+<!--        <el-select v-model="selectedType" @change="onTypeChange" placeholder="请选择">-->
+<!--          <el-option label="日" value="days"></el-option>-->
+<!--          <el-option label="月" value="months"></el-option>-->
+<!--          <el-option label="季度" value="quarters"></el-option>-->
+<!--          <el-option label="年" value="years"></el-option>-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+<!--      <el-form-item label="选择时间">-->
+<!--        <el-date-picker-->
+<!--          v-if="selectedType === 'days'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="date"-->
+<!--          placeholder="选择日期"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'months'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="month"-->
+<!--          placeholder="选择月份"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'quarters'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="month"-->
+<!--          placeholder="选择季度"-->
+<!--          @change="fetchData"-->
+<!--          :picker-options="quarterShortcuts"-->
+<!--        ></el-date-picker>-->
+<!--        <el-date-picker-->
+<!--          v-else-if="selectedType === 'years'"-->
+<!--          v-model="selectedDate"-->
+<!--          type="year"-->
+<!--          placeholder="选择年份"-->
+<!--          @change="fetchData"-->
+<!--        ></el-date-picker>-->
+<!--      </el-form-item>-->
+<!--    </el-form>-->
+
+<!--    &lt;!&ndash; 图表容器 &ndash;&gt;-->
+<!--    <div id="main" style="width: 600px; height: 400px;"></div>-->
+<!--  </div>-->
+<!--</template>-->
+
+<!--<script>-->
+<!--import * as echarts from 'echarts';-->
+<!--import 'element-ui/lib/theme-chalk/index.css';-->
+<!--import { productionStatistics } from "@/api/statisticalAnalysis/index";-->
+
+<!--export default {-->
+<!--  name: 'yield',-->
+<!--  data() {-->
+<!--    return {-->
+<!--      selectedType: 'months',-->
+<!--      selectedDate: new Date(),-->
+<!--      chart: null,-->
+<!--      chartData: {},-->
+<!--      quarterShortcuts: {-->
+<!--        shortcuts: [-->
+<!--          {-->
+<!--            text: '第一季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 0, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第二季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 3, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第三季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 6, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--          {-->
+<!--            text: '第四季度',-->
+<!--            onClick(picker) {-->
+<!--              const start = new Date(new Date().getFullYear(), 9, 1);-->
+<!--              picker.$emit('pick', start);-->
+<!--            },-->
+<!--          },-->
+<!--        ],-->
+<!--      },-->
+<!--    };-->
+<!--  },-->
+<!--  mounted() {-->
+<!--    this.chart = echarts.init(document.getElementById('main'));-->
+<!--    this.fetchData();-->
+<!--  },-->
+<!--  created() {-->
+<!--    this.fetchData();-->
+<!--  },-->
+<!--  methods: {-->
+<!--    onTypeChange() {-->
+<!--      this.selectedDate = '';-->
+<!--      this.chart.clear();-->
+<!--    },-->
+<!--    fetchData() {-->
+<!--      // 模拟从后端获取数据-->
+<!--      // 实际上应根据selectedType和selectedDate发送请求到后端获取数据-->
+<!--      let timeParam;-->
+<!--      if (this.selectedType === 'years') {-->
+<!--        timeParam = this.selectedDate.getFullYear();-->
+<!--      } else if (this.selectedType === 'months') {-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2); // 获取月份并补零-->
+<!--        timeParam = `${year}-${month}`;-->
+<!--      } else if (this.selectedType === 'days') {-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const month = ('0' + (this.selectedDate.getMonth() + 1)).slice(-2);-->
+<!--        const day = ('0' + this.selectedDate.getDate()).slice(-2); // 获取日期并补零-->
+<!--        timeParam = `${year}-${month}-${day}`;-->
+<!--      } else if (this.selectedType === 'quarters') {-->
+<!--        const month = this.selectedDate.getMonth();-->
+<!--        // 计算季度,可以通过除以3并向上取整得到-->
+<!--        const year = this.selectedDate.getFullYear();-->
+<!--        const quarters = Math.ceil((month + 1) / 3);-->
+<!--        timeParam = `${year}-${quarters}`;-->
+<!--      }-->
+<!--      let payload = {-->
+<!--        timeType: this.selectedType,-->
+<!--        timeParam: timeParam-->
+<!--      };-->
+
+<!--      productionStatistics(payload).then(response => {-->
+<!--        this.chartData = response.data;-->
+<!--        this.updateChart();-->
+<!--      });-->
+
+<!--    },-->
+<!--    initChart() {-->
+<!--      this.updateChart();-->
+<!--    },-->
+<!--    updateChart() {-->
+<!--      // 使用柱状图的配置项-->
+<!--      const option = {-->
+<!--        title: {-->
+<!--          text: '产量统计',-->
+<!--          // subtext: 'Fake Data',-->
+<!--          left: 'center',-->
+<!--          textStyle: { // 添加 textStyle 属性-->
+<!--            backgroundColor: 'transparent', // 设置背景颜色为透明-->
+<!--            borderColor: 'transparent' // 设置边框颜色为透明-->
+<!--          }-->
+<!--        },-->
+<!--        tooltip: {-->
+<!--          trigger: 'axis',-->
+<!--          formatter: (params) => {-->
+<!--            const item = this.chartData.output[params[0].dataIndex];-->
+<!--            return `${item.name}<br/>重量: ${item.data}<br/>色号: ${item.productColour}`;-->
+<!--          }-->
+<!--        },-->
+<!--        legend: {-->
+<!--          data: ['产量']-->
+<!--        },-->
+<!--        xAxis: {-->
+<!--          type: 'category',-->
+<!--          data: this.chartData.output.map(item => item.name),-->
+<!--          axisLabel: {-->
+<!--            interval: 0, // 强制显示所有标签-->
+<!--            rotate: 45 // 旋转角度-->
+<!--          }-->
+<!--        },-->
+<!--        yAxis: {-->
+<!--          type: 'value'-->
+<!--        },-->
+<!--        series: [-->
+<!--          {-->
+<!--            name: '产量',-->
+<!--            type: 'bar',-->
+<!--            data: this.chartData.output.map(item => item.data)-->
+<!--          }-->
+<!--        ]-->
+<!--      };-->
+<!--      this.chart.setOption(option);-->
+<!--    }-->
+<!--  }-->
+<!--};-->
+<!--</script>-->
+
+<!--<style scoped>-->
+<!--#main {-->
+<!--  width: 100%;-->
+<!--  height: 400px;-->
+<!--}-->
+<!--</style>-->
+