Browse Source

直播发货任务

yuhongqi 1 day ago
parent
commit
a71d17c4ab
27 changed files with 1453 additions and 40 deletions
  1. 76 8
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreHealthOrderScrmController.java
  2. 10 0
      fs-admin/src/main/java/com/fs/hisStore/task/LiveTask.java
  3. 6 0
      fs-admin/src/main/java/com/fs/hisStore/task/MallStoreTask.java
  4. 3 0
      fs-admin/src/main/java/com/fs/live/controller/LiveController.java
  5. 102 9
      fs-admin/src/main/java/com/fs/live/controller/LiveHealthOrderController.java
  6. 4 0
      fs-admin/src/main/java/com/fs/live/controller/LiveOrderController.java
  7. 1 1
      fs-company-app/src/main/resources/application.yml
  8. 7 4
      fs-company/src/main/java/com/fs/company/controller/live/LiveOrderController.java
  9. 12 9
      fs-service/src/main/java/com/fs/course/dto/FsOrderDeliveryNoteDTO.java
  10. 18 0
      fs-service/src/main/java/com/fs/course/dto/OrderOpenIdTransDTO.java
  11. 3 0
      fs-service/src/main/java/com/fs/hisStore/config/StoreConfig.java
  12. 2 0
      fs-service/src/main/java/com/fs/hisStore/domain/FsStoreOrderScrm.java
  13. 17 0
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderScrmMapper.java
  14. 11 0
      fs-service/src/main/java/com/fs/hisStore/service/IFsStoreOrderScrmService.java
  15. 264 0
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
  16. 38 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderCodeOpenIdVo.java
  17. 84 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderDeliveryNoteExportVO.java
  18. 3 1
      fs-service/src/main/java/com/fs/live/domain/LiveOrder.java
  19. 4 1
      fs-service/src/main/java/com/fs/live/dto/LiveOrderDeliveryNoteDTO.java
  20. 20 1
      fs-service/src/main/java/com/fs/live/mapper/LiveOrderMapper.java
  21. 17 0
      fs-service/src/main/java/com/fs/live/service/ILiveOrderService.java
  22. 275 3
      fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java
  23. 34 0
      fs-service/src/main/java/com/fs/live/vo/LiveOrderCodeOpenIdVo.java
  24. 81 0
      fs-service/src/main/java/com/fs/live/vo/LiveOrderDeliveryNoteExportVO.java
  25. 2 3
      fs-service/src/main/java/com/fs/live/vo/LiveOrderVoZm.java
  26. 163 0
      fs-service/src/main/resources/mapper/hisStore/FsStoreOrderScrmMapper.xml
  27. 196 0
      fs-service/src/main/resources/mapper/live/LiveOrderMapper.xml

+ 76 - 8
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreHealthOrderScrmController.java

@@ -22,10 +22,7 @@ import com.fs.his.vo.FsStoreOrderListAndStatisticsVo;
 import com.fs.hisStore.dto.StoreOrderProductDTO;
 import com.fs.hisStore.param.FsStoreOrderParam;
 import com.fs.hisStore.service.*;
-import com.fs.hisStore.vo.FsStoreOrderErpExportVO;
-import com.fs.hisStore.vo.FsStoreOrderExportVO;
-import com.fs.hisStore.vo.FsStoreOrderItemExportVO;
-import com.fs.hisStore.vo.FsStoreOrderVO;
+import com.fs.hisStore.vo.*;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -33,10 +30,8 @@ import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
+import java.text.SimpleDateFormat;
+import java.util.*;
 
 @RestController
 @RequestMapping("/store/store/storeOrder")
@@ -380,4 +375,77 @@ public class FsStoreHealthOrderScrmController extends BaseController {
         }
         return false;
     }
+
+    //订单发货批量导入
+    @Log(title = "发货同步导入", businessType = BusinessType.IMPORT)
+    @PostMapping("/importDeliveryNoteExpressWithApp")
+    public R importDeliveryNoteExpressWithApp(@RequestParam("file") MultipartFile file,@RequestParam("miniAppId") String miniAppId) {
+        // 1. 检查文件是否为空
+        if (file.isEmpty()) {
+            return R.error("上传的文件不能为空");
+        }
+        // 2. 检查文件大小
+        if (file.getSize() > MAX_FILE_SIZE) {
+            return R.error("文件大小不能超过5MB");
+        }
+        // 3. 检查文件扩展名
+        String fileName = file.getOriginalFilename();
+        if (fileName == null || !isValidExcelFile(fileName)) {
+            return R.error("请上传Excel文件(.xlsx或.xls格式)");
+        }
+
+        ExcelUtil<FsOrderDeliveryNoteDTO> util=new ExcelUtil<>(FsOrderDeliveryNoteDTO.class);
+        try {
+            List<FsOrderDeliveryNoteDTO> dtoList = util.importExcel(file.getInputStream());
+            if(!dtoList.isEmpty()){
+                if(dtoList.size() > 200){
+                    R.error("操作失败,导入数据不能大于200条!");
+                }
+                return fsStoreOrderService.importDeliveryNoteExpress(dtoList,miniAppId);
+            }else {
+                R.error("操作失败,导入数据不能小于1条!");
+            }
+        }catch (Exception e){
+            e.getStackTrace();
+        }
+        return R.ok();
+    }
+
+
+    /**
+     * 发货单导出接口
+     * **/
+    @PreAuthorize("@ss.hasPermi('store:storeOrder:healthExportShippingOrder')")
+    @GetMapping("/healthExportShippingOrder")
+    public AjaxResult healthExportShippingOrder(FsStoreOrderParam param){
+        if ("".equals(param.getBeginTime()) && "".equals(param.getEndTime())){
+            param.setBeginTime(null);
+            param.setEndTime(null);
+        }
+        if(fsStoreOrderService.isEntityNull(param)){
+            param = new FsStoreOrderParam();
+        }
+        if(!StringUtils.isEmpty(param.getCreateTimeRange())){
+            param.setCreateTimeList(param.getCreateTimeRange().split("--"));
+        }
+        if(!StringUtils.isEmpty(param.getPayTimeRange())){
+            param.setPayTimeList(param.getPayTimeRange().split("--"));
+        }
+        if(!StringUtils.isEmpty(param.getDeliverySendTimeRange())){
+            param.setDeliverySendTimeList(param.getDeliverySendTimeRange().split("--"));
+        }
+        if(!StringUtils.isEmpty(param.getDeliveryImportTimeRange())){
+            param.setDeliveryImportTimeList(param.getDeliveryImportTimeRange().split("--"));
+        }
+        param.setIsHealth("1");
+        List<FsStoreOrderDeliveryNoteExportVO> storeOrderDeliveryNoteExportVOList=fsStoreOrderService.getDeliveryNote(param);
+        ExcelUtil<FsStoreOrderDeliveryNoteExportVO> util = new ExcelUtil<>(FsStoreOrderDeliveryNoteExportVO.class);
+        //通过商品ID获取关键字
+        String firstKeyword = storeOrderDeliveryNoteExportVOList.stream()
+                .map(FsStoreOrderDeliveryNoteExportVO::getKeyword)
+                .findFirst()
+                .orElse("无订单");
+        String fileName="077AC"+firstKeyword+new SimpleDateFormat("yyyyMMdd").format(new Date());
+        return util.exportExcel(storeOrderDeliveryNoteExportVOList, fileName);
+    }
 }

+ 10 - 0
fs-admin/src/main/java/com/fs/hisStore/task/LiveTask.java

@@ -45,6 +45,8 @@ import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
 
 import java.text.ParseException;
 import java.time.LocalTime;
@@ -168,6 +170,14 @@ public class LiveTask {
         }
     }
 
+
+    //定时任务刷新微信订单结算状态
+    public void refreshOrderSettlementStatus(){
+        liveOrderService.refreshOrderSettlementStatus();
+    }
+
+
+
     //每5分钟执行一次
     public void deliveryOp() {
         List<LiveOrder> list = liveOrderService.selectUpdateExpress();

+ 6 - 0
fs-admin/src/main/java/com/fs/hisStore/task/MallStoreTask.java

@@ -231,6 +231,12 @@ public class MallStoreTask
     }
 
 
+    //定时任务刷新微信订单结算状态
+    public void refreshOrderSettlementStatus(){
+        fsStoreOrderService.refreshOrderSettlementStatus();
+    }
+
+
     public void storeProdUpdateCostPrice()
     {
         String json=configService.selectConfigByKey("store.config");

+ 3 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveController.java

@@ -7,6 +7,8 @@ import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.hisStore.task.LiveTask;
+import com.fs.hisStore.task.MallStoreTask;
 import com.fs.live.domain.Live;
 import com.fs.live.service.ILiveService;
 import com.fs.live.vo.LiveListVo;
@@ -14,6 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
+import java.text.ParseException;
 import java.util.List;
 import java.util.Map;
 

+ 102 - 9
fs-admin/src/main/java/com/fs/live/controller/LiveHealthOrderController.java

@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.CloudHostUtils;
@@ -23,20 +24,15 @@ import com.fs.live.param.LiveOrderParam;
 import com.fs.live.service.ILiveOrderDfService;
 import com.fs.live.service.ILiveOrderItemService;
 import com.fs.live.service.ILiveOrderService;
-import com.fs.live.vo.LiveOrderErpExportVO;
-import com.fs.live.vo.LiveOrderItemExportVO;
-import com.fs.live.vo.LiveOrderListAndStatisticsVo;
-import com.fs.live.vo.LiveOrderVO;
+import com.fs.live.vo.*;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**`
  * 订单Controller
@@ -318,9 +314,106 @@ public class LiveHealthOrderController extends BaseController {
         return util.exportExcel(list, "订单明细数据");
     }
 
+
+
+    // 允许的文件扩展名
+    private static final String[] ALLOWED_EXCEL_EXTENSIONS = {".xlsx", ".xls"};
+
+    // 最大文件大小(5MB)
+    private static final long MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
+
+    /**
+     * 下载订单发货导入模板
+     */
     @GetMapping("/importDeliveryNoteExpressTemplate")
-    public AjaxResult importTemplate() {
+    public AjaxResult importDeliveryNoteExpressTemplate() {
         ExcelUtil<LiveOrderDeliveryNoteDTO> util = new ExcelUtil<>(LiveOrderDeliveryNoteDTO.class);
         return util.importTemplateExcel("订单发货导入模板");
     }
+
+    /**
+     * 订单发货批量导入
+     */
+    @Log(title = "发货同步导入", businessType = BusinessType.IMPORT)
+    @PostMapping("/importDeliveryNoteExpress")
+    public R importDeliveryNoteExpress(@RequestParam("file") MultipartFile file, @RequestParam("miniAppId") String miniAppId) {
+        // 1. 检查文件是否为空
+        if (file.isEmpty()) {
+            return R.error("上传的文件不能为空");
+        }
+        // 2. 检查文件大小
+        if (file.getSize() > MAX_FILE_SIZE) {
+            return R.error("文件大小不能超过5MB");
+        }
+        // 3. 检查文件扩展名
+        String fileName = file.getOriginalFilename();
+        if (fileName == null || !isValidExcelFile(fileName)) {
+            return R.error("请上传Excel文件(.xlsx或.xls格式)");
+        }
+
+        ExcelUtil<LiveOrderDeliveryNoteDTO> util = new ExcelUtil<>(LiveOrderDeliveryNoteDTO.class);
+        try {
+            List<LiveOrderDeliveryNoteDTO> dtoList = util.importExcel(file.getInputStream());
+            if (!dtoList.isEmpty()) {
+                if (dtoList.size() > 200) {
+                    return R.error("操作失败,导入数据不能大于200条!");
+                }
+                return liveOrderService.importDeliveryNoteExpress(dtoList,miniAppId);
+            } else {
+                return R.error("操作失败,导入数据不能小于1条!");
+            }
+        } catch (Exception e) {
+            logger.error("导入发货单失败", e);
+            return R.error("导入失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 发货单导出接口
+     */
+    @PreAuthorize("@ss.hasPermi('live:liveOrder:healthExportShippingOrder')")
+    @Log(title = "发货单导出", businessType = BusinessType.EXPORT)
+    @GetMapping("/healthExportShippingOrder")
+    public AjaxResult healthExportShippingOrder(LiveOrderParam param) {
+        if ("".equals(param.getBeginTime()) && "".equals(param.getEndTime())) {
+            param.setBeginTime(null);
+            param.setEndTime(null);
+        }
+        if (liveOrderService.isEntityNull(param)) {
+            param = new LiveOrderParam();
+        }
+        if (!StringUtils.isEmpty(param.getCreateTimeRange())) {
+            param.setCreateTimeList(param.getCreateTimeRange().split("--"));
+        }
+        if (!StringUtils.isEmpty(param.getPayTimeRange())) {
+            param.setPayTimeList(param.getPayTimeRange().split("--"));
+        }
+        if (!StringUtils.isEmpty(param.getDeliverySendTimeRange())) {
+            param.setDeliverySendTimeList(param.getDeliverySendTimeRange().split("--"));
+        }
+        if (!StringUtils.isEmpty(param.getDeliveryImportTimeRange())) {
+            param.setDeliveryImportTimeList(param.getDeliveryImportTimeRange().split("--"));
+        }
+        List<LiveOrderDeliveryNoteExportVO> deliveryNoteExportVOList = liveOrderService.getDeliveryNote(param);
+        ExcelUtil<LiveOrderDeliveryNoteExportVO> util = new ExcelUtil<>(LiveOrderDeliveryNoteExportVO.class);
+        //通过商品ID获取关键字
+        String firstKeyword = deliveryNoteExportVOList.stream()
+                .map(LiveOrderDeliveryNoteExportVO::getKeyword)
+                .findFirst()
+                .orElse("无订单");
+        String fileName = "077AC" + firstKeyword + new java.text.SimpleDateFormat("yyyyMMdd").format(new Date());
+        return util.exportExcel(deliveryNoteExportVOList, fileName);
+    }
+
+    /**
+     * 检查文件是否为有效的Excel文件
+     */
+    private boolean isValidExcelFile(String fileName) {
+        for (String ext : ALLOWED_EXCEL_EXTENSIONS) {
+            if (fileName.toLowerCase().endsWith(ext)) {
+                return true;
+            }
+        }
+        return false;
+    }
 }

+ 4 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveOrderController.java

@@ -35,7 +35,10 @@ import com.fs.hisStore.param.*;
 import com.fs.hisStore.vo.FsStoreOrderVO;
 import com.fs.live.domain.*;
 import com.fs.live.dto.LiveOrderCustomerExportDTO;
+import com.fs.live.dto.LiveOrderDeliveryNoteDTO;
 import com.fs.live.dto.LiveOrderExpressExportDTO;
+import com.fs.live.param.LiveOrderParam;
+import com.fs.live.vo.LiveOrderDeliveryNoteExportVO;
 import com.fs.live.enums.LiveOrderCancleReason;
 import com.fs.live.param.LiveOrderScrmSetErpPhoneParam;
 import com.fs.live.service.*;
@@ -52,6 +55,7 @@ import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
 import java.text.ParseException;

+ 1 - 1
fs-company-app/src/main/resources/application.yml

@@ -6,4 +6,4 @@ server:
 spring:
   profiles:
 #    active: druid-fcky-test
-    active: dev-jnlzjk
+    active: druid-bjzm-test

+ 7 - 4
fs-company/src/main/java/com/fs/company/controller/live/LiveOrderController.java

@@ -28,6 +28,7 @@ import com.fs.live.service.ILiveOrderPaymentService;
 import com.fs.live.service.ILiveOrderService;
 import com.fs.live.vo.LiveGoodsVo;
 import com.fs.live.vo.LiveOrderTimeVo;
+import com.fs.live.vo.LiveOrderVoZm;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -117,8 +118,9 @@ public class LiveOrderController extends BaseController
     public TableDataInfo listZm(LiveOrder liveOrder)
     {
         startPage();
-        List<LiveOrder> list = liveOrderService.selectLiveOrderList(liveOrder);
-        for (LiveOrder vo : list){
+        liveOrder.setCompanyId(SecurityUtils.getLoginUser().getUser().getCompanyId());
+        List<LiveOrderVoZm> list = liveOrderService.selectLiveOrderListZm(liveOrder);
+        for (LiveOrderVoZm vo : list){
             vo.setUserPhone(ParseUtils.parsePhone(vo.getUserPhone()));
         }
         return getDataTable(list);
@@ -132,8 +134,9 @@ public class LiveOrderController extends BaseController
     @GetMapping("/exportZm")
     public AjaxResult exportZm(LiveOrder liveOrder)
     {
-        List<LiveOrder> list = liveOrderService.selectLiveOrderList(liveOrder);
-        ExcelUtil<LiveOrder> util = new ExcelUtil<LiveOrder>(LiveOrder.class);
+        liveOrder.setCompanyId(SecurityUtils.getLoginUser().getUser().getCompanyId());
+        List<LiveOrderVoZm> list = liveOrderService.selectLiveOrderListZm(liveOrder);
+        ExcelUtil<LiveOrderVoZm> util = new ExcelUtil<LiveOrderVoZm>(LiveOrderVoZm.class);
         return util.exportExcel(list, "订单数据");
     }
 

+ 12 - 9
fs-service/src/main/java/com/fs/course/dto/FsOrderDeliveryNoteDTO.java

@@ -13,33 +13,36 @@ public class FsOrderDeliveryNoteDTO {
     /**
      * 系统订单号
      * **/
-    @Excel(name = "系统订单号(必填)",width = 20,sort = 1)
+    @Excel(name = "原始单号",width = 20,sort = 1)
     private String orderNumber;
 
-    @Excel(name = "物流公司编号(必填)(SF:顺丰、EMS:邮政、ZTO:中通、JD:京东、DBL:德邦)",width = 30,sort = 2)
+//    @Excel(name = "物流公司",width = 30,sort = 2)
     private String deliverySn;
 
+    @Excel(name = "物流公司",width = 10,sort = 10)
+    private String logisticsCompany;
+
     private String deliveryName;
 
-    @Excel(name = "快递单号(必填)",width = 20,sort = 3)
+    @Excel(name = "快递单号",width = 20,sort = 23)
     private String deliveryId;
 
-    @Excel(name = "物流状态(0:暂无信息、1:已揽收、2:在途中、3:签收、4:问题件)",width = 40,sort = 4)
+//    @Excel(name = "物流状态(0:暂无信息、1:已揽收、2:在途中、3:签收、4:问题件)",width = 40,sort = 4)
     private Integer deliveryStatus;
 
-    @Excel(name = "物流结算费用",width = 20,sort = 5)
+//    @Excel(name = "物流结算费用",width = 20,sort = 5)
     private BigDecimal deliveryPayMoney;
 
-    @Excel(name = "物流跟踪状态(311:快递柜或驿站签收、304:派件异常后最终签收、301:正常签收、211:已放入快递柜或驿站、202:派件中、201:到达派件城市、401:发货无信息、412:快递柜或驿站超时未取、407:退货未签收)",width = 40,sort = 6)
+//    @Excel(name = "物流跟踪状态(311:快递柜或驿站签收、304:派件异常后最终签收、301:正常签收、211:已放入快递柜或驿站、202:派件中、201:到达派件城市、401:发货无信息、412:快递柜或驿站超时未取、407:退货未签收)",width = 40,sort = 6)
     private Integer deliveryType;
 
-    @Excel(name = "物流结算状态(1:已结算、2:冻结、3:解冻、4:退回运费、5.调账)",width = 20,sort = 7)
+//    @Excel(name = "物流结算状态(1:已结算、2:冻结、3:解冻、4:退回运费、5.调账)",width = 20,sort = 7)
     private Integer deliveryPayStatus;
 
-    @Excel(name = "快递账单日期",width = 20,sort = 8)
+//    @Excel(name = "快递账单日期",width = 20,sort = 8)
     private String deliveryTime;
 
-    @Excel(name = "快递结算日期",width = 20,sort = 9)
+//    @Excel(name = "快递结算日期",width = 20,sort = 9)
     private String deliveryPayTime;
 
 //    /**

+ 18 - 0
fs-service/src/main/java/com/fs/course/dto/OrderOpenIdTransDTO.java

@@ -0,0 +1,18 @@
+package com.fs.course.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class OrderOpenIdTransDTO implements Serializable {
+    /**
+     * 用户微信openId
+     * **/
+    private String openId;
+
+    /**
+     * 交易单号
+     * **/
+    private String transactionId;
+}

+ 3 - 0
fs-service/src/main/java/com/fs/hisStore/config/StoreConfig.java

@@ -25,4 +25,7 @@ public class StoreConfig implements Serializable {
     private Integer createSalesOrderType; // 订单改价方式 1 商品改价 2总价改价
     private Boolean isBrushOrders;//是否开启刷单按钮
     private Integer orderAttribution; // 下单归属 1 多销售 2单销售
+    private Boolean isWeChatShipping;//是否开启微信发货
+    private Boolean scanCodeDiscountEnabled;//是否开启扫码立减金
+    private BigDecimal scanCodeDiscountAmount;//扫码立减金额
 }

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsStoreOrderScrm.java

@@ -351,4 +351,6 @@ public class FsStoreOrderScrm extends BaseEntity
     private BigDecimal billPrice;
     private String erpPhone;
 
+    @TableField(exist = false)
+    private String bankTransactionId;
 }

+ 17 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderScrmMapper.java

@@ -1378,4 +1378,21 @@ public interface FsStoreOrderScrmMapper
 
     @Select("select * from fs_store_order_scrm where  `status`=2 and (extend_order_id is not null and extend_order_id != '') and (delivery_id is not null and delivery_id != '')")
     List<FsStoreOrderScrm> selectShippedOrder();
+    /**
+     * 获取发货单数据
+     * @param maps 查询参数
+     * @return list
+     * **/
+    List<FsStoreOrderDeliveryNoteExportVO> getDeliveryNote(@Param("maps") FsStoreOrderParam maps);
+    /**
+     * 获取订单用户信息
+     * @param list 订单号
+     * @return lsit
+     * **/
+    List<FsStoreOrderCodeOpenIdVo> selectOrderCodeOpenIdInOrderCode(@Param("list") List<String> list);
+    /**
+     * 获取未结算订单
+     * **/
+    List<FsStoreOrderScrm> getUnsettledOrder();
+
 }

+ 11 - 0
fs-service/src/main/java/com/fs/hisStore/service/IFsStoreOrderScrmService.java

@@ -320,4 +320,15 @@ public interface IFsStoreOrderScrmService
     R dfOrderResult(String body);
 
     R receiveWaybillPush(String body);
+
+    /**
+     * 获取发货单数据
+     * @param param 查询条件
+     * @return list
+     * **/
+    List<FsStoreOrderDeliveryNoteExportVO> getDeliveryNote(FsStoreOrderParam param);
+
+    R importDeliveryNoteExpress(List<FsOrderDeliveryNoteDTO> dtoList, String miniAppId);
+
+    void refreshOrderSettlementStatus();
 }

+ 264 - 0
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -1,6 +1,8 @@
 package com.fs.hisStore.service.impl;
 
 import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
+import cn.binarywang.wx.miniapp.bean.shop.request.shipping.*;
+import cn.binarywang.wx.miniapp.bean.shop.response.WxMaOrderShippingInfoGetResponse;
 import cn.hutool.core.date.DateTime;
 import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.hutool.core.net.URLDecoder;
@@ -46,6 +48,7 @@ import com.fs.core.config.WxMaConfiguration;
 import com.fs.core.config.WxPayProperties;
 import com.fs.core.utils.OrderCodeUtils;
 import com.fs.course.dto.FsOrderDeliveryNoteDTO;
+import com.fs.course.dto.OrderOpenIdTransDTO;
 import com.fs.erp.domain.*;
 import com.fs.erp.dto.*;
 import com.fs.erp.dto.df.*;
@@ -4710,6 +4713,254 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         return null;
     }
 
+    @Override
+    public List<FsStoreOrderDeliveryNoteExportVO> getDeliveryNote(FsStoreOrderParam param) {
+        return fsStoreOrderMapper.getDeliveryNote(param);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public R importDeliveryNoteExpress(List<FsOrderDeliveryNoteDTO> dtoList, String appId) {
+        try {
+            StringBuilder builder = new StringBuilder();
+            //获取商城配置
+            String json = configService.selectConfigByKey("store.config");
+            StoreConfig config = JSONUtil.toBean(json, StoreConfig.class);
+
+            List<FsOrderDeliveryNoteDTO> successList = new ArrayList<>(dtoList.size());
+            //提前获取所有必要数据
+            Map<String, String> expressDeliveryMap = buildExpressDeliveryMap();
+            //提取所有有效订单号
+            List<String> orderCodeList = new ArrayList<>(dtoList.size());
+            for (int i = 0; i < dtoList.size(); i++) {
+                FsOrderDeliveryNoteDTO dto = dtoList.get(i);
+                if (StringUtils.isEmpty(dto.getOrderNumber())) {
+                    builder.append("数据第").append(i + 2).append("行系统订单为空!").append(System.lineSeparator());
+                }
+                if (StringUtils.isEmpty(dto.getLogisticsCompany())) {
+                    builder.append("数据第").append(i + 2).append("行物流公司为空!").append(System.lineSeparator());
+                }
+                if (StringUtils.isEmpty(dto.getDeliveryId())) {
+                    builder.append("数据第").append(i + 2).append("行快递单号为空!").append(System.lineSeparator());
+                } else {
+                    //处理订单ID信息
+                    String originalOrderNumber = dto.getOrderNumber();
+                    String processedOrderNumber = extractNumbers(originalOrderNumber);
+                    dto.setOrderNumber(processedOrderNumber);
+                    orderCodeList.add(dto.getOrderNumber());
+                }
+            }
+
+            //批量查询订单信息
+            if (orderCodeList.isEmpty()) {
+                return R.ok(builder.toString());
+            }
+            List<FsStoreOrderCodeOpenIdVo> orderCodeOpenIdVoList = fsStoreOrderMapper.selectOrderCodeOpenIdInOrderCode(orderCodeList);
+            Map<String, OrderOpenIdTransDTO> orderMap = new HashMap<>(orderCodeOpenIdVoList.size());
+            Map<String, List<FsStoreOrderCodeOpenIdVo>> orderDetailsMap = new HashMap<>(orderCodeOpenIdVoList.size());
+
+            for (FsStoreOrderCodeOpenIdVo vo : orderCodeOpenIdVoList) {
+                orderMap.computeIfAbsent(vo.getId(), k -> {
+                    OrderOpenIdTransDTO dto = new OrderOpenIdTransDTO();
+                    dto.setOpenId(vo.getOpenId());
+                    dto.setTransactionId(vo.getOutTransId());
+                    return dto;
+                });
+
+                orderDetailsMap
+                        .computeIfAbsent(vo.getId(), k -> new ArrayList<>())
+                        .add(vo);
+            }
+            final WxMaService wxService = WxMaConfiguration.getMaService(appId);
+            String uploadTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"))
+                    .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+
+            for (int i = 0; i < dtoList.size(); i++) {
+                FsOrderDeliveryNoteDTO dto = dtoList.get(i);
+                int rowNum = i + 2;
+                if (StringUtils.isEmpty(dto.getOrderNumber())) {
+                    continue;
+                }
+                if (StringUtils.isEmpty(dto.getDeliveryId())) {
+                    builder.append("数据第").append(rowNum).append("行快递单号为空!")
+                            .append(System.lineSeparator());
+                    continue;
+                }
+
+                if (StringUtils.isEmpty(dto.getLogisticsCompany())) {
+                    builder.append("数据第").append(rowNum).append("行快递公司编号为空!")
+                            .append(System.lineSeparator());
+                    continue;
+                }
+//                if (dto.getDeliveryStatus() == null) {
+//                    dto.setDeliveryStatus(0);
+//                }
+//                if (ObjectUtil.isNotNull(dto.getDeliveryTime())) {
+//                    dto.setDeliveryTime(parseCstToDateOnlyString(dto.getDeliveryTime()));
+//                }
+//
+//                if (ObjectUtil.isNotNull(dto.getDeliveryPayTime()) &&
+//                        !dto.getDeliveryPayTime().isEmpty()) {
+//                    dto.setDeliveryPayTime(parseCstToDateOnlyString(dto.getDeliveryPayTime()));
+//                }
+                // 验证快递公司
+                String deliverySn = expressDeliveryMap.get(dto.getLogisticsCompany());
+                if (deliverySn == null) {
+                    builder.append("数据第").append(rowNum).append("行订单号为")
+                            .append(dto.getOrderNumber()).append("物流公司名称异常")
+                            .append(System.lineSeparator());
+                    continue;
+                }
+                dto.setDeliverySn(deliverySn);
+
+                // 检查订单是否存在
+                String orderNumber = dto.getOrderNumber();
+                OrderOpenIdTransDTO orderInfo = orderMap.get(orderNumber);
+                if (orderInfo == null) {
+                    builder.append("数据第").append(rowNum).append("行订单号")
+                            .append(orderNumber).append("不存在").append(System.lineSeparator());
+                    continue;
+                }
+                //验证是否开启微信发货
+                if (config.getIsWeChatShipping() != null && config.getIsWeChatShipping()) {
+                    // 上传物流信息到微信
+                    List<FsStoreOrderCodeOpenIdVo> orderDetails = orderDetailsMap.get(orderNumber);
+                    if (uploadShippingInfoToWechat(wxService, orderInfo, orderDetails, dto, uploadTime)) {
+                        successList.add(dto);
+                    } else {
+                        builder.append("数据第").append(rowNum).append("行订单号为")
+                                .append(orderNumber).append("上传微信失败").append(System.lineSeparator());
+                    }
+                } else {
+                    successList.add(dto);
+                }
+            }
+
+            //批量更新数据
+            if (!successList.isEmpty()) {
+                batchUpdateDeliveryNotes(successList);
+            }
+
+            return R.ok(builder.toString().equals("") ? "操作成功!" : builder.toString());
+        } catch (Exception e) {
+            log.error("导入发货单快递信息失败", e);
+            return R.error("导入失败:" + e.getMessage());
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
+    public void refreshOrderSettlementStatus() {
+        try {
+            // 判断是否对接微信发货
+            String json = configService.selectConfigByKey("store.config");
+            StoreConfig config = JSONUtil.toBean(json, StoreConfig.class);
+            logger.info("进入微信结算订单定时任务--------------->{}", "start");
+            if (config != null && config.getIsWeChatShipping() != null && config.getIsWeChatShipping()) {
+                // 获取未结算订单
+                List<FsStoreOrderScrm> orderScrmList = fsStoreOrderMapper.getUnsettledOrder();
+
+                String payConfig = configService.selectConfigByKey("store.pay");
+                JSONObject js = JSON.parseObject(payConfig);
+                String appId = js.getString("appId");
+
+                if (ObjectUtil.isNotNull(appId) && !appId.isEmpty()) {
+                    final WxMaService wxService = WxMaConfiguration.getMaService(appId);
+
+                    if (!orderScrmList.isEmpty()) {
+                        for (FsStoreOrderScrm order : orderScrmList) {
+                            WxMaOrderShippingInfoGetRequest request = new WxMaOrderShippingInfoGetRequest();
+                            request.setTransactionId(order.getBankTransactionId());
+                            WxMaOrderShippingInfoGetResponse response;
+
+                            try {
+                                response = wxService.getWxMaOrderShippingService().get(request);
+
+                                if (response.getErrCode().equals(0)) {
+                                    // 订单状态枚举:(1) 待发货;(2) 已发货;(3) 确认收货;(4) 交易完成;(5) 已退款
+                                    if (response.getOrder().getOrderState().equals(3) || response.getOrder().getOrderState().equals(4)) {
+                                        if (order.getStatus() == OrderInfoEnum.STATUS_2.getValue()) {
+                                            this.finishOrder(order.getId());
+                                        }
+                                    }
+                                    logger.info("请求信息------------------------》{}", response);
+                                }
+
+                            } catch (WxErrorException e) {
+                                logger.info("异常信息------------------------》{}", e.getMessage());
+                                continue;
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.getStackTrace();
+        } finally {
+            logger.info("进入微信结算订单定时任务--------------->{}", "end");
+        }
+    }
+
+    private void batchUpdateDeliveryNotes(List<FsOrderDeliveryNoteDTO> list) {
+        int batchSize = 500;
+        int total = list.size();
+        int batches = (total + batchSize - 1) / batchSize;
+        for (int i = 0; i < batches; i++) {
+            int start = i * batchSize;
+            int end = Math.min(start + batchSize, total);
+            List<FsOrderDeliveryNoteDTO> subList = list.subList(start, end);
+            fsStoreOrderMapper.batchUpdateInOrderCode(subList);
+        }
+    }
+
+    private boolean uploadShippingInfoToWechat(WxMaService wxService,
+                                               OrderOpenIdTransDTO orderInfo,
+                                               List<FsStoreOrderCodeOpenIdVo> orderDetails,
+                                               FsOrderDeliveryNoteDTO dto,
+                                               String uploadTime) {
+        try {
+            WxMaOrderShippingInfoUploadRequest request = new WxMaOrderShippingInfoUploadRequest();
+            OrderKeyBean orderKeyBean = new OrderKeyBean();
+            orderKeyBean.setOrderNumberType(2);
+            orderKeyBean.setTransactionId(orderInfo.getTransactionId());
+            request.setOrderKey(orderKeyBean);
+            request.setDeliveryMode(1);
+            request.setLogisticsType(1);
+            List<ShippingListBean> shippingList = new ArrayList<>(orderDetails.size());
+            ShippingListBean shippingListBean = null;
+            for (FsStoreOrderCodeOpenIdVo detail : orderDetails) {
+                if (shippingListBean == null) {
+                    shippingListBean = new ShippingListBean();
+                    shippingListBean.setTrackingNo(dto.getDeliveryId());
+                    shippingListBean.setExpressCompany(dto.getDeliverySn());
+                    JSONObject js = JSON.parseObject(detail.getJsonInfo());
+                    shippingListBean.setItemDesc(js.getString("productName"));
+                    ContactBean contactBean = new ContactBean();
+                    contactBean.setReceiverContact(detail.getPhone());
+                    shippingListBean.setContact(contactBean);
+                } else {
+                    //拼接
+//                    JSONObject js = JSON.parseObject(detail.getJsonInfo());
+//                    shippingListBean.setItemDesc(shippingListBean.getItemDesc()+"-"+js.getString("productName"));
+                    break;
+                }
+            }
+            shippingList.add(shippingListBean);
+            request.setShippingList(shippingList);
+            request.setUploadTime(uploadTime);
+            // 设置支付者信息
+            PayerBean payerBean = new PayerBean();
+            payerBean.setOpenid(orderInfo.getOpenId());
+            request.setPayer(payerBean);
+
+            // 上传物流信息
+            return wxService.getWxMaOrderShippingService().upload(request).getErrCode() == 0;
+        } catch (Exception e) {
+            log.error("上传物流信息到微信失败,订单号: {}", dto.getOrderNumber(), e);
+            return false;
+        }
+    }
+
     private static final DateTimeFormatter CST_FORMATTER = DateTimeFormatter
             .ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US)
             .withZone(ZoneId.of("Asia/Shanghai"));
@@ -4749,6 +5000,19 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         return map;
     }
 
+    //高性能截取订单ID
+    private static String extractNumbers(String str) {
+        if (str == null || str.isEmpty()) {
+            return "";
+        }
+        int start = 0;
+        int len = str.length();
+        while (start < len && !Character.isDigit(str.charAt(start))) {
+            start++;
+        }
+        return start < len ? str.substring(start) : "";
+    }
+
 
     @Override
     public FsStoreOrderAmountScrmStatsVo selectFsStoreOrderAmountScrmStats(FsStoreOrderAmountScrmStatsQueryDto queryDto) {

+ 38 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderCodeOpenIdVo.java

@@ -0,0 +1,38 @@
+package com.fs.hisStore.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class FsStoreOrderCodeOpenIdVo implements Serializable {
+//    /**
+//     * 订单编码
+//     * **/
+//    private String orderCode;
+
+    /**
+     * 订单id
+     * **/
+    private String id;
+
+    /**
+     * 用户openId
+     * **/
+    private String openId;
+
+    /**
+     * 用户手机号
+     * **/
+    private String phone;
+
+    /**
+     * 商品详情信息
+     * **/
+    private String jsonInfo;
+
+    /**
+     * 交易单号
+     * **/
+    private String outTransId;
+}

+ 84 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderDeliveryNoteExportVO.java

@@ -0,0 +1,84 @@
+package com.fs.hisStore.vo;
+
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 发货单导出(商城订单)
+ * **/
+@Data
+public class FsStoreOrderDeliveryNoteExportVO implements Serializable {
+    //系统订单号
+    @Excel(name = "原始单号",width = 20,sort = 1)
+    private String orderNumber;
+
+    @Excel(name = "收件人",width = 10,sort = 2)
+    private String recipient;
+
+    @Excel(name = "收件人手机",width = 20,sort = 3)
+    private String recipientPhone;
+
+    @Excel(name = "收件人电话",width = 20,sort = 4)
+    private String recipientTelephone;
+
+    //具体到某个街道和小区
+    @Excel(name = "收件人详细地址",width = 30,sort = 5)
+    private String recipientAddress;
+
+//    //省市区
+//    @Excel(name = "收货地址",width = 20,sort = 6)
+//    private String receivingAddress;
+
+    //编号和数量:662551*2
+    @Excel(name = "组合编号及数量",width = 20,sort = 7)
+    private String number;
+
+    //名称和数量:商品名称*2
+    @Excel(name = "组合名称及数量",width = 20,sort = 8)
+    private String nameAndNumber;
+
+    @Excel(name = "代收金额",width = 10,sort = 9)
+    private BigDecimal collectionAmount;
+
+    @Excel(name = "物流公司",width = 10,sort = 10)
+    private String logisticsCompany;
+
+    @Excel(name = "物流产品",width = 10,sort = 11)
+    private String logisticsProduct;
+
+    @Excel(name = "物流付款方式",width = 15,sort = 12)
+    private String logisticsPayMethod;
+
+    @Excel(name = "包裹数",width = 10,sort = 13)
+    private Long packageNum;
+
+    @Excel(name = "寄件人",width = 10,sort = 14)
+    private String sender;
+
+    @Excel(name = "寄件人手机",width = 20,sort = 15)
+    private String senderPhone;
+
+    @Excel(name = "寄件人电话",width = 20,sort = 16)
+    private String senderTelephone;
+
+    @Excel(name = "寄件公司",width = 10,sort = 17)
+    private String senderCompany;
+
+    //具体到某个街道和小区
+    @Excel(name = "寄件人详细地址",width = 30,sort = 18)
+    private String senderAddress;
+
+    @Excel(name = "出库仓库",width = 10,sort = 19)
+    private String outboundWarehouse;
+
+    @Excel(name = "订单付款方式",width = 10,sort = 20)
+    private String payMethod;
+
+    @Excel(name = "订单备注",width = 20,sort = 21)
+    private String orderNotes;
+
+    private String keyword;
+}

+ 3 - 1
fs-service/src/main/java/com/fs/live/domain/LiveOrder.java

@@ -1,5 +1,6 @@
 package com.fs.live.domain;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fs.common.annotation.Excel;
 import com.fs.common.core.domain.BaseEntity;
@@ -344,6 +345,7 @@ public class LiveOrder extends BaseEntity {
 
     private Integer price;
     private Integer cost;
-
+    @TableField(exist = false)
+    private String bankTransactionId;
 
 }

+ 4 - 1
fs-service/src/main/java/com/fs/live/dto/LiveOrderDeliveryNoteDTO.java

@@ -16,9 +16,12 @@ public class LiveOrderDeliveryNoteDTO {
     @Excel(name = "系统订单号(必填)",width = 20,sort = 1)
     private String orderNumber;
 
-    @Excel(name = "物流公司编号(必填)(SF:顺丰、EMS:邮政、ZTO:中通、JD:京东、DBL:德邦)",width = 30,sort = 2)
+//    @Excel(name = "物流公司编号(必填)(SF:顺丰、EMS:邮政、ZTO:中通、JD:京东、DBL:德邦)",width = 30,sort = 2)
     private String deliverySn;
 
+    @Excel(name = "物流公司(必填)(SF:顺丰、EMS:邮政、ZTO:中通、JD:京东、DBL:德邦)",width = 10,sort = 10)
+    private String logisticsCompany;
+
     private String deliveryName;
 
     @Excel(name = "快递单号(必填)",width = 20,sort = 3)

+ 20 - 1
fs-service/src/main/java/com/fs/live/mapper/LiveOrderMapper.java

@@ -2,6 +2,7 @@ package com.fs.live.mapper;
 
 
 import com.fs.live.domain.LiveOrder;
+import com.fs.live.dto.LiveOrderDeliveryNoteDTO;
 import com.fs.live.param.FsMyLiveOrderQueryParam;
 import com.fs.live.param.LiveOrderParam;
 import com.fs.live.vo.*;
@@ -109,7 +110,7 @@ public interface LiveOrderMapper {
     @Select("select order_id from live_order where `status` = 2")
     List<Long> selectSyncExpressIds();
 
-    @Select("select order_id from live_order where `status` = 2 and extend_order_id is null ")
+    @Select("select order_id from live_order where `status` = 1 and extend_order_id is null ")
     List<Long> selectOrderIdByNoErp();
 
     @Select("select * from live_order where extend_order_id is not null and `status`=2")
@@ -425,4 +426,22 @@ public interface LiveOrderMapper {
 
     @Select("select * from live_order where  `status`=2 and (extend_order_id is not null and extend_order_id != '') and (delivery_id is not null and delivery_id != '')")
     List<LiveOrder> selectShippedOrder();
+
+    List<LiveOrder> getUnsettledOrder();
+
+
+    List<LiveOrderDeliveryNoteExportVO> getDeliveryNote(@Param("maps") LiveOrderParam param);
+
+    /**
+     * 根据订单号批量查询订单信息(包含openId和transactionId)
+     * @param list 订单号列表
+     * @return 订单信息列表
+     */
+    List<LiveOrderCodeOpenIdVo> selectLiveOrderCodeOpenIdInOrderCode(@Param("list") List<String> list);
+
+    /**
+     * 批量更新订单物流信息
+     * @param dtoList 物流信息列表
+     */
+    void batchUpdateInOrderCode(@Param("list") List<LiveOrderDeliveryNoteDTO> dtoList);
 }

+ 17 - 0
fs-service/src/main/java/com/fs/live/service/ILiveOrderService.java

@@ -9,8 +9,10 @@ import com.fs.hisStore.vo.FsStoreOrderVO;
 import com.fs.live.domain.LiveAfterSales;
 import com.fs.live.domain.LiveOrder;
 import com.fs.live.dto.LiveOrderComputeDTO;
+import com.fs.live.dto.LiveOrderDeliveryNoteDTO;
 import com.fs.live.param.*;
 import com.fs.live.vo.*;
+import com.fs.live.vo.LiveOrderDeliveryNoteExportVO;
 import com.fs.store.domain.FsStoreDelivers;
 import org.springframework.web.bind.annotation.RequestBody;
 
@@ -238,4 +240,19 @@ public interface ILiveOrderService {
     R handleLiveOrderPay(LiveOrderPayParam param);
 
     List<LiveOrder> selectLiveOrderItemJson();
+
+    void refreshOrderSettlementStatus();
+
+    /**
+     * 批量导入更新直播订单发货状态
+     * @param dtoList 订单数据
+     * **/
+    R importDeliveryNoteExpress(List<LiveOrderDeliveryNoteDTO> dtoList,String appId);
+
+    /**
+     * 获取发货单数据
+     * @param param 查询条件
+     * @return list
+     * **/
+    List<LiveOrderDeliveryNoteExportVO> getDeliveryNote(LiveOrderParam param);
 }

+ 275 - 3
fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java

@@ -7,12 +7,16 @@ import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
+import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.shop.request.shipping.*;
+import cn.binarywang.wx.miniapp.bean.shop.response.WxMaOrderShippingInfoGetResponse;
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.util.IdUtil;
@@ -45,7 +49,10 @@ import com.fs.company.service.ICompanyDeptService;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.service.ICompanyUserService;
 import com.fs.config.cloud.CloudHostProper;
+import com.fs.core.config.WxMaConfiguration;
 import com.fs.core.utils.OrderCodeUtils;
+import com.fs.course.dto.FsOrderDeliveryNoteDTO;
+import com.fs.course.dto.OrderOpenIdTransDTO;
 import com.fs.erp.domain.*;
 import com.fs.erp.dto.*;
 import com.fs.erp.mapper.FsErpFinishPushMapper;
@@ -70,9 +77,7 @@ import com.fs.hisStore.mapper.FsStoreProductScrmMapper;
 import com.fs.hisStore.mapper.FsUserScrmMapper;
 import com.fs.hisStore.param.*;
 import com.fs.hisStore.service.*;
-import com.fs.hisStore.vo.FsMyStoreOrderListQueryVO;
-import com.fs.hisStore.vo.FsStoreOrderItemVO;
-import com.fs.hisStore.vo.FsStoreOrderVO;
+import com.fs.hisStore.vo.*;
 import com.fs.huifuPay.domain.HuiFuCreateOrder;
 import com.fs.huifuPay.domain.HuiFuRefundResult;
 import com.fs.huifuPay.domain.HuifuCreateOrderResult;
@@ -81,6 +86,7 @@ import com.fs.huifuPay.service.HuiFuService;
 import com.fs.live.domain.*;
 import com.fs.live.dto.LiveOrderComputeDTO;
 import com.fs.live.dto.LiveOrderCustomerExportDTO;
+import com.fs.live.dto.LiveOrderDeliveryNoteDTO;
 import com.fs.live.dto.LiveOrderItemDTO;
 import com.fs.live.mapper.*;
 import com.fs.live.param.*;
@@ -97,6 +103,7 @@ import com.github.binarywang.wxpay.config.WxPayConfig;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.WxPayService;
 import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.error.WxErrorException;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang.ObjectUtils;
 import org.apache.http.util.Asserts;
@@ -674,6 +681,7 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
 
             order.setStatus(OrderInfoEnum.STATUS_1.getValue());
             order.setPayTime(LocalDateTime.now());
+            order.setIsPay("1");
             baseMapper.updateLiveOrder(order);
             return "SUCCESS";
         }catch (Exception e){
@@ -1507,7 +1515,13 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
         if (!StringUtils.isEmpty(order.getExtendOrderId()) && order.getStatus() != 1) {
             return R.error("订单:" + order.getOrderCode() + ",已推送erp/订单状态不正确");
         }
+        if(order.getUserName() == null || StringUtils.isEmpty(order.getUserName())) return R.error("用户信息为空");
         ErpOrder erpOrder = getErpOrder(order);
+        if(erpOrder == null ){
+            log.info("组合码为空,订单ID:" + order.getOrderCode());
+            return R.error("组合码为空");
+        }
+
         if (erpOrderService == jSTOrderService) {
             erpOrder.setShop_code(erpConfig.getErpJstShopCode());
         }
@@ -1616,6 +1630,7 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
         for (LiveOrderItem orderItem : orderItems) {
             FsStoreProduct cartDTO = JSONUtil.toBean(orderItem.getJsonInfo(), FsStoreProduct.class);
             ErpOrderItem item = new ErpOrderItem();
+            if(cartDTO.getBarCode() == null) return null;
             item.setItem_code(cartDTO.getBarCode() == null ? "" : cartDTO.getBarCode().trim());
             item.setPrice(cartDTO.getPrice() == null ? "" : cartDTO.getPrice().toString());
             // todo yhq 需要检查
@@ -2896,6 +2911,263 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
         return baseMapper.selectLiveOrderItemJson();
     }
 
+    @Override
+    @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
+    public void refreshOrderSettlementStatus() {
+        try {
+            // 判断是否对接微信发货
+            String json = configService.selectConfigByKey("store.config");
+            StoreConfig config = JSONUtil.toBean(json, StoreConfig.class);
+            log.info("进入微信结算订单定时任务--------------->{}", "start");
+            if (config != null && config.getIsWeChatShipping() != null && config.getIsWeChatShipping()) {
+                // 获取未结算订单
+                List<LiveOrder> orderScrmList = liveOrderMapper.getUnsettledOrder();
+
+                String payConfig = configService.selectConfigByKey("store.pay");
+                JSONObject js = JSON.parseObject(payConfig);
+                String appId = js.getString("appId");
+
+                if (ObjectUtil.isNotNull(appId) && !appId.isEmpty()) {
+                    final WxMaService wxService = WxMaConfiguration.getMaService(appId);
+
+                    if (!orderScrmList.isEmpty()) {
+                        for (LiveOrder order : orderScrmList) {
+                            WxMaOrderShippingInfoGetRequest request = new WxMaOrderShippingInfoGetRequest();
+                            request.setTransactionId(order.getBankTransactionId());
+                            WxMaOrderShippingInfoGetResponse response;
+
+                            try {
+                                response = wxService.getWxMaOrderShippingService().get(request);
+
+                                if (response.getErrCode().equals(0)) {
+                                    // 订单状态枚举:(1) 待发货;(2) 已发货;(3) 确认收货;(4) 交易完成;(5) 已退款
+                                    if (response.getOrder().getOrderState().equals(3) || response.getOrder().getOrderState().equals(4)) {
+                                        if (order.getStatus() == OrderInfoEnum.STATUS_2.getValue()) {
+                                            this.finishOrder(order.getOrderId());
+                                        }
+                                    }
+                                    log.info("请求信息------------------------》{}", response);
+                                }
+
+                            } catch (WxErrorException e) {
+                                log.info("异常信息------------------------》{}", e.getMessage());
+                                continue;
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.getStackTrace();
+        } finally {
+            log.info("进入微信结算订单定时任务--------------->{}", "end");
+        }
+    }
+
+
+    @Override
+    public R importDeliveryNoteExpress(List<LiveOrderDeliveryNoteDTO> dtoList,String appId) {
+        try {
+            StringBuilder builder = new StringBuilder();
+            //获取商城配置
+            String json = configService.selectConfigByKey("store.config");
+            StoreConfig config = JSONUtil.toBean(json, StoreConfig.class);
+
+            List<LiveOrderDeliveryNoteDTO> successList = new ArrayList<>(dtoList.size());
+            //提前获取所有必要数据
+            Map<String, String> expressDeliveryMap = buildExpressDeliveryMap();
+            //提取所有有效订单号
+            List<String> orderCodeList = new ArrayList<>(dtoList.size());
+            for (int i = 0; i < dtoList.size(); i++) {
+                LiveOrderDeliveryNoteDTO dto = dtoList.get(i);
+                if (StringUtils.isEmpty(dto.getOrderNumber())) {
+                    builder.append("数据第").append(i + 2).append("行系统订单为空!").append(System.lineSeparator());
+                }
+                if (StringUtils.isEmpty(dto.getLogisticsCompany())) {
+                    builder.append("数据第").append(i + 2).append("行物流公司为空!").append(System.lineSeparator());
+                }
+                if (StringUtils.isEmpty(dto.getDeliveryId())) {
+                    builder.append("数据第").append(i + 2).append("行快递单号为空!").append(System.lineSeparator());
+                } else {
+                    //处理订单ID信息
+                    String originalOrderNumber = dto.getOrderNumber();
+                    String processedOrderNumber = extractNumbers(originalOrderNumber);
+                    dto.setOrderNumber(processedOrderNumber);
+                    orderCodeList.add(dto.getOrderNumber());
+                }
+            }
+
+            //批量查询订单信息
+            if (orderCodeList.isEmpty()) {
+                return R.ok(builder.toString());
+            }
+            List<LiveOrderCodeOpenIdVo> orderCodeOpenIdVoList = baseMapper.selectLiveOrderCodeOpenIdInOrderCode(orderCodeList);
+            Map<String, OrderOpenIdTransDTO> orderMap = new HashMap<>(orderCodeOpenIdVoList.size());
+            Map<String, List<LiveOrderCodeOpenIdVo>> orderDetailsMap = new HashMap<>(orderCodeOpenIdVoList.size());
+
+            for (LiveOrderCodeOpenIdVo vo : orderCodeOpenIdVoList) {
+                orderMap.computeIfAbsent(vo.getId(), k -> {
+                    OrderOpenIdTransDTO dto = new OrderOpenIdTransDTO();
+                    dto.setOpenId(vo.getOpenId());
+                    dto.setTransactionId(vo.getOutTransId());
+                    return dto;
+                });
+
+                orderDetailsMap
+                        .computeIfAbsent(vo.getId(), k -> new ArrayList<>())
+                        .add(vo);
+            }
+            final WxMaService wxService = WxMaConfiguration.getMaService(appId);
+            String uploadTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"))
+                    .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+
+            for (int i = 0; i < dtoList.size(); i++) {
+                LiveOrderDeliveryNoteDTO dto = dtoList.get(i);
+                int rowNum = i + 2;
+                if (StringUtils.isEmpty(dto.getOrderNumber())) {
+                    continue;
+                }
+                if (StringUtils.isEmpty(dto.getDeliveryId())) {
+                    builder.append("数据第").append(rowNum).append("行快递单号为空!")
+                            .append(System.lineSeparator());
+                    continue;
+                }
+
+                if (StringUtils.isEmpty(dto.getLogisticsCompany())) {
+                    builder.append("数据第").append(rowNum).append("行快递公司编号为空!")
+                            .append(System.lineSeparator());
+                    continue;
+                }
+                // 验证快递公司
+                String deliverySn = expressDeliveryMap.get(dto.getLogisticsCompany());
+                if (deliverySn == null) {
+                    builder.append("数据第").append(rowNum).append("行订单号为")
+                            .append(dto.getOrderNumber()).append("物流公司名称异常")
+                            .append(System.lineSeparator());
+                    continue;
+                }
+                dto.setDeliverySn(deliverySn);
+
+                // 检查订单是否存在
+                String orderNumber = dto.getOrderNumber();
+                OrderOpenIdTransDTO orderInfo = orderMap.get(orderNumber);
+                if (orderInfo == null) {
+                    builder.append("数据第").append(rowNum).append("行订单号")
+                            .append(orderNumber).append("不存在").append(System.lineSeparator());
+                    continue;
+                }
+                //验证是否开启微信发货
+                if (config.getIsWeChatShipping() != null && config.getIsWeChatShipping()) {
+                    // 上传物流信息到微信
+                    List<LiveOrderCodeOpenIdVo> orderDetails = orderDetailsMap.get(orderNumber);
+                    if (uploadShippingInfoToWechat(wxService, orderInfo, orderDetails, dto, uploadTime)) {
+                        successList.add(dto);
+                    } else {
+                        builder.append("数据第").append(rowNum).append("行订单号为")
+                                .append(orderNumber).append("上传微信失败").append(System.lineSeparator());
+                    }
+                } else {
+                    successList.add(dto);
+                }
+            }
+
+            //批量更新数据
+            if (!successList.isEmpty()) {
+                batchUpdateDeliveryNotes(successList);
+            }
+
+            return R.ok(builder.toString().equals("") ? "操作成功!" : builder.toString());
+        } catch (Exception e) {
+            log.error("导入发货单快递信息失败", e);
+            return R.error("导入失败:" + e.getMessage());
+        }
+    }
+
+    private void batchUpdateDeliveryNotes(List<LiveOrderDeliveryNoteDTO> list) {
+        int batchSize = 500;
+        int total = list.size();
+        int batches = (total + batchSize - 1) / batchSize;
+        for (int i = 0; i < batches; i++) {
+            int start = i * batchSize;
+            int end = Math.min(start + batchSize, total);
+            List<LiveOrderDeliveryNoteDTO> subList = list.subList(start, end);
+            baseMapper.batchUpdateInOrderCode(subList);
+        }
+    }
+
+    private boolean uploadShippingInfoToWechat(WxMaService wxService,
+                                               OrderOpenIdTransDTO orderInfo,
+                                               List<LiveOrderCodeOpenIdVo> orderDetails,
+                                               LiveOrderDeliveryNoteDTO dto,
+                                               String uploadTime) {
+        try {
+            WxMaOrderShippingInfoUploadRequest request = new WxMaOrderShippingInfoUploadRequest();
+            OrderKeyBean orderKeyBean = new OrderKeyBean();
+            orderKeyBean.setOrderNumberType(2);
+            orderKeyBean.setTransactionId(orderInfo.getTransactionId());
+            request.setOrderKey(orderKeyBean);
+            request.setDeliveryMode(1);
+            request.setLogisticsType(1);
+            List<ShippingListBean> shippingList = new ArrayList<>(orderDetails.size());
+            ShippingListBean shippingListBean = null;
+            for (LiveOrderCodeOpenIdVo detail : orderDetails) {
+                if (shippingListBean == null) {
+                    shippingListBean = new ShippingListBean();
+                    shippingListBean.setTrackingNo(dto.getDeliveryId());
+                    shippingListBean.setExpressCompany(dto.getDeliverySn());
+                    JSONObject js = JSON.parseObject(detail.getJsonInfo());
+                    shippingListBean.setItemDesc(js.getString("productName"));
+                    ContactBean contactBean = new ContactBean();
+                    contactBean.setReceiverContact(detail.getPhone());
+                    shippingListBean.setContact(contactBean);
+                } else {
+                    break;
+                }
+            }
+            shippingList.add(shippingListBean);
+            request.setShippingList(shippingList);
+            request.setUploadTime(uploadTime);
+            // 设置支付者信息
+            PayerBean payerBean = new PayerBean();
+            payerBean.setOpenid(orderInfo.getOpenId());
+            request.setPayer(payerBean);
+
+            // 上传物流信息
+            return wxService.getWxMaOrderShippingService().upload(request).getErrCode() == 0;
+        } catch (Exception e) {
+            log.error("上传物流信息到微信失败,订单号: {}", dto.getOrderNumber(), e);
+            return false;
+        }
+    }
+
+    public Map<String, String> buildExpressDeliveryMap() {
+        Map<String, String> map = new HashMap<>();
+        map.put("SF", "顺丰");
+        map.put("EMS", "邮政");
+        map.put("ZTO", "中通");
+        map.put("JD", "京东");
+        map.put("DBL", "德邦");
+        return map;
+    }
+
+    //高性能截取订单ID
+    private static String extractNumbers(String str) {
+        if (str == null || str.isEmpty()) {
+            return "";
+        }
+        int start = 0;
+        int len = str.length();
+        while (start < len && !Character.isDigit(str.charAt(start))) {
+            start++;
+        }
+        return start < len ? str.substring(start) : "";
+    }
+
+    @Override
+    public List<LiveOrderDeliveryNoteExportVO> getDeliveryNote(LiveOrderParam param) {
+        return baseMapper.getDeliveryNote(param);
+    }
+
 
     @Override
     @Transactional(rollbackFor = Throwable.class,propagation = Propagation.REQUIRED)

+ 34 - 0
fs-service/src/main/java/com/fs/live/vo/LiveOrderCodeOpenIdVo.java

@@ -0,0 +1,34 @@
+package com.fs.live.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class LiveOrderCodeOpenIdVo implements Serializable {
+    /**
+     * 订单id
+     * **/
+    private String id;
+
+    /**
+     * 用户openId
+     * **/
+    private String openId;
+
+    /**
+     * 用户手机号
+     * **/
+    private String phone;
+
+    /**
+     * 商品详情信息
+     * **/
+    private String jsonInfo;
+
+    /**
+     * 交易单号
+     * **/
+    private String outTransId;
+}
+

+ 81 - 0
fs-service/src/main/java/com/fs/live/vo/LiveOrderDeliveryNoteExportVO.java

@@ -0,0 +1,81 @@
+package com.fs.live.vo;
+
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 发货单导出(直播订单)
+ * **/
+@Data
+public class LiveOrderDeliveryNoteExportVO implements Serializable {
+    //系统订单号
+    @Excel(name = "原始单号",width = 20,sort = 1)
+    private String orderNumber;
+
+    @Excel(name = "收件人",width = 10,sort = 2)
+    private String recipient;
+
+    @Excel(name = "收件人手机",width = 20,sort = 3)
+    private String recipientPhone;
+
+    @Excel(name = "收件人电话",width = 20,sort = 4)
+    private String recipientTelephone;
+
+    //具体到某个街道和小区
+    @Excel(name = "收件人详细地址",width = 30,sort = 5)
+    private String recipientAddress;
+
+    //编号和数量:662551*2
+    @Excel(name = "组合编号及数量",width = 20,sort = 7)
+    private String number;
+
+    //名称和数量:商品名称*2
+    @Excel(name = "组合名称及数量",width = 20,sort = 8)
+    private String nameAndNumber;
+
+    @Excel(name = "代收金额",width = 10,sort = 9)
+    private BigDecimal collectionAmount;
+
+    @Excel(name = "物流公司",width = 10,sort = 10)
+    private String logisticsCompany;
+
+    @Excel(name = "物流产品",width = 10,sort = 11)
+    private String logisticsProduct;
+
+    @Excel(name = "物流付款方式",width = 15,sort = 12)
+    private String logisticsPayMethod;
+
+    @Excel(name = "包裹数",width = 10,sort = 13)
+    private Long packageNum;
+
+    @Excel(name = "寄件人",width = 10,sort = 14)
+    private String sender;
+
+    @Excel(name = "寄件人手机",width = 20,sort = 15)
+    private String senderPhone;
+
+    @Excel(name = "寄件人电话",width = 20,sort = 16)
+    private String senderTelephone;
+
+    @Excel(name = "寄件公司",width = 10,sort = 17)
+    private String senderCompany;
+
+    //具体到某个街道和小区
+    @Excel(name = "寄件人详细地址",width = 30,sort = 18)
+    private String senderAddress;
+
+    @Excel(name = "出库仓库",width = 10,sort = 19)
+    private String outboundWarehouse;
+
+    @Excel(name = "订单付款方式",width = 10,sort = 20)
+    private String payMethod;
+
+    @Excel(name = "订单备注",width = 20,sort = 21)
+    private String orderNotes;
+
+    private String keyword;
+}
+

+ 2 - 3
fs-service/src/main/java/com/fs/live/vo/LiveOrderVoZm.java

@@ -121,7 +121,6 @@ public class LiveOrderVoZm{
 
     /** 支付时间 */
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    @Excel(name = "支付时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime payTime;
 
 
@@ -391,8 +390,8 @@ public class LiveOrderVoZm{
 //    @Excel(name = "是否改价")
     private Integer isEditMoney;
 
-    /** 创建时间*/
-//    @Excel(name = "创建时间")
+    /** 创建时间 (下单时间)*/
+    @Excel(name = "下单时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
 
     /** 更新时间*/

+ 163 - 0
fs-service/src/main/resources/mapper/hisStore/FsStoreOrderScrmMapper.xml

@@ -1896,4 +1896,167 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             AND company_user_id = #{companyUserId}
         </if>
     </select>
+
+    <select id="getDeliveryNote" resultType="com.fs.hisStore.vo.FsStoreOrderDeliveryNoteExportVO">
+        SELECT
+        CONCAT('AC', o.id) AS orderNumber,
+        o.real_name AS recipient,
+        o.user_phone AS recipientPhone,
+        o.user_address AS recipientAddress,
+        GROUP_CONCAT(
+        DISTINCT IFNULL(
+        CASE WHEN LENGTH(sps.product_name) > 0
+        THEN CONCAT(sps.product_name, '*', sois.num)
+        END, ''
+        )
+        SEPARATOR '+'
+        ) AS nameAndNumber,
+        sps.keyword
+        FROM
+        fs_store_order_scrm o
+        LEFT JOIN fs_store_order_item_scrm sois
+        ON sois.order_id = o.id
+        LEFT JOIN fs_store_product_scrm sps
+        ON sps.product_id = sois.product_id
+        LEFT JOIN fs_user u
+        ON o.user_id = u.user_id
+        LEFT JOIN company c
+        ON c.company_id = o.company_id
+        LEFT JOIN company_user cu
+        ON cu.user_id = o.company_user_id
+        LEFT JOIN (
+        SELECT DISTINCT order_id
+        FROM fs_store_payment_scrm
+        WHERE is_pay_remain != 0 AND STATUS != 0
+        ) fp
+        ON o.id = fp.order_id
+        WHERE
+        o.is_del = 0 and
+        1 = 1
+        <if test="maps.orderCode != null and maps.orderCode != ''">
+            AND o.order_code LIKE CONCAT('%', #{maps.orderCode}, '%')
+        </if>
+        <if test="maps.userId != null">
+            AND o.user_id = #{maps.userId}
+        </if>
+        <if test="maps.deliveryId != null and maps.deliveryId != ''">
+            AND o.delivery_id = #{maps.deliveryId}
+        </if>
+        <if test="maps.nickname != null and maps.nickname != ''">
+            AND u.nickname LIKE CONCAT('%', #{maps.nickname}, '%')
+        </if>
+        <if test="maps.realName != null and maps.realName != ''">
+            AND o.real_name LIKE CONCAT('%', #{maps.realName}, '%')
+        </if>
+        <if test="maps.phone != null and maps.phone != ''">
+            AND u.phone LIKE CONCAT('%', #{maps.phone}, '%')
+        </if>
+        <if test="maps.userPhone != null and maps.userPhone != ''">
+            AND o.user_phone LIKE CONCAT('%', #{maps.userPhone}, '%')
+        </if>
+        <if test="maps.status == null">
+            AND o.status = 1
+        </if>
+        <if test="maps.status != null">
+            AND o.status = #{maps.status}
+        </if>
+        <if test="maps.deliveryStatus != null">
+            AND o.delivery_status = #{maps.deliveryStatus}
+        </if>
+        <if test="maps.deliveryPayStatus != null">
+            AND o.delivery_pay_status = #{maps.deliveryPayStatus}
+        </if>
+        <if test="maps.companyId != null">
+            AND o.company_id = #{maps.companyId}
+        </if>
+        <if test="maps.isHealth != null and maps.isHealth != ''">
+            AND o.company_id IS NULL
+        </if>
+        <if test="maps.notHealth != null and maps.notHealth != ''">
+            AND o.company_id IS NOT NULL
+        </if>
+        <if test="maps.companyUserId != null">
+            AND o.company_user_id = #{maps.companyUserId}
+        </if>
+        <if test="maps.companyUserNickName != null and maps.companyUserNickName != ''">
+            AND cu.nick_name LIKE CONCAT('%', #{maps.companyUserNickName}, '%')
+        </if>
+        <if test="maps.orderType != null">
+            AND o.order_type = #{maps.orderType}
+        </if>
+        <if test="maps.payType != null">
+            AND o.pay_type = #{maps.payType}
+        </if>
+        <if test="maps.createTimeList != null">
+            AND o.create_time >= STR_TO_DATE(#{maps.createTimeList[0]}, '%Y%m%d')
+            AND o.create_time &lt; DATE_ADD(STR_TO_DATE(#{maps.createTimeList[1]}, '%Y%m%d'), INTERVAL 1 DAY)
+        </if>
+        <if test="maps.payTimeList != null">
+            AND o.pay_time >= STR_TO_DATE(#{maps.payTimeList[0]}, '%Y%m%d')
+            AND o.pay_time &lt; DATE_ADD(STR_TO_DATE(#{maps.payTimeList[1]}, '%Y%m%d'), INTERVAL 1 DAY)
+        </if>
+        <if test="maps.deliverySendTimeList != null">
+            AND o.delivery_send_time >= STR_TO_DATE(#{maps.deliverySendTimeList[0]}, '%Y%m%d')
+            AND o.delivery_send_time &lt; DATE_ADD(STR_TO_DATE(#{maps.deliverySendTimeList[1]}, '%Y%m%d'), INTERVAL 1 DAY)
+        </if>
+        <if test="maps.deliveryImportTimeList != null">
+            AND o.delivery_import_time >= STR_TO_DATE(#{maps.deliveryImportTimeList[0]}, '%Y%m%d')
+            AND o.delivery_import_time &lt; DATE_ADD(STR_TO_DATE(#{maps.deliveryImportTimeList[1]}, '%Y%m%d'), INTERVAL 1 DAY)
+        </if>
+        <if test="maps.deptId != null">
+            AND (o.dept_id = #{maps.deptId}
+            OR o.dept_id IN (SELECT t.dept_id FROM company_dept t WHERE FIND_IN_SET(#{maps.deptId}, t.ancestors)))
+        </if>
+        <if test="maps.isUpload != null and maps.isUpload == 0">
+            AND o.certificates IS NULL
+        </if>
+        <if test="maps.scheduleId != null">
+            AND o.schedule_id = #{maps.scheduleId}
+        </if>
+        <if test="maps.isUpload != null and maps.isUpload == 1">
+            AND o.certificates IS NOT NULL
+        </if>
+        ${maps.params.dataScope}
+        AND o.paid = 1
+        GROUP BY o.id
+        LIMIT 10000;
+    </select>
+
+    <select id="selectOrderCodeOpenIdInOrderCode" resultType="com.fs.hisStore.vo.FsStoreOrderCodeOpenIdVo">
+        SELECT
+        os.id,
+        fu.phone,
+        fu.ma_open_id openId,
+        ois.json_info,
+        sps.bank_transaction_id outTransId
+        FROM
+        fs_store_order_scrm os
+        INNER JOIN fs_user fu ON os.user_id = fu.user_id
+        INNER JOIN fs_store_order_item_scrm ois ON ois.order_id = os.id
+        INNER JOIN fs_store_payment_scrm sps ON os.id=sps.order_id
+        WHERE os.is_del = 0 and os.id IN <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
+        #{item}
+    </foreach>
+        AND  sps.`status` = 1
+    </select>
+
+    <select id="getUnsettledOrder" resultType="com.fs.hisStore.domain.FsStoreOrderScrm">
+        SELECT
+            sos.*,
+            sps.bank_transaction_id
+        FROM
+            fs_store_order_scrm sos
+                INNER JOIN fs_store_payment_scrm sps ON sos.id = sps.order_id
+        WHERE
+            sos.is_del = 0 and
+            sos.paid = 1
+          AND sps.business_type = 2
+          AND sos.`status` = 2
+          AND sps.`status`=1
+          AND DATEDIFF(
+                      NOW(),
+                      sos.delivery_send_time
+              ) >= 3
+    </select>
+
 </mapper>

+ 196 - 0
fs-service/src/main/resources/mapper/live/LiveOrderMapper.xml

@@ -1070,4 +1070,200 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </where>
         ORDER BY o.create_time DESC
     </select>
+
+    <select id="getUnsettledOrder" resultType="com.fs.live.domain.LiveOrder">
+        SELECT
+            sos.*,
+            sps.bank_transaction_id
+        FROM
+            live_order sos
+                INNER JOIN live_order_payment sps ON sos.id = sps.order_id
+        WHERE
+            sos.is_del = 0 and
+            sos.is_pay = 1
+          AND sps.business_type = 2
+          AND sos.`status` = 2
+          AND sps.`status`=1
+          AND DATEDIFF(
+                      NOW(),
+                      sos.delivery_send_time
+              ) >= 3
+    </select>
+
+    <select id="getDeliveryNote" resultType="com.fs.live.vo.LiveOrderDeliveryNoteExportVO">
+        SELECT
+        CONCAT('AC', o.id) AS orderNumber,
+        o.user_name AS recipient,
+        o.user_phone AS recipientPhone,
+        o.user_address AS recipientAddress,
+        GROUP_CONCAT(
+        DISTINCT IFNULL(
+        CASE WHEN LENGTH(sps.product_name) > 0
+        THEN CONCAT(sps.product_name, '*', sois.num)
+        END, ''
+        )
+        SEPARATOR '+'
+        ) AS nameAndNumber,
+        sps.keyword
+        FROM
+        live_order o
+        LEFT JOIN live_order_item sois
+        ON sois.order_id = o.order_id
+        LEFT JOIN fs_store_product_scrm sps
+        ON sps.product_id = sois.product_id
+        LEFT JOIN fs_user u
+        ON o.user_id = u.user_id
+        LEFT JOIN company c
+        ON c.company_id = o.company_id
+        LEFT JOIN company_user cu
+        ON cu.user_id = o.company_user_id
+        LEFT JOIN (
+        SELECT DISTINCT order_id
+        FROM live_order_payment
+        WHERE is_pay_remain != 0 AND STATUS != 0
+        ) fp
+        ON o.id = fp.order_id
+        WHERE
+        o.is_del = 0 and
+        1 = 1
+        <if test="maps.orderCode != null and maps.orderCode != ''">
+            AND o.order_code LIKE CONCAT('%', #{maps.orderCode}, '%')
+        </if>
+        <if test="maps.userId != null">
+            AND o.user_id = #{maps.userId}
+        </if>
+        <if test="maps.deliveryId != null and maps.deliveryId != ''">
+            AND o.delivery_id = #{maps.deliveryId}
+        </if>
+        <if test="maps.nickname != null and maps.nickname != ''">
+            AND u.nickname LIKE CONCAT('%', #{maps.nickname}, '%')
+        </if>
+        <if test="maps.realName != null and maps.realName != ''">
+            AND o.user_name LIKE CONCAT('%', #{maps.realName}, '%')
+        </if>
+        <if test="maps.phone != null and maps.phone != ''">
+            AND u.phone LIKE CONCAT('%', #{maps.phone}, '%')
+        </if>
+        <if test="maps.userPhone != null and maps.userPhone != ''">
+            AND o.user_phone LIKE CONCAT('%', #{maps.userPhone}, '%')
+        </if>
+        <if test="maps.status == null">
+            AND o.status = 1
+        </if>
+        <if test="maps.status != null">
+            AND o.status = #{maps.status}
+        </if>
+        <if test="maps.deliveryStatus != null">
+            AND o.delivery_status = #{maps.deliveryStatus}
+        </if>
+        <if test="maps.deliveryPayStatus != null">
+            AND o.delivery_pay_status = #{maps.deliveryPayStatus}
+        </if>
+        <if test="maps.companyId != null">
+            AND o.company_id = #{maps.companyId}
+        </if>
+        <if test="maps.isHealth != null and maps.isHealth != ''">
+            AND o.company_id IS NULL
+        </if>
+        <if test="maps.notHealth != null and maps.notHealth != ''">
+            AND o.company_id IS NOT NULL
+        </if>
+        <if test="maps.companyUserId != null">
+            AND o.company_user_id = #{maps.companyUserId}
+        </if>
+        <if test="maps.companyUserNickName != null and maps.companyUserNickName != ''">
+            AND cu.nick_name LIKE CONCAT('%', #{maps.companyUserNickName}, '%')
+        </if>
+        <if test="maps.orderType != null">
+            AND o.order_type = #{maps.orderType}
+        </if>
+        <if test="maps.payType != null">
+            AND o.pay_type = #{maps.payType}
+        </if>
+        <if test="maps.createTimeList != null">
+            AND o.create_time >= STR_TO_DATE(#{maps.createTimeList[0]}, '%Y%m%d')
+            AND o.create_time &lt; DATE_ADD(STR_TO_DATE(#{maps.createTimeList[1]}, '%Y%m%d'), INTERVAL 1 DAY)
+        </if>
+        <if test="maps.payTimeList != null">
+            AND o.pay_time >= STR_TO_DATE(#{maps.payTimeList[0]}, '%Y%m%d')
+            AND o.pay_time &lt; DATE_ADD(STR_TO_DATE(#{maps.payTimeList[1]}, '%Y%m%d'), INTERVAL 1 DAY)
+        </if>
+        <if test="maps.deliverySendTimeList != null">
+            AND o.delivery_send_time >= STR_TO_DATE(#{maps.deliverySendTimeList[0]}, '%Y%m%d')
+            AND o.delivery_send_time &lt; DATE_ADD(STR_TO_DATE(#{maps.deliverySendTimeList[1]}, '%Y%m%d'), INTERVAL 1 DAY)
+        </if>
+        <if test="maps.deliveryImportTimeList != null">
+            AND o.delivery_import_time >= STR_TO_DATE(#{maps.deliveryImportTimeList[0]}, '%Y%m%d')
+            AND o.delivery_import_time &lt; DATE_ADD(STR_TO_DATE(#{maps.deliveryImportTimeList[1]}, '%Y%m%d'), INTERVAL 1 DAY)
+        </if>
+        <if test="maps.deptId != null">
+            AND (o.dept_id = #{maps.deptId}
+            OR o.dept_id IN (SELECT t.dept_id FROM company_dept t WHERE FIND_IN_SET(#{maps.deptId}, t.ancestors)))
+        </if>
+        <if test="maps.isUpload != null and maps.isUpload == 0">
+            AND o.certificates IS NULL
+        </if>
+        <if test="maps.scheduleId != null">
+            AND o.schedule_id = #{maps.scheduleId}
+        </if>
+        <if test="maps.isUpload != null and maps.isUpload == 1">
+            AND o.certificates IS NOT NULL
+        </if>
+        ${maps.params.dataScope}
+        AND o.paid = 1
+        GROUP BY o.id
+        LIMIT 10000;
+    </select>
+
+    <select id="selectLiveOrderCodeOpenIdInOrderCode" resultType="com.fs.live.vo.LiveOrderCodeOpenIdVo">
+        SELECT
+        os.order_id as id,
+        fu.phone,
+        fu.ma_open_id openId,
+        ois.json_info,
+        lop.bank_transaction_id outTransId
+        FROM
+        live_order os
+        INNER JOIN fs_user fu ON os.user_id = fu.user_id
+        INNER JOIN live_order_item ois ON ois.order_id = os.order_id
+        INNER JOIN live_order_payment lop ON os.order_id = lop.business_id
+        WHERE os.is_del = 0 and os.order_code IN
+        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        AND lop.`status` = 1
+    </select>
+
+    <update id="batchUpdateInOrderCode">
+        UPDATE live_order
+        <set>
+            delivery_sn = CASE
+            <foreach collection="list" item="item">
+                WHEN order_code = #{item.orderNumber} THEN #{item.deliverySn}
+            </foreach>
+            ELSE delivery_sn
+            END,
+            delivery_name = CASE
+            <foreach collection="list" item="item">
+                WHEN order_code = #{item.orderNumber} THEN #{item.logisticsCompany}
+            </foreach>
+            ELSE delivery_name
+            END,
+            delivery_id = CASE
+            <foreach collection="list" item="item">
+                WHEN order_code = #{item.orderNumber} THEN #{item.deliveryId}
+            </foreach>
+            ELSE delivery_id
+            END,
+            status = CASE
+            WHEN status = 1 THEN 2
+            ELSE status
+            END,
+            delivery_send_time = NOW()
+        </set>
+        WHERE order_code IN
+        <foreach collection="list" item="item" open="(" separator="," close=")">
+            #{item.orderNumber}
+        </foreach>
+    </update>
 </mapper>