From bc76a082becae4e5d344ae1b193582be38761d2d Mon Sep 17 00:00:00 2001
From: skyouc
Date: 星期三, 05 三月 2025 16:47:07 +0800
Subject: [PATCH] #新增 1. 新增编规则生成功能 2. 新增PO单同步功能

---
 rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/AsnOrderController.java |    2 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Purchase.java               |    5 
 rsf-server/src/main/java/com/vincent/rsf/server/api/controller/ErpApiController.java       |   52 ++
 rsf-server/src/main/java/com/vincent/rsf/server/common/config/WebMvcConfig.java            |    2 
 rsf-server/src/main/java/com/vincent/rsf/server/api/controller/params/Order.java           |   56 ++
 rsf-server/src/main/java/com/vincent/rsf/server/api/entity/enums/OrderType.java            |   24 +
 rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ErpApiServiceImpl.java    |   72 +++
 rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java        |   13 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/MatnrController.java    |    4 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/PurchaseItem.java           |   21 
 rsf-server/src/main/java/com/vincent/rsf/server/api/controller/params/OrderItem.java       |   53 ++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/ScheduleJobs.java            |   33 +
 rsf-server/src/main/java/com/vincent/rsf/server/api/service/ErpApiService.java             |   18 
 rsf-server/src/main/java/com/vincent/rsf/server/system/entity/SerialRule.java              |   10 
 rsf-server/src/main/java/com/vincent/rsf/server/common/security/SecurityConfig.java        |    1 
 rsf-server/src/main/java/com/vincent/rsf/server/system/utils/SerialRuleUtils.java          |  140 ++++++
 rsf-server/src/main/java/com/vincent/rsf/server/api/entity/enums/OrderWorkType.java        |   29 +
 rsf-server/src/main/java/com/vincent/rsf/server/common/utils/DateUtils.java                |  726 +++++++++++++++++++++++++++++++++
 rsf-server/src/main/java/com/vincent/rsf/server/system/enums/SerialRuleReset.java          |   27 +
 rsf-server/src/main/java/com/vincent/rsf/server/system/enums/SerialRuleType.java           |   29 +
 20 files changed, 1,291 insertions(+), 26 deletions(-)

diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/ErpApiController.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/ErpApiController.java
new file mode 100644
index 0000000..e83aa51
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/ErpApiController.java
@@ -0,0 +1,52 @@
+package com.vincent.rsf.server.api.controller;
+
+import com.vincent.rsf.framework.common.R;
+import com.vincent.rsf.server.api.controller.params.Order;
+import com.vincent.rsf.server.api.service.ErpApiService;
+import com.vincent.rsf.server.system.controller.BaseController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @author Ryan
+ * @version 1.0
+ * @title ErpApiController
+ * @description
+ * @create 2025/3/4 13:19
+ */
+@RestController
+@RequestMapping("/erp")
+@Api(tags = "ERP鎺ュ彛瀵规帴")
+public class ErpApiController extends BaseController {
+
+    @Autowired
+    private ErpApiService erpApiService;
+
+    /**
+     * @author Ryan
+     * @description 鎺ユ敹ERP鎺ㄩ�佺殑PO鍗曟嵁
+     * @throws
+     * @return
+     * @time 2025/3/4 13:57
+     */
+    @ApiOperation(value = "鎺ユ敹鍚屾ERP閲囪喘鍗�")
+    @PostMapping("/sync/purchase")
+    public R syncPurchases(@RequestBody List<Order> orders) {
+        if (orders.isEmpty()) {
+            return R.error("鎺ㄩ�佽鍗曚笉鑳戒负绌猴紝璇锋鏌ユ牎楠屽悗鍐嶆搷浣滐紒锛�");
+        }
+        if (!erpApiService.syncPurchasee(orders)) {
+            return R.error("淇濆瓨澶辫触");
+        } else {
+            return R.ok("淇濆瓨鎴愬姛锛侊紒");
+        }
+    }
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/params/Order.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/params/Order.java
new file mode 100644
index 0000000..996b6ea
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/params/Order.java
@@ -0,0 +1,56 @@
+package com.vincent.rsf.server.api.controller.params;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author Ryan
+ * @version 1.0
+ * @title PurchaseOrder
+ * @description
+ * @create 2025/3/4 13:41
+ */
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "PurchaseOrder", description = "鍏ュ簱鍗曟嵁")
+public class Order implements Serializable {
+
+    @ApiModelProperty(value = "鍗曟嵁缂栫爜")
+    private String code;
+
+    @ApiModelProperty(value = "闇�姹傛暟閲�", required = true)
+    private Double anfme;
+
+    @ApiModelProperty(value = "宸叉敹璐ф暟閲�",required = true)
+    private Double qty;
+
+    @ApiModelProperty(value = "鏀惰揣涓暟閲�", required = true)
+    private Double workQty;
+
+    @ApiModelProperty(value = "璁″垝鏀惰揣鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date startTime;
+
+    @ApiModelProperty(value = "璁″垝鏀惰揣缁撴潫鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date endTime;
+
+    @ApiModelProperty(value = "椤圭洰缂栫爜")
+    private String projectCode;
+
+    @ApiModelProperty(value = "涓氬姟绫诲瀷")
+    private String wkType;
+
+    @ApiModelProperty(value = "鍗曟嵁鏄庣粏")
+    private List<OrderItem> children;
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/params/OrderItem.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/params/OrderItem.java
new file mode 100644
index 0000000..0006660
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/params/OrderItem.java
@@ -0,0 +1,53 @@
+package com.vincent.rsf.server.api.controller.params;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * @author Ryan
+ * @version 1.0
+ * @title OrderItem
+ * @description
+ * @create 2025/3/5 16:23
+ */
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "OrderItem", description = "鍏ュ簱鍗曟嵁")
+public class OrderItem implements Serializable {
+
+    @ApiModelProperty(value = "鏄庣粏鏁伴噺")
+    private Double anfme;
+
+    @ApiModelProperty(value = "宸插畬鎴愭暟閲�")
+    private Double qty;
+
+    @ApiModelProperty(value = "erp涓婚敭")
+    private String erpId;
+
+    @ApiModelProperty(value = "鐗╂枡缂栫爜")
+    private String matnrCode;
+
+    @ApiModelProperty(value = "鐗╂枡鍚嶇О")
+    private String matnrName;
+
+    @ApiModelProperty(value = "鍗曚綅")
+    private String unit;
+
+    @ApiModelProperty(value = "鏍囧寘鏁伴噺")
+    private String nromQty;
+
+    @ApiModelProperty(value = "渚涘簲鍟嗗悕绉�")
+    private String splrName;
+
+    @ApiModelProperty(value = "渚涘簲鍟嗙紪鐮�")
+    private String splrCode;
+
+    @ApiModelProperty(value = "渚涘簲鍟嗘壒娆�")
+    private String splrBatch;
+
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/enums/OrderType.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/enums/OrderType.java
new file mode 100644
index 0000000..bad8293
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/enums/OrderType.java
@@ -0,0 +1,24 @@
+package com.vincent.rsf.server.api.entity.enums;
+
+/**
+ * @author Ryan
+ * @version 1.0
+ * @title PurchaseType
+ * @description
+ * @create 2025/3/5 15:54
+ */
+public enum OrderType {
+    //璁㈠崟绫诲瀷
+    ORDER_PURCHASE_IN("purchase", "閲囪喘鍏ュ簱鍗�"),
+    ORDER_OUT("out", "閲囪喘鍑哄簱鍗�"),
+    ;
+
+    OrderType(String type, String desc) {
+        this.type = type;
+        this.desc = desc;
+    }
+
+    public String type;
+    public String desc;
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/enums/OrderWorkType.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/enums/OrderWorkType.java
new file mode 100644
index 0000000..09c00e4
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/enums/OrderWorkType.java
@@ -0,0 +1,29 @@
+package com.vincent.rsf.server.api.entity.enums;
+
+/**
+ * @author Ryan
+ * @version 1.0
+ * @title PurchaseType
+ * @description
+ * @create 2025/3/5 15:54
+ */
+public enum OrderWorkType {
+    //璁㈠崟绫诲瀷
+    ORDER_PURCHASE_IN("purchase", "閲囪喘鍗�"),
+    ORDER_PROD_IN("prod", "鐢熶骇棰嗘枡鍗�"),
+    ORDER_DONE_IN("done", "瀹屽伐鍏ユ枡鍗�"),
+    ORDER_SALE_IN("sale", "閿�鍞鍗�"),
+    ORDER_PROD_BACK_IN("prod back", "鐢熶骇閫�鏂欏崟"),
+    ORDER_SPLR_BACK_OUT("supplier back", "渚涘簲鍟嗗嚭璐у崟"),
+    ORDER_SALE_BACK_IN("sale back", "閿�鍞��璐у崟")
+    ;
+
+    OrderWorkType(String type, String desc) {
+        this.type = type;
+        this.desc = desc;
+    }
+
+    public String type;
+    public String desc;
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/ErpApiService.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/ErpApiService.java
new file mode 100644
index 0000000..a241420
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/ErpApiService.java
@@ -0,0 +1,18 @@
+package com.vincent.rsf.server.api.service;
+
+
+import com.vincent.rsf.server.api.controller.params.Order;
+
+import java.util.List;
+
+/**
+ * @author Ryan
+ * @version 1.0
+ * @title ErpApiService
+ * @description
+ * @create 2025/3/4 16:23
+ */
+public interface ErpApiService {
+
+    boolean syncPurchasee(List<Order> orders);
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ErpApiServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ErpApiServiceImpl.java
new file mode 100644
index 0000000..b60f6e1
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ErpApiServiceImpl.java
@@ -0,0 +1,72 @@
+package com.vincent.rsf.server.api.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.vincent.rsf.framework.exception.CoolException;
+import com.vincent.rsf.server.api.controller.params.OrderItem;
+import com.vincent.rsf.server.api.entity.enums.OrderType;
+import com.vincent.rsf.server.manager.entity.PurchaseItem;
+import com.vincent.rsf.server.manager.service.PurchaseItemService;
+import com.vincent.rsf.server.manager.service.PurchaseService;
+import com.vincent.rsf.server.system.constant.SerialRuleCode;
+import com.vincent.rsf.server.api.controller.params.Order;
+import com.vincent.rsf.server.system.utils.SerialRuleUtils;
+import com.vincent.rsf.server.api.service.ErpApiService;
+import com.vincent.rsf.server.manager.entity.Purchase;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Ryan
+ * @version 1.0
+ * @title ErpApiServiceImpl
+ * @description
+ * @create 2025/3/4 16:27
+ */
+@Service
+public class ErpApiServiceImpl extends ServiceImpl implements ErpApiService {
+
+    @Autowired
+    private PurchaseService purchaseService;
+
+    @Autowired
+    private PurchaseItemService purchaseItemService;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean syncPurchasee(List<Order> orders) {
+        if (orders.isEmpty()) {
+            throw new CoolException("鍗曟嵁鍐呭涓嶈兘涓虹┖锛侊紒");
+        }
+        orders.forEach(ors -> {
+            Purchase purchase = new Purchase();
+            BeanUtils.copyProperties(ors, purchase);
+            String wkVal = SerialRuleUtils.generateRuleCode(SerialRuleCode.PURCHASE_CODE, purchase);
+            purchase.setCode(wkVal)
+                    .setType(OrderType.ORDER_PURCHASE_IN.type);
+            if (!purchaseService.save(purchase)) {
+                throw new CoolException("閲囪喘鍗曟嵁淇濆瓨澶辫触");
+            }
+            //鍒ゆ柇瀛愬垪琛ㄤ笉涓虹┖
+            if (!ors.getChildren().isEmpty()) {
+                ArrayList<PurchaseItem> list = new ArrayList<>();
+                ors.getChildren().forEach(orderItem -> {
+                    PurchaseItem item = new PurchaseItem();
+                    BeanUtils.copyProperties(orderItem, item);
+                    item.setPurchaseId(purchase.getId());
+                    list.add(item);
+                });
+                if (!purchaseItemService.saveBatch(list)) {
+                    throw new CoolException("閲囪喘鍗曟槑缁嗕繚瀛樺け璐ワ紒锛�");
+                }
+            }
+        });
+
+        return true;
+    }
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/common/config/WebMvcConfig.java b/rsf-server/src/main/java/com/vincent/rsf/server/common/config/WebMvcConfig.java
index c79c7d6..ddb8d66 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/common/config/WebMvcConfig.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/common/config/WebMvcConfig.java
@@ -26,7 +26,7 @@
     public void addInterceptors(InterceptorRegistry registry) {
         registry.addInterceptor(getAsyncHandlerInterceptor())
                 .addPathPatterns("/**")
-                .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**","/v3/**","/doc.html/**", "/swagger-ui.html/**");
+                .excludePathPatterns("/swagger-resources/**", "/webjars/**","/erp/**", "/v2/**","/v3/**","/doc.html/**", "/swagger-ui.html/**");
     }
 
     @Bean
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/common/security/SecurityConfig.java b/rsf-server/src/main/java/com/vincent/rsf/server/common/security/SecurityConfig.java
index 53ad888..9375e31 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/common/security/SecurityConfig.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/common/security/SecurityConfig.java
@@ -39,6 +39,7 @@
             "/system/info",
             "/tenant/list",
             "/email/code",
+            "/erp/**",
             "/login",
             "/register",
             "/druid/**",
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/common/utils/DateUtils.java b/rsf-server/src/main/java/com/vincent/rsf/server/common/utils/DateUtils.java
new file mode 100755
index 0000000..ff3c883
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/common/utils/DateUtils.java
@@ -0,0 +1,726 @@
+package com.vincent.rsf.server.common.utils;
+
+import org.apache.tika.utils.StringUtils;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+
+/**
+ * 鏃ユ湡鏃堕棿宸ュ叿绫�
+ *
+ * @author Ryan
+ * @createTime 2018-07-19 10:42:00
+ */
+public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
+
+    public final static String YYYYMMDDHHMMSS_PATTER = "yyyyMMddHHmmss";
+
+    public final static String YYYYMMDDHHMMSS_PATTER_HB = "YYYY-MM-dd HH:mm:ss.SSS";
+    public final static String YYYYMMDDHHMMSS_PATTER_HB1 = "YYYY-MM-dd HH:mm:ss.000";
+
+    public static String datetimeFormat = "yyyy-MM-dd HH:mm:ss";
+
+    public final static String[] parsePatterns = {
+            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd", "yyyy-MM",
+            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM/dd", "yyyy/MM",
+            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM.dd", "yyyy.MM", "YYYY-MM-dd HH:mm:ss.SSS"};
+
+    public static Date now() {
+        return Calendar.getInstance().getTime();
+    }
+
+    /**
+     * 浠呮樉绀哄勾鏈堟棩锛屼緥濡� 2021-08-11.
+     */
+    public static final String DATE_PATTERN = "yyyy-MM-dd";
+
+
+    /**
+     * 涓�澶╃殑缁撴潫鏃堕棿锛屼粎鏄剧ず鏃跺垎绉�
+     */
+    private static final String END_TIME = "23:59:59";
+
+    /**
+     * @Description锛� 杩斿洖 yyyy-MM-dd HH:mm:ss
+     */
+    public static String nowDate() {
+        return getDate(new Date());
+    }
+
+    /**
+     * 灏嗘棩鏈熷瓧绗︿覆杞崲涓烘棩鏈熺被鍨�
+     *
+     * @param pattern 鏃ユ湡瀛楃涓叉牸寮� 涓嶄紶鍒欎负 yyyy-MM-dd
+     * @return
+     * @throws ParseException
+     */
+    public static Date nowDate(String pattern) throws ParseException {
+        if (StringUtils.isBlank(pattern)) {
+            pattern = "yyyy-MM-dd";
+        }
+        //璁剧疆鏃ユ湡鏍煎紡
+        SimpleDateFormat df = new SimpleDateFormat(pattern);
+        return df.parse(df.format(new Date()));
+    }
+
+    /**
+     * 鑾峰彇鎸囧畾鏃ユ湡褰撳懆鏄熸湡涓�鐨勬椂闂�
+     *
+     * @param date
+     * @return
+     */
+    public static Date getFirstDayOfWeek(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        //鑾峰彇鏈懆绗竴澶�
+        calendar.set(Calendar.WEEK_OF_YEAR, calendar.get(Calendar.WEEK_OF_YEAR));
+        int dayOfWeek = 0;
+        if (calendar.get(Calendar.DAY_OF_WEEK) == 1) {
+            dayOfWeek = -6;
+        } else {
+            dayOfWeek = 2 - calendar.get(Calendar.DAY_OF_WEEK);
+        }
+        calendar.add(Calendar.DAY_OF_WEEK, dayOfWeek);
+
+        return calendar.getTime();
+    }
+
+    public static Date getFirstDayOfWeekT(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        //鑾峰彇鏈懆绗竴澶�
+        calendar.set(Calendar.WEEK_OF_YEAR, calendar.get(Calendar.WEEK_OF_YEAR));
+        int dayOfWeek = 0;
+        if (calendar.get(Calendar.DAY_OF_WEEK) == 1) {
+            dayOfWeek = -6;
+        } else {
+            dayOfWeek = 2 - calendar.get(Calendar.DAY_OF_WEEK);
+        }
+        calendar.add(Calendar.DAY_OF_WEEK, dayOfWeek);
+
+        //璁剧疆鏃ユ湡鏍煎紡
+        SimpleDateFormat df = new SimpleDateFormat(DATE_PATTERN);
+
+        try {
+            return df.parse(df.format(calendar.getTime()));
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 鑾峰彇鎸囧畾鏃ユ湡褰撳懆鏄熸湡鏃ョ殑鏃堕棿
+     *
+     * @param date
+     * @return
+     */
+    public static Date getLastDayOfWeek(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setFirstDayOfWeek(Calendar.MONDAY);
+        calendar.setTime(date);
+        // Sunday
+        calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek() + 6);
+
+        return calendar.getTime();
+    }
+
+    /**
+     * 鑾峰彇鎸囧畾鏃ユ湡褰撴湀绗竴澶╃殑鏃堕棿
+     *
+     * @param date
+     * @return
+     */
+    public static Date getFirstDayOfMonth(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.add(Calendar.MONTH, 0);
+        calendar.set(Calendar.DAY_OF_MONTH, 1);
+        return calendar.getTime();
+    }
+
+    /**
+     * 鑾峰彇鎸囧畾鏃ユ湡褰撴湀鏈�鍚庝竴澶╃殑鏃堕棿
+     *
+     * @param date
+     * @return
+     */
+    public static Date getLastDayOfMonth(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.add(Calendar.MONTH, 0);
+        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
+        return calendar.getTime();
+    }
+
+    /**
+     * 鑾峰彇鎸囧畾鏃ユ湡褰撳勾绗竴澶╃殑鏃堕棿
+     *
+     * @param date
+     * @return
+     */
+    public static Date getFirstDayOfYear(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.clear();
+        calendar.set(Calendar.YEAR, date.getYear() + 1900);
+        return calendar.getTime();
+    }
+
+    /**
+     * 鑾峰彇鎸囧畾鏃ユ湡褰撳勾鏈�鍚庝竴澶╃殑鏃堕棿
+     *
+     * @param date
+     * @return
+     */
+    public static Date getLastDayOfYear(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.clear();
+        calendar.set(Calendar.YEAR, date.getYear() + 1900);
+        calendar.roll(Calendar.DAY_OF_YEAR, -1);
+        return calendar.getTime();
+    }
+
+    /**
+     * 鑾峰彇涓や釜鏃ユ湡鐩搁殧鐨勫ぉ鏁�
+     *
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    public static float getDateDiffOfDays(Date startDate, Date endDate) {
+        long diff = endDate.getTime() - startDate.getTime();
+
+        return diff / (24 * 60 * 60 * 1000);
+    }
+
+    /**
+     * 鑾峰彇姣忓ぉ宸ヤ綔灏忔椂鏁般�備緥濡傦細鏃╀笂9鐐逛笂鐝紝涓嬪崍6鐐逛笅鐝紝浼戞伅涓�涓皬鏃讹紝宸ヤ綔鏃堕棿涓�8
+     *
+     * @param startTime 寮�濮嬫椂闂达紝鏍煎紡锛欻Hmm銆備緥濡傛棭涓�7鐐瑰崐锛屼娇鐢�0730琛ㄧず
+     * @param endTime   缁撴潫鏃堕棿锛屾牸寮忥細HHmm銆備緥濡備笅鍗�6鐐瑰崐锛屼娇鐢�1830琛ㄧず
+     * @param restHours 浼戞伅鏃堕棿
+     * @return
+     */
+    public static float getWorkHours(String startTime, String endTime, float restHours) {
+        Date m = new Date();
+        m.setHours(Integer.parseInt(startTime.substring(0, 2)) - 1);
+        m.setMinutes(Integer.parseInt(startTime.substring(2)));
+        Date a = new Date();
+        a.setHours(Integer.parseInt(endTime.substring(0, 2)) - 1);
+        a.setMinutes(Integer.parseInt(endTime.substring(2)));
+
+        return (a.getTime() - m.getTime()) / (1000 * 60 * 60 * 1.0f) - restHours;
+    }
+
+    /**
+     * 灏嗘棩鏈熷瓧绗︿覆杞崲涓烘棩鏈熺被鍨�
+     *
+     * @param dateStr 鏃ユ湡瀛楃涓�
+     * @param pattern 鏃ユ湡瀛楃涓叉牸寮�
+     * @return
+     * @throws ParseException
+     */
+    public static Date parse(String dateStr, String pattern) throws ParseException {
+        if (StringUtils.isBlank(dateStr)) {
+            return null;
+        }
+        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
+        return dateFormat.parse(dateStr);
+    }
+
+    /**
+     * 鏃ユ湡鍨嬪瓧绗︿覆杞寲涓烘棩鏈� 鏍煎紡
+     * { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
+     * "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm",
+     * "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm" }
+     */
+    public static Date parse(String str) {
+        if (str == null) {
+            return null;
+        }
+        try {
+            return parseDate(str, parsePatterns);
+        } catch (ParseException e) {
+            return null;
+        }
+    }
+
+    public static String formatToAnotherPattern(String dateStr, String pattern, String anotherPatter) throws ParseException {
+        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
+
+        Date date = dateFormat.parse(dateStr);
+        dateFormat = new SimpleDateFormat(anotherPatter);
+        return dateFormat.format(date);
+    }
+
+    /**
+     * 鑾峰彇鏃ユ湡鏃堕棿瀛楃涓�
+     *
+     * @param date 闇�瑕佽浆鍖栫殑鏃ユ湡鏃堕棿
+     * @return String 鏃ユ湡鏃堕棿瀛楃涓诧紝渚嬪 2015-08-11
+     */
+    public static String format(Date date) {
+        return format(date, DATE_PATTERN);
+    }
+
+    public static String format(Date date, String pattern) {
+        if (date == null) {
+            return "";
+        }
+        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
+        return dateFormat.format(date);
+    }
+
+    public static Date addHours(Date date, int amount) {
+        return add(date, Calendar.HOUR_OF_DAY, amount);
+    }
+
+    public static Date addDays(Date date, int amount) {
+        return add(date, Calendar.DAY_OF_MONTH, amount);
+    }
+
+    public static Date addYear(Date date, int amount) {
+        return add(date, Calendar.YEAR, amount);
+    }
+
+    public static Date addMonth(Date date, int amount) {
+        return add(date, Calendar.MONTH, amount);
+    }
+
+
+    private static Date add(Date date, int calendarField, int amount) {
+        Calendar c = Calendar.getInstance();
+        c.setTime(date);
+        c.add(calendarField, amount);
+        return c.getTime();
+    }
+
+    /**
+     * 灏嗘绉掓牸寮忓寲锛屽鏋滃ぇ浜�60绉掞紝杩斿洖 1鍒唜x绉掞紝澶т簬60鍒嗛挓锛岃繑鍥� 1灏忔椂xx鍒唜x绉�
+     *
+     * @param ms 姣
+     * @return
+     */
+    public static String formatTime(long ms) {
+        if (ms < 1000) { //姣
+            return ms + "姣";
+        } else if (ms / 1000 < 60) {
+            // 灏忎簬60绉掞紝浠ョ鏄剧ず
+            return ms / 1000 + "绉�";
+        } else if (ms / 1000 / 60 < 60) {
+            // 灏忎簬60鍒嗭紝浠ュ垎鏄剧ず
+            return ms / 1000 / 60 + "鍒�" + (ms / 1000 % 60) + "绉�";
+        } else if (ms / 1000 / 60 / 60 < 24) {
+            // 灏忎簬24灏忔椂
+            return (ms / 1000 / 60 / 60) + "鏃�" + (ms / 1000 % 60) + "鍒�" + (ms / 1000 / 60 % 60) + "绉�";
+        } else {
+            return (ms / 1000 / 60 / 60 / 24) + "澶�" + (ms / 1000 / 60 / 60) + "鏃�" + (ms / 1000 % 60) + "鍒�" + (ms / 1000 / 60 % 60) + "绉�";
+        }
+    }
+
+    public static Date dateToISODate(Date date) {
+        //T浠h〃鍚庨潰璺熺潃鏃堕棿锛孼浠h〃UTC缁熶竴鏃堕棿
+        SimpleDateFormat format =
+                new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+        format.setCalendar(new GregorianCalendar(new SimpleTimeZone(0, "GMT")));
+        String isoDate = format.format(date);
+        try {
+            return format.parse(isoDate);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+    public static Date localDateTime2Date(LocalDateTime localDateTime) {
+        ZoneId zoneId = ZoneId.systemDefault();
+        //Combines this date-time with a time-zone to create a  ZonedDateTime.
+        ZonedDateTime zdt = localDateTime.atZone(zoneId);
+        //Tue Mar 27 14:17:17 CST 2018
+        return Date.from(zdt.toInstant());
+    }
+
+    public static String localDateTimeToString(LocalDateTime localDateTime) {
+        DateTimeFormatter fmt = DateTimeFormatter.ofPattern(datetimeFormat);
+        return fmt.format(localDateTime);
+    }
+
+    public static LocalDateTime stringToLocalDateTime(String str) {
+        DateTimeFormatter fmt = DateTimeFormatter.ofPattern(datetimeFormat);
+        return LocalDateTime.parse(str, fmt);
+    }
+
+    public static LocalDateTime stringToLocalDateTime(String str, String fmtStr) {
+        DateTimeFormatter fmt = DateTimeFormatter.ofPattern(fmtStr);
+        return LocalDateTime.parse(str, fmt);
+    }
+
+    /**
+     * Date杞琇ocalDateTime
+     *
+     * @param date Date
+     * @return LocalDateTime
+     */
+    public static LocalDateTime dateToLocalDateTime(Date date) {
+        try {
+            Instant instant = date.toInstant();
+            ZoneId zoneId = ZoneId.systemDefault();
+            return instant.atZone(zoneId).toLocalDateTime();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * @Description锛氳幏鍙栧綋鍓嶆棩鏈� yyyy-MM-dd HH:mm:ss
+     * @Author wyt
+     * @Date 2020/8/21
+     */
+    public static String getDate(Date date) {
+        SimpleDateFormat sdf = new SimpleDateFormat(datetimeFormat);
+        return sdf.format(date);
+    }
+
+    public static String getDate(Date date, String format) {
+        SimpleDateFormat sdf = new SimpleDateFormat(format);
+        return sdf.format(date);
+    }
+
+    /**
+     * @Description锛� 鍒ゆ柇鏄惁鏄悎娉曟棩鏈熸牸寮�
+     * @Author wyt
+     * @Date 2021/2/24
+     */
+    public static boolean isValidDate(String str, String fmt) {
+        if (StringUtils.isBlank(str)) {
+            return false;
+        }
+        boolean convertSuccess = true;
+        // 鎸囧畾鏃ユ湡鏍煎紡涓哄洓浣嶅勾/涓や綅鏈堜唤/涓や綅鏃ユ湡锛屾敞鎰弝yyy/MM/dd鍖哄垎澶у皬鍐欙紱
+        SimpleDateFormat format = new SimpleDateFormat(fmt);
+        try {
+            // 璁剧疆lenient涓篺alse. 鍚﹀垯SimpleDateFormat浼氭瘮杈冨鏉惧湴楠岃瘉鏃ユ湡锛屾瘮濡�2007/02/29浼氳鎺ュ彈锛屽苟杞崲鎴�2007/03/01
+            format.setLenient(false);
+            Date date = format.parse(str);
+            long time = date.getTime();
+            if (time < 14400) {
+                convertSuccess = false;
+            }
+        } catch (ParseException e) {
+            // e.printStackTrace();
+            // 濡傛灉throw java.text.ParseException鎴栬�匩ullPointerException锛屽氨璇存槑鏍煎紡涓嶅
+            convertSuccess = false;
+        }
+        return convertSuccess;
+    }
+
+
+    /**
+     * 璁$畻涓や釜鏃ユ湡鐩稿樊鐨勭鏁�
+     *
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    public static int calLastedTime(Date startDate, Date endDate) {
+        long a = endDate.getTime();
+        long b = startDate.getTime();
+        int c = (int) ((a - b) / 1000);
+        return c;
+    }
+
+    /**
+     * 鑾峰彇鏈湀鐨勭涓�澶�
+     *
+     * @return Calendar 鏃ュ巻
+     */
+    public static Calendar getStartDayOfMonth(Date date) {
+        Calendar calendar = Calendar.getInstance(Locale.CHINA);
+        calendar.setTime(date);
+        calendar.set(Calendar.DAY_OF_MONTH, 1);
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        return calendar;
+    }
+
+    /**
+     * 鏍规嵁鏃ュ巻杩斿洖鏃ユ湡鏃堕棿瀛楃涓�
+     *
+     * @param calendar 鏃ュ巻
+     * @return String 鏃ユ湡鏃堕棿瀛楃涓�
+     */
+    public static String getDateTimeStr(Calendar calendar) {
+        StringBuffer buf = new StringBuffer("");
+
+        buf.append(calendar.get(Calendar.YEAR));
+        buf.append("-");
+        buf.append(calendar.get(Calendar.MONTH) + 1 > 9 ? calendar.get(Calendar.MONTH) + 1 + ""
+                : "0" + (calendar.get(Calendar.MONTH) + 1));
+        buf.append("-");
+        buf.append(calendar.get(Calendar.DAY_OF_MONTH) > 9 ? calendar.get(Calendar.DAY_OF_MONTH) + ""
+                : "0" + calendar.get(Calendar.DAY_OF_MONTH));
+        buf.append(" ");
+        buf.append(calendar.get(Calendar.HOUR_OF_DAY) > 9 ? calendar.get(Calendar.HOUR_OF_DAY) + ""
+                : "0" + calendar.get(Calendar.HOUR_OF_DAY));
+        buf.append(":");
+        buf.append(calendar.get(Calendar.MINUTE) > 9 ? calendar.get(Calendar.MINUTE) + ""
+                : "0" + calendar.get(Calendar.MINUTE));
+        buf.append(":");
+        buf.append(calendar.get(Calendar.SECOND) > 9 ? calendar.get(Calendar.SECOND) + ""
+                : "0" + calendar.get(Calendar.SECOND));
+        return buf.toString();
+    }
+
+
+    /**
+     * 鑾峰彇鎸囧畾鏃ユ湡褰撴湀绗竴澶╃殑鏃ユ湡瀛楃涓�
+     *
+     * @param date 鎸囧畾鏃ユ湡
+     * @return String 鏍煎紡锛歽yyy-MM-dd HH:mm:ss
+     */
+    public static String getMonthStartTimeStr(Date date) {
+        return getDateTimeStr(getStartDayOfMonth(date));
+    }
+
+
+    /**
+     * 鑾峰緱鎸囧畾鏃ユ湡鎵�鍦ㄦ棩鐨勭粨鏉熸椂闂村瓧绗︿覆
+     *
+     * @param date 鎸囧畾鏃ユ湡
+     * @return String 渚嬪锛�2021-08-11 23:59:59
+     */
+    public static String getDateEndTimeStr(Date date) {
+        String result = format(date, DATE_PATTERN);
+        return result.concat(" ").concat(END_TIME);
+    }
+
+
+    /**
+     * 鏃堕棿鎴宠浆鏃ユ湡
+     *
+     * @param msStr 鏃堕棿鎴�
+     * @return 涓嶄负绌猴細yyyy-MM-dd HH:mm:ss鏍煎紡鏃ユ湡锛屼负绌猴細杩斿洖null
+     */
+    public static String transForDate(String msStr) {
+        if (StringUtils.isBlank(msStr)) {
+            return null;
+        }
+
+        long msl = Long.parseLong(msStr);
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        return sdf.format(msl);
+    }
+
+    /**
+     * 鍒ゆ柇鏄惁鏄椂闂存埑
+     *
+     * @param msStr 鏃堕棿鎴�
+     * @return 涓嶄负绌猴紝骞朵笖鏄椂闂存埑鏍煎紡锛岃繑鍥瀟rue
+     */
+    public static boolean isTimeStamp(String msStr) {
+        if (StringUtils.isBlank(msStr)) {
+            return false;
+        }
+        boolean is = false;
+        try {
+            if (transForDate(msStr) != null) {
+                is = true;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return is;
+    }
+
+    /**
+     * 濡傛灉endDate>startDate锛岃繑鍥瀟rue锛屽惁鍒欒繑鍥瀎alse
+     *
+     * @param startDate 寮�濮嬫棩鏈熷瓧绗︿覆
+     * @param endDate   缁撴潫鏃ユ湡瀛楃涓�
+     * @return boolean
+     */
+    public static boolean compareDate(Date startDate, Date endDate) {
+        String startDateStr = format(startDate, DATE_PATTERN);
+        String endDateStr = format(endDate, DATE_PATTERN);
+        return compareDate(startDateStr, endDateStr);
+    }
+
+    /**
+     * @param thisDate  鈥�  褰撳墠鏃ユ湡
+     * @param otherDate 鈥� 姣旇緝鏃ユ湡
+     * @Description锛氭妸鏃堕棿鏍煎紡鍖栧埌绉掔骇缁х画姣旇緝 yyyy-MM-dd HH:mm:ss
+     * 濡傛灉thisDate>otherDate锛岃繑鍥� 1锛�
+     * thisDate=otherDate锛�   杩斿洖 0锛�
+     * thisDate<otherDate锛�   杩斿洖 -1锛�
+     * @Returns int
+     **/
+    public static int compareDateBySecond(Date thisDate, Date otherDate) {
+        String thisDateStr = format(thisDate, datetimeFormat);
+        String otherDateStr = format(otherDate, datetimeFormat);
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datetimeFormat);
+        try {
+            Date tDate = simpleDateFormat.parse(thisDateStr);
+            Date oDate = simpleDateFormat.parse(otherDateStr);
+            return tDate.compareTo(oDate);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return thisDate.compareTo(otherDate);
+    }
+
+    public static boolean compareDate(String startDateStr, String endDateStr) {
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_PATTERN);
+        try {
+            Date startDate = simpleDateFormat.parse(startDateStr);
+            Date endDate = simpleDateFormat.parse(endDateStr);
+            return endDate.after(startDate);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+    /**
+     * 鎸囧畾鏃堕棿寰�鍓嶆垨寰�鍚庡嚑澶�
+     *
+     * @param day 澶╂暟
+     * @return
+     */
+    public static String getTimeBeforeDay(int day, String fmt) {
+        if (StringUtils.isBlank(fmt)) {
+            fmt = "yyyy-MM-dd HH:mm:ss";
+        }
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        Date nowDate = new Date();
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(nowDate);
+        calendar.add(Calendar.DATE, day);
+        Date updateDate = calendar.getTime();
+        return sdf.format(updateDate);
+    }
+
+    /**
+     * 鑾峰彇鏃ユ湡鎵�鍦ㄦ湀绗竴澶╅浂鐐�
+     *
+     * @return
+     */
+    public static Date getFirstDayZeroOfMonth(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.add(Calendar.MONTH, 0);
+        calendar.set(Calendar.DAY_OF_MONTH, 1);
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        return calendar.getTime();
+    }
+
+    /**
+     * 鑾峰彇鏃ユ湡闆剁偣
+     *
+     * @return
+     */
+    public static Date getDayZero(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        return calendar.getTime();
+    }
+
+    /**
+     * 鑾峰彇鎸囧畾鏃ユ湡褰撳懆鏄熸湡涓�鐨勬椂闂�
+     *
+     * @param date
+     * @return
+     */
+    public static Date getFirstDayZeroOfWeek(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        //鑾峰彇鏈懆绗竴澶�
+        calendar.set(Calendar.WEEK_OF_YEAR, calendar.get(Calendar.WEEK_OF_YEAR));
+        int dayOfWeek = 0;
+        if (calendar.get(Calendar.DAY_OF_WEEK) == 1) {
+            dayOfWeek = -6;
+        } else {
+            dayOfWeek = 2 - calendar.get(Calendar.DAY_OF_WEEK);
+        }
+        calendar.add(Calendar.DAY_OF_WEEK, dayOfWeek);
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        return calendar.getTime();
+    }
+
+    /**
+     * @author Ryan
+     * @param: [date]
+     * @return: java.time.LocalDate
+     * @date: 2023/7/28
+     * @description: 鑾峰彇褰撳墠鏃堕棿鐨勫墠涓�骞�
+     */
+    public static Date getCurrDateOfLastYear(Date date, String perciod, boolean isMinus, Integer num) {
+
+        Instant instant = date.toInstant();
+        ZoneId zoneId = ZoneId.systemDefault();
+        LocalDateTime of = LocalDateTime.ofInstant(instant, zoneId);
+        LocalDate localDate = of.toLocalDate();
+        ZonedDateTime zonedDateTime = null;
+        if (perciod.equals("year")) {
+            if (isMinus) {
+                zonedDateTime = localDate.minusYears(num).atStartOfDay(zoneId);
+            } else {
+                zonedDateTime = localDate.plusYears(num).atStartOfDay(zoneId);
+            }
+        } else if (perciod.equals("months")) {
+            if (isMinus) {
+                zonedDateTime = localDate.minusMonths(num).atStartOfDay(zoneId);
+            } else {
+                zonedDateTime = localDate.plusMonths(num).atStartOfDay(zoneId);
+            }
+        } else if (perciod.equals("week")) {
+            if (isMinus) {
+                zonedDateTime = localDate.minusWeeks(num).atStartOfDay(zoneId);
+            } else {
+                zonedDateTime = localDate.plusWeeks(num).atStartOfDay(zoneId);
+            }
+        } else {
+            if (isMinus) {
+                zonedDateTime = localDate.minusDays(num).atStartOfDay(zoneId);
+            } else {
+                zonedDateTime = localDate.plusDays(num).atStartOfDay(zoneId);
+            }
+        }
+        return Date.from(zonedDateTime.toInstant());
+    }
+
+
+    public static Date getCurrDateOfLastYear(Date date, Integer num) {
+        return getCurrDateOfLastYear(date, "year", true, num);
+    }
+
+    //缁欐棩鏈熷鍔犳寚瀹氬勾
+    public static Date addYears(Date date, Integer num) {
+        // 鍒涘缓Calendar瀵硅薄
+        Calendar calendar = Calendar.getInstance();
+
+        // 璁剧疆寰呮搷浣滅殑鏃ユ湡
+        calendar.setTime(date);
+
+        // 澧炲姞涓夊勾
+        calendar.add(Calendar.YEAR, num);
+
+        // 鑾峰彇澧炲姞鍚庣殑鏃ユ湡
+        Date newDate = calendar.getTime();
+
+        return newDate;
+    }
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/AsnOrderController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/AsnOrderController.java
index 03d44a6..e088b8a 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/AsnOrderController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/AsnOrderController.java
@@ -107,4 +107,6 @@
         ExcelUtil.build(ExcelUtil.create(asnOrderService.list(), AsnOrder.class), response);
     }
 
+
+
 }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/MatnrController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/MatnrController.java
index 6dd9f72..3b4fc39 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/MatnrController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/MatnrController.java
@@ -1,9 +1,5 @@
 package com.vincent.rsf.server.manager.controller;
 
-import cn.afterturn.easypoi.excel.ExcelImportUtil;
-import cn.afterturn.easypoi.excel.entity.ImportParams;
-import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
-import cn.afterturn.easypoi.excel.imports.ExcelImportService;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.vincent.rsf.framework.common.Cools;
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Purchase.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Purchase.java
index 2f55f31..b59e788 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Purchase.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Purchase.java
@@ -2,6 +2,8 @@
 
 import java.text.SimpleDateFormat;
 import java.util.Date;
+
+import lombok.experimental.Accessors;
 import org.springframework.format.annotation.DateTimeFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
@@ -28,6 +30,7 @@
 import java.util.Date;
 
 @Data
+@Accessors(chain = true)
 @TableName("man_purchase")
 public class Purchase implements Serializable {
 
@@ -80,7 +83,7 @@
     /**
      * 宸叉敹璐ф暟閲�
      */
-    @ApiModelProperty(value= "宸叉敹璐ф暟閲�")
+    @ApiModelProperty(value= "鏀惰揣涓暟閲�")
     private Double workQty;
 
     /**
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/PurchaseItem.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/PurchaseItem.java
index 5d54e83..a9c82a5 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/PurchaseItem.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/PurchaseItem.java
@@ -3,6 +3,8 @@
 import com.baomidou.mybatisplus.annotation.TableLogic;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+
+import lombok.experimental.Accessors;
 import org.springframework.format.annotation.DateTimeFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
@@ -22,6 +24,7 @@
 import java.util.Date;
 
 @Data
+@Accessors(chain = true)
 @TableName("man_purchase_item")
 public class PurchaseItem implements Serializable {
 
@@ -80,7 +83,7 @@
      * 鏍囧噯鍖呰
      */
     @ApiModelProperty(value= "鏍囧噯鍖呰")
-    private Double nomQty;
+    private Double nromQty;
 
     /**
      * ASN鍗曟嵁鏁伴噺
@@ -98,19 +101,19 @@
      * 渚涘簲鍟嗗悕绉�
      */
     @ApiModelProperty(value= "渚涘簲鍟嗗悕绉�")
-    private String pulrName;
+    private String splrName;
 
     /**
      * 渚涘簲鍟嗙紪鐮�
      */
     @ApiModelProperty(value= "渚涘簲鍟嗙紪鐮�")
-    private String pulrCode;
+    private String splrCode;
 
     /**
      * 渚涘簲鍟嗘壒娆�
      */
     @ApiModelProperty(value= "渚涘簲鍟嗘壒娆�")
-    private String pulrBatch;
+    private String splrBatch;
 
     /**
      * 鐘舵�� 1: 姝e父  0: 鍐荤粨  
@@ -165,7 +168,7 @@
 
     public PurchaseItem() {}
 
-    public PurchaseItem(Long purchaseId,String erpId,String matnrCode,String matnrName,String unit,Double anfme,Double qty,Double nomQty,Double asnQty,Double printQty,String pulrName,String pulrCode,String pulrBatch,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
+    public PurchaseItem(Long purchaseId,String erpId,String matnrCode,String matnrName,String unit,Double anfme,Double qty,Double nromQty,Double asnQty,Double printQty,String splrName,String splrCode,String splrBatch,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
         this.purchaseId = purchaseId;
         this.erpId = erpId;
         this.matnrCode = matnrCode;
@@ -173,12 +176,12 @@
         this.unit = unit;
         this.anfme = anfme;
         this.qty = qty;
-        this.nomQty = nomQty;
+        this.nromQty = nromQty;
         this.asnQty = asnQty;
         this.printQty = printQty;
-        this.pulrName = pulrName;
-        this.pulrCode = pulrCode;
-        this.pulrBatch = pulrBatch;
+        this.splrName = splrName;
+        this.splrCode = splrCode;
+        this.splrBatch = splrBatch;
         this.status = status;
         this.deleted = deleted;
         this.tenantId = tenantId;
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/ScheduleJobs.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/ScheduleJobs.java
index dedd1a5..aceb1c9 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/ScheduleJobs.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/ScheduleJobs.java
@@ -2,16 +2,18 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.vincent.rsf.framework.exception.CoolException;
+import com.vincent.rsf.server.common.utils.DateUtils;
 import com.vincent.rsf.server.manager.entity.*;
 import com.vincent.rsf.server.manager.service.*;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
+import java.util.Date;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * @author Ryan
@@ -20,6 +22,7 @@
  * @description
  * @create 2025/3/3 15:38
  */
+@Component
 public class ScheduleJobs {
 
     @Autowired
@@ -37,26 +40,31 @@
     private AsnOrderItemService asnOrderItemService;
     /**
      * @author Ryan
-     * @description  鏍规嵁PO鍗曟嵁鐢熸垚ASN鍗�
+     * @description  鏍规嵁PO鍗曟嵁鐢熸垚ASN鍗�,鑷姩鐢熸垚ASN鍗曚负鍏ㄩ噺鐢熸垚
      * @throws
      * @return
      * @time 2025/3/3 15:44
      */
-    @Scheduled(cron = "0/10 * * * * ? ")
+    @Scheduled(cron = "0 0/30 * * * ?  ")
     @Transactional(rollbackFor = Exception.class)
     public void genAsnOrder() {
         //鑾峰彇鏈敓鎴怉SN鍗曟嵁
-        List<Purchase> purchases = purchaseService.list(new LambdaQueryWrapper<Purchase>().eq(Purchase::getStatus, 2));
+        List<Purchase> purchases = purchaseService.list(new LambdaQueryWrapper<Purchase>().eq(Purchase::getStatus, 0));
         //閲囪喘鍗曚负绌猴紝鐩存帴璺冲嚭褰撳墠浠诲姟
         if (purchases.isEmpty()) {
             return;
         }
         //鐢熸垚ASN鍗曟嵁
         purchases.forEach(purchase -> {
+            if (!Objects.isNull(purchase.getStartTime())) {
+                //鍒ゆ柇璧峰鏃堕棿鏄惁澶т簬褰撳墠鏃堕棿
+                if (DateUtils.compareDate(new Date(), purchase.getStartTime())) {
+                    return;
+                }
+            }
             List<PurchaseItem> items = purchaseItemService.list(new LambdaQueryWrapper<PurchaseItem>().eq(PurchaseItem::getPurchaseId, purchase.getId()));
-            //瀛愬垪琛ㄤ负绌烘暟鎹紝鐩存帴璺冲嚭
             if (items.isEmpty()) {
-                return;
+                throw new CoolException("瀛愬垪琛ㄦ暟鎹负绌猴紝璇锋煡璇O鍗曟槸鍚︽纭綍鍏ワ紒锛�");
             }
             AsnOrder order = new AsnOrder();
             order.setAnfme(purchase.getAnfme())
@@ -74,8 +82,8 @@
                 orderItem.setAnfme(item.getAnfme())
                         .setAsnId(purchase.getId())
                         .setQty(item.getQty())
-                        .setSplrName(item.getPulrName())
-                        .setSplrCode(item.getPulrCode())
+                        .setSplrName(item.getSplrName())
+                        .setSplrCode(item.getSplrCode())
                         .setMatnk(item.getMatnrName())
                         .setPoDetlId(item.getId() + "")
                         .setPurQty(item.getAnfme())
@@ -88,6 +96,13 @@
                 throw new CoolException(("Asn鍗曟嵁鏄庣粏淇濆瓨澶辫触锛侊紒"));
             }
 
+            //浠诲姟鎵ц瀹屾垚锛屼慨鏀瑰凡瀹屾垚鏁伴噺鍜孭O鍗曟墽琛岀姸鎬�
+            purchase.setQty(purchase.getAnfme()).setStatus(1);
+
+            if (!purchaseService.save(purchase)) {
+                throw new CoolException("PO鍗曟墽琛屽畬鎴愬悗锛屼繚瀛樺け璐ワ紒锛�");
+            }
+
         });
     }
 
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java b/rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java
new file mode 100644
index 0000000..bc92ad9
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java
@@ -0,0 +1,13 @@
+package com.vincent.rsf.server.system.constant;
+
+/**
+ * @author Ryan
+ * @version 1.0
+ * @title SerialRuleCode
+ * @description
+ * @create 2025/3/4 17:02
+ */
+public class SerialRuleCode {
+
+    public final static String PURCHASE_CODE = "sys_purchase_code";
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/system/entity/SerialRule.java b/rsf-server/src/main/java/com/vincent/rsf/server/system/entity/SerialRule.java
index 7f2920c..12f7d3f 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/system/entity/SerialRule.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/system/entity/SerialRule.java
@@ -3,6 +3,8 @@
 import com.baomidou.mybatisplus.annotation.TableLogic;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+
+import lombok.experimental.Accessors;
 import org.springframework.format.annotation.DateTimeFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
@@ -22,6 +24,7 @@
 import java.util.Date;
 
 @Data
+@Accessors(chain = true)
 @TableName("sys_serial_rule")
 public class SerialRule implements Serializable {
 
@@ -68,7 +71,7 @@
      * 褰撳墠鍊�
      */
     @ApiModelProperty(value= "褰撳墠鍊�")
-    private String currValue;
+    private Integer currValue;
 
     /**
      * 鏈�杩戠敓鎴愮紪鐮�
@@ -81,6 +84,9 @@
      */
     @ApiModelProperty(value= "鐘舵�� 1: 姝e父  0: 鍐荤粨  ")
     private Integer status;
+
+    @ApiModelProperty(value = "娴佹按鍙锋渶澶ч暱搴�")
+    private Integer maxLen;
 
     /**
      * 鏄惁鍒犻櫎 1: 鏄�  0: 鍚�  
@@ -129,7 +135,7 @@
 
     public SerialRule() {}
 
-    public SerialRule(String code,String name,String delimit,String reset,String resetDep,String currValue,String lastCode,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
+    public SerialRule(String code,String name,String delimit,String reset,String resetDep,Integer currValue,String lastCode,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
         this.code = code;
         this.name = name;
         this.delimit = delimit;
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/system/enums/SerialRuleReset.java b/rsf-server/src/main/java/com/vincent/rsf/server/system/enums/SerialRuleReset.java
new file mode 100644
index 0000000..4e93aa4
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/system/enums/SerialRuleReset.java
@@ -0,0 +1,27 @@
+package com.vincent.rsf.server.system.enums;
+
+/**
+ * @author Ryan
+ * @version 1.0
+ * @title SerialRuleRest
+ * @description
+ * @create 2025/3/5 09:44
+ */
+public enum SerialRuleReset {
+
+    //閲嶇疆绫诲瀷锛氬勾
+    SERIAL_REST_TYPE_YEAR("year", "骞�"),
+    //閲嶇疆绫诲瀷锛氭湀
+    SERIAL_REST_TYPE_MONTH("month", "鏈�"),
+    //閲嶇疆绫诲瀷锛氭棩
+    SERIAL_REST_TYPE_DAYS("day", "鏃�")
+    ;
+
+    public String type;
+    public String desc;
+
+    SerialRuleReset(String type, String desc) {
+        this.type = type;
+        this.desc = desc;
+    }
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/system/enums/SerialRuleType.java b/rsf-server/src/main/java/com/vincent/rsf/server/system/enums/SerialRuleType.java
new file mode 100644
index 0000000..1c3ee92
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/system/enums/SerialRuleType.java
@@ -0,0 +1,29 @@
+package com.vincent.rsf.server.system.enums;
+
+/**
+ * @author Ryan
+ * @version 1.0
+ * @title SerialRuleType
+ * @description
+ * @create 2025/3/5 08:11
+ */
+public enum SerialRuleType {
+    //甯搁噺鍊�
+    WK_CONSTANT("1", "甯搁噺"),
+    //娴佹按鍙�
+    WK_SERIAL_NO("2", "娴佹按鍙�"),
+    //鏃ユ湡
+    WK_DATE_FORMAT("3", "鏃ユ湡"),
+    //瀛楁
+    WK_FEILD("4", "瀛楁")
+    ;
+
+    public String wkType;
+    public String wkName;
+
+    SerialRuleType(String type, String name){
+        this.wkType = type;
+        this.wkName = name;
+    }
+
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/system/utils/SerialRuleUtils.java b/rsf-server/src/main/java/com/vincent/rsf/server/system/utils/SerialRuleUtils.java
new file mode 100644
index 0000000..c026c72
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/system/utils/SerialRuleUtils.java
@@ -0,0 +1,140 @@
+package com.vincent.rsf.server.system.utils;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.vincent.rsf.framework.common.SpringUtils;
+import com.vincent.rsf.framework.exception.CoolException;
+import com.vincent.rsf.server.common.utils.DateUtils;
+import com.vincent.rsf.server.system.entity.SerialRule;
+import com.vincent.rsf.server.system.entity.SerialRuleItem;
+import com.vincent.rsf.server.system.enums.SerialRuleReset;
+import com.vincent.rsf.server.system.enums.SerialRuleType;
+import com.vincent.rsf.server.system.service.SerialRuleItemService;
+import com.vincent.rsf.server.system.service.SerialRuleService;
+import org.apache.tika.utils.StringUtils;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * @author Ryan
+ * @version 1.0
+ * @title 鐢熸垚瑙勫垯缂栫爜鍔熻兘
+ * @description
+ * @create 2025/3/5 08:01
+ */
+public class SerialRuleUtils {
+
+    /**
+     * @author Ryan
+     * @description 鏍规嵁缂栫爜瑙勫垯鐢熸垚缂栫爜鍙�
+     * @throws
+     * @return 缂栫爜鍙�
+     * @time 2025/3/5 08:52
+     */
+    public static String generateRuleCode(String code, Object obj) {
+        SerialRuleService ruleService = SpringUtils.getBean(SerialRuleService.class);
+        //鑾峰彇瑙勫垯缂栫爜涓诲崟
+        SerialRule serialRule = ruleService
+                .getOne(new LambdaQueryWrapper<SerialRule>()
+                        .eq(SerialRule::getCode, code));
+        if (Objects.isNull(serialRule)) {
+            throw new CoolException("閲囪喘缂栫爜瑙勫垯涓嶅瓨鍦紒锛�");
+        }
+        SerialRuleItemService serialRuleItemService = SpringUtils.getBean(SerialRuleItemService.class);
+
+        //鑾峰彇瑙勫垯缂栫爜鏄庣粏
+        List<SerialRuleItem> ruleItems = serialRuleItemService
+                .list(new LambdaQueryWrapper<SerialRuleItem>()
+                        .eq(SerialRuleItem::getRuleId, serialRule.getId())
+                        .orderByAsc(SerialRuleItem::getSort));
+        if (Objects.isNull(ruleItems)) {
+            throw new CoolException("缂栫爜瑙勫垯鏄庣粏涓虹┖锛侊紒");
+        }
+
+        StringBuffer buffer = new StringBuffer();
+        ruleItems.forEach(rule -> {
+            if (rule.getWkType().equals(SerialRuleType.WK_CONSTANT.wkType)) {
+                buffer.append(rule.getFeildValue());
+            } else if (rule.getWkType().equals(SerialRuleType.WK_SERIAL_NO.wkType)) {
+                String result = "", format = "";
+                if (serialRule.getReset().equals(SerialRuleReset.SERIAL_REST_TYPE_YEAR.type)) {
+                     format = DateUtils.format(new Date(), "yyyy");
+                } else if (serialRule.getReset().equals(SerialRuleReset.SERIAL_REST_TYPE_MONTH.type)) {
+                     format = DateUtils.format(new Date(), "MM");
+                } else {
+                     format = DateUtils.format(new Date(), "dd");
+                }
+                //褰撳墠鍊艰嚜鍔ㄥ姞1
+                Integer curVal = serialRule.getCurrValue() + 1;
+                //瀛楃涓插乏杈硅嚜鍔犺ˉ0
+                String lef =  StringUtils.leftPad(curVal + "", serialRule.getMaxLen(), "0");
+                //鏈�杩戜竴娆℃祦姘村彿
+                result = format + lef;
+                //淇敼鏈�鍚庣紪鐮侊紝褰撳墠鍊�
+                serialRule.setCurrValue(curVal);
+
+                buffer.append(result);
+            } else if (rule.getWkType().equals(SerialRuleType.WK_DATE_FORMAT.wkType)) {
+                //鑾峰彇鏃堕棿14浣嶆牸寮忔椂闂村�紋yyyMMddHHmmss
+                String format = DateUtils.format(new Date(), DateUtils.YYYYMMDDHHMMSS_PATTER);
+                //鍒ゆ柇鏄惁璁剧疆鎴彇闀垮害鍜岃捣濮嬫埅鍙栦綅缃�
+                buffer.append(subStr(format, rule.getLenStr(), rule.getLen()));
+            } else if (rule.getWkType().equals(SerialRuleType.WK_FEILD.wkType)) {
+                String subStr = subStr(objectToMap(obj).get(rule.getFeildValue()).toString(), rule.getLenStr(), rule.getLen());
+                buffer.append(subStr);
+            }
+        });
+
+        serialRule.setLastCode(buffer.toString());
+        //淇敼褰撳墠瑙勫垯缂栫爜鍙疯嚦鏁版嵁搴�
+        if (!ruleService.saveOrUpdate(serialRule)) {
+            throw new CoolException("瑙勫垯缂栫爜淇濆瓨澶辫触锛侊紒");
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * @author Ryan
+     * @description 鏍规嵁瀛楁闀垮害鍙婏紝璧峰浣嶇疆鎴彇瀛楃涓�
+     * @throws
+     * @return
+     * @time 2025/3/5 13:00
+     */
+    public static String subStr(String str, Integer start, Integer end) {
+        StringBuffer buffer = new StringBuffer();
+        //鍒ゆ柇鏄惁璁剧疆鎴彇闀垮害鍜岃捣濮嬫埅鍙栦綅缃�
+        if (Objects.isNull(start) || end == 0) {
+            buffer.append(str);
+        } else {
+            if (str.length() <= (end + start)) {
+                throw new CoolException("鎴彇瀛楃璧峰嚭瀛楃涓查暱搴︼紝璇锋煡鐪嬭鍒欒瀹氾紒锛�");
+            }
+            //杩斿洖璧峰浣嶇疆lenStr寮�濮嬶紝缁堢偣浣嶇疆涓簂enStr + len闀垮害鐨勫瓧绗︿覆
+            String substring  = str.substring(start, (start + end));
+            buffer.append(substring);
+        }
+        return buffer.toString();
+    }
+
+
+    /**
+     * @author Ryan
+     * @description Object 杞� Map瀛楁
+     * @throws
+     * @return
+     * @time 2025/3/5 14:00
+     */
+    public static Map<?, ?> objectToMap (Object obj) {
+        if (obj == null) {
+            return null;
+        }
+        ObjectMapper objectMapper = new ObjectMapper();
+        Map<?, ?> mappedObject = objectMapper.convertValue(obj, Map.class);
+
+        return mappedObject;
+    }
+
+}

--
Gitblit v1.9.1