Просмотр исходного кода

Merge branch 'master' of http://1.14.104.71:10880/root/ylrz_his_scrm_java

15376779826 2 недель назад
Родитель
Сommit
9f5060316f
68 измененных файлов с 3210 добавлено и 327 удалено
  1. 76 8
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreHealthOrderScrmController.java
  2. 512 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. 4 3
      fs-admin/src/main/java/com/fs/live/controller/LiveController.java
  5. 12 0
      fs-admin/src/main/java/com/fs/live/controller/LiveDataController.java
  6. 102 9
      fs-admin/src/main/java/com/fs/live/controller/LiveHealthOrderController.java
  7. 6 9
      fs-admin/src/main/java/com/fs/live/controller/LiveOrderController.java
  8. 0 183
      fs-admin/src/main/java/com/fs/task/LiveTask.java
  9. 1 1
      fs-company-app/src/main/resources/application.yml
  10. 30 0
      fs-company/src/main/java/com/fs/company/controller/course/FsUserCoursePeriodController.java
  11. 7 4
      fs-company/src/main/java/com/fs/company/controller/live/LiveOrderController.java
  12. 2 1
      fs-service/src/main/java/com/fs/course/dto/FsCourseQuestionBankImportDTO.java
  13. 12 9
      fs-service/src/main/java/com/fs/course/dto/FsOrderDeliveryNoteDTO.java
  14. 18 0
      fs-service/src/main/java/com/fs/course/dto/OrderOpenIdTransDTO.java
  15. 9 0
      fs-service/src/main/java/com/fs/course/mapper/FsUserCoursePeriodDaysMapper.java
  16. 3 0
      fs-service/src/main/java/com/fs/course/mapper/FsUserCoursePeriodMapper.java
  17. 2 0
      fs-service/src/main/java/com/fs/course/param/FsCourseWatchLogListParam.java
  18. 4 0
      fs-service/src/main/java/com/fs/course/service/IFsUserCoursePeriodService.java
  19. 13 7
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseQuestionBankServiceImpl.java
  20. 78 24
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCoursePeriodDaysServiceImpl.java
  21. 11 0
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCoursePeriodServiceImpl.java
  22. 38 15
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  23. 3 0
      fs-service/src/main/java/com/fs/course/vo/UpdateCourseTimeVo.java
  24. 435 5
      fs-service/src/main/java/com/fs/erp/service/impl/DfOrderServiceImpl.java
  25. 4 1
      fs-service/src/main/java/com/fs/erp/service/impl/ErpOrderServiceImpl.java
  26. 137 0
      fs-service/src/main/java/com/fs/erp/service/impl/HzOMSErpOrderServiceImpl.java
  27. 151 1
      fs-service/src/main/java/com/fs/erp/service/impl/K9OrderScrmServiceImpl.java
  28. 181 1
      fs-service/src/main/java/com/fs/erp/service/impl/WdtErpOrderServiceImpl.java
  29. 3 3
      fs-service/src/main/java/com/fs/his/service/impl/FsIntegralOrderServiceImpl.java
  30. 3 0
      fs-service/src/main/java/com/fs/his/service/impl/FsPrescribeServiceImpl.java
  31. 1 1
      fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java
  32. 3 0
      fs-service/src/main/java/com/fs/hisStore/config/StoreConfig.java
  33. 2 0
      fs-service/src/main/java/com/fs/hisStore/domain/FsMenuScrm.java
  34. 2 0
      fs-service/src/main/java/com/fs/hisStore/domain/FsStoreOrderScrm.java
  35. 17 0
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderScrmMapper.java
  36. 7 6
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductScrmMapper.java
  37. 11 0
      fs-service/src/main/java/com/fs/hisStore/service/IFsStoreOrderScrmService.java
  38. 264 0
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
  39. 38 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderCodeOpenIdVo.java
  40. 84 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderDeliveryNoteExportVO.java
  41. 3 1
      fs-service/src/main/java/com/fs/live/domain/LiveOrder.java
  42. 4 1
      fs-service/src/main/java/com/fs/live/dto/LiveOrderDeliveryNoteDTO.java
  43. 2 0
      fs-service/src/main/java/com/fs/live/mapper/LiveMapper.java
  44. 29 1
      fs-service/src/main/java/com/fs/live/mapper/LiveOrderMapper.java
  45. 19 0
      fs-service/src/main/java/com/fs/live/service/ILiveOrderService.java
  46. 3 0
      fs-service/src/main/java/com/fs/live/service/ILiveService.java
  47. 280 3
      fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java
  48. 21 0
      fs-service/src/main/java/com/fs/live/service/impl/LiveServiceImpl.java
  49. 1 0
      fs-service/src/main/java/com/fs/live/vo/LiveDataListVo.java
  50. 1 0
      fs-service/src/main/java/com/fs/live/vo/LiveDataStatisticsVo.java
  51. 34 0
      fs-service/src/main/java/com/fs/live/vo/LiveOrderCodeOpenIdVo.java
  52. 81 0
      fs-service/src/main/java/com/fs/live/vo/LiveOrderDeliveryNoteExportVO.java
  53. 2 3
      fs-service/src/main/java/com/fs/live/vo/LiveOrderVoZm.java
  54. 5 2
      fs-service/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java
  55. 2 0
      fs-service/src/main/java/com/fs/statis/dto/ModifyMoreDTO.java
  56. 2 2
      fs-service/src/main/resources/application-druid-bjzm-test.yml
  57. 2 2
      fs-service/src/main/resources/application-druid-bjzm.yml
  58. 3 1
      fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml
  59. 4 0
      fs-service/src/main/resources/mapper/course/FsUserCoursePeriodDaysMapper.xml
  60. 6 0
      fs-service/src/main/resources/mapper/course/FsUserCoursePeriodMapper.xml
  61. 6 1
      fs-service/src/main/resources/mapper/hisStore/FsMenuScrmMapper.xml
  62. 163 0
      fs-service/src/main/resources/mapper/hisStore/FsStoreOrderScrmMapper.xml
  63. 18 15
      fs-service/src/main/resources/mapper/hisStore/FsStoreProductScrmMapper.xml
  64. 196 0
      fs-service/src/main/resources/mapper/live/LiveOrderMapper.xml
  65. 9 0
      fs-service/src/main/resources/mapper/qw/QwExternalContactMapper.xml
  66. 16 0
      fs-user-app/src/main/java/com/fs/app/controller/live/LiveController.java
  67. 5 2
      fs-user-app/src/main/java/com/fs/app/controller/store/CompanyUserScrmController.java
  68. 1 2
      fs-user-app/src/main/java/com/fs/app/controller/store/IndexScrmController.java

+ 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);
+    }
 }

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

@@ -0,0 +1,512 @@
+package com.fs.hisStore.task;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONUtil;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.company.service.ICompanyService;
+import com.fs.company.vo.RedPacketMoneyVO;
+import com.fs.course.mapper.FsCourseRedPacketLogMapper;
+import com.fs.erp.domain.ErpDeliverys;
+import com.fs.erp.domain.ErpOrderQuery;
+import com.fs.erp.dto.ErpOrderQueryRequert;
+import com.fs.erp.dto.ErpOrderQueryResponse;
+import com.fs.erp.service.IErpOrderService;
+import com.fs.his.config.FsSysConfig;
+import com.fs.his.dto.ExpressInfoDTO;
+import com.fs.his.service.IFsExpressService;
+import com.fs.his.service.IFsUserService;
+import com.fs.his.utils.ConfigUtil;
+import com.fs.hisStore.domain.FsStoreProductAttrValueScrm;
+import com.fs.hisStore.dto.DateComparisonConfigDTO;
+import com.fs.hisStore.enums.ShipperCodeEnum;
+import com.fs.hisStore.mapper.FsStoreProductAttrValueScrmMapper;
+import com.fs.hisStore.param.FsStoreOrderAddTuiMoneyParam;
+import com.fs.hisStore.service.IFsStoreProductScrmService;
+import com.fs.live.domain.LiveAfterSales;
+import com.fs.live.domain.LiveOrder;
+import com.fs.live.domain.LiveOrderItem;
+import com.fs.live.domain.LiveOrderPayment;
+import com.fs.live.mapper.LiveOrderItemMapper;
+import com.fs.live.mapper.LiveOrderMapper;
+import com.fs.live.mapper.LiveOrderPaymentMapper;
+import com.fs.live.param.LiveAfterSalesAudit1Param;
+import com.fs.live.param.LiveAfterSalesParam;
+import com.fs.live.param.LiveAfterSalesProductParam;
+import com.fs.live.service.*;
+import com.fs.pay.pay.dto.OrderQueryDTO;
+import com.fs.pay.service.IPayService;
+import com.fs.store.config.StoreConfig;
+import com.fs.system.service.ISysConfigService;
+import com.fs.ybPay.domain.OrderResult;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+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;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+import static com.fs.hisStore.constants.StoreConstants.DELIVERY;
+
+/**
+ * 定时任务调度测试
+ *
+ * @author fs
+ */
+@Slf4j
+@Component("liveTask")
+public class LiveTask {
+    @Autowired
+    private RedisTemplate redisTemplate;
+    @Autowired
+    private RedisCache redisCache;
+    @Autowired
+    private ILiveOrderService liveOrderService;
+
+    @Autowired
+    private ILiveCouponService liveCouponService;
+
+    @Autowired
+    private ILiveCouponIssueService liveCouponIssueService;
+    @Autowired
+    private IFsStoreProductScrmService fsStoreProductScrmService;
+
+    @Autowired
+    private ILiveAfterSalesService liveAfterSalesService;
+
+    @Autowired
+    private ILiveOrderItemService liveOrderItemService;
+
+    @Autowired
+    private ILiveOrderPaymentService liveOrderPaymentService;
+
+    @Autowired
+    private IFsUserService userService;
+
+    @Autowired
+    private ICompanyService companyService;
+
+    @Autowired
+    @Qualifier("erpOrderServiceImpl")
+    private IErpOrderService gyOrderService;
+
+    @Autowired
+    @Qualifier("wdtErpOrderServiceImpl")
+    private IErpOrderService wdtOrderService;
+
+    @Autowired
+    @Qualifier("hzOMSErpOrderServiceImpl")
+    private IErpOrderService hzOMSOrderService;
+
+    @Autowired
+    @Qualifier("dfOrderServiceImpl")
+    private IErpOrderService dfOrderService;
+
+    @Autowired
+    @Qualifier("JSTErpOrderServiceImpl")
+    private IErpOrderService jSTOrderService;
+
+    @Autowired
+    @Qualifier("k9OrderScrmServiceImpl")
+    private IErpOrderService k9OrderService;
+
+    @Autowired
+    private ConfigUtil configUtil;
+
+    @Autowired
+    IErpOrderService erpOrderService;
+
+    @Autowired
+    private LiveOrderMapper liveOrderMapper;
+
+    @Autowired
+    private LiveOrderItemMapper liveOrderItemMapper;
+
+    @Autowired
+    private LiveOrderPaymentMapper liveOrderPaymentMapper;
+
+    @Autowired
+    private IPayService ybPayService;
+
+    @Autowired
+    private ISysConfigService configService;
+
+    @Autowired
+    private IFsExpressService expressService;
+
+    @Autowired
+    private FsCourseRedPacketLogMapper fsCourseRedPacketLogMapper;
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    public void PushErp() throws ParseException {
+        List<Long> ids = liveOrderMapper.selectOrderIdByNoErp();
+        for (Long id : ids) {
+            liveOrderService.createOmsOrder(id);
+        }
+    }
+
+    public void redPacketSubMoney() throws Exception {
+        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogByCompany();
+        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
+            companyService.subtractCompanyMoney(redPacketMoneyVO.getMoney(), redPacketMoneyVO.getCompanyId());
+        }
+    }
+
+    public void redPacketAddMoney() throws Exception {
+        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseAddRedPacketLogByCompany();
+        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
+            companyService.addRedPacketCompanyMoney(redPacketMoneyVO.getMoney(), redPacketMoneyVO.getCompanyId());
+        }
+    }
+
+
+    //定时任务刷新微信订单结算状态
+    public void refreshOrderSettlementStatus(){
+        liveOrderService.refreshOrderSettlementStatus();
+    }
+
+
+
+    //每5分钟执行一次
+    public void deliveryOp() {
+        List<LiveOrder> list = liveOrderService.selectUpdateExpress();
+        for (LiveOrder order : list) {
+            ErpOrderQueryRequert request = new ErpOrderQueryRequert();
+            request.setCode(order.getExtendOrderId());
+            IErpOrderService erpOrderService = getErpOrderService();
+            ErpOrderQueryResponse response = erpOrderService.getLiveOrder(request);
+            if (erpOrderService != dfOrderService) {
+                if (response.getOrders() != null && !response.getOrders().isEmpty()) {
+                    for (ErpOrderQuery orderQuery : response.getOrders()) {
+                        if (orderQuery.getDeliverys() != null && orderQuery.getDeliverys().size() > 0) {
+                            for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
+                                if (delivery.getDelivery() && StringUtils.isNotEmpty(delivery.getMail_no())) {
+                                    //更新商订单状态 删除REDIS
+                                    liveOrderService.deliveryOrder(order.getOrderCode(), delivery.getMail_no(), delivery.getExpress_code(), delivery.getExpress_name());
+                                    redisCache.deleteObject(DELIVERY + ":" + order.getExtendOrderId());
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void couponOp() {
+        // 直播优惠券过期处理,如果有对应方法则调用
+        // liveCouponService.updateFsCouponByExpire();
+    }
+
+    //退款自动处理 24小时未审核自动审核通过 每小时执行一次
+    public void refundOp() {
+        //获取所有退款申请
+        List<LiveAfterSales> list = liveAfterSalesService.selectLiveAfterSalesByDoAudit();
+        if (list != null) {
+            for (LiveAfterSales afterSales : list) {
+                //仅退款
+                if (afterSales.getRefundType().equals(0)) {
+                    LiveAfterSalesAudit1Param audit1Param = new LiveAfterSalesAudit1Param();
+                    audit1Param.setSalesId(afterSales.getId());
+                    audit1Param.setOperator("平台");
+                    liveAfterSalesService.audit1(audit1Param);
+                }
+            }
+        }
+    }
+
+    //每天执行一次
+    public void userMoneyOp() {
+        // 直播订单完成7天后给用户返现,如果有对应方法则调用
+        // List<LiveOrder> list = liveOrderService.selectLiveOrderListByFinish7Day();
+        // if (list != null) {
+        //     for (LiveOrder order : list) {
+        //         userService.addMoney(order);
+        //     }
+        // }
+    }
+
+    //每30秒执行一次
+    public void orderItemSyncOp() {
+//         同步订单项JSON,如果有对应方法则调用
+         List<LiveOrder> list = liveOrderService.selectLiveOrderItemJson();
+         for (LiveOrder storeOrder : list) {
+             LiveOrderItem parmOrderItem = new LiveOrderItem();
+             parmOrderItem.setOrderId(storeOrder.getOrderId());
+             List<LiveOrderItem> listOrderItem = liveOrderItemService.selectLiveOrderItemList(parmOrderItem);
+             if (listOrderItem.size() > 0) {
+                 String itemJson = JSONUtil.toJsonStr(listOrderItem);
+                 storeOrder.setItemJson(itemJson);
+                 liveOrderMapper.updateLiveOrderItemJson(storeOrder);
+             }
+         }
+    }
+
+    public void returnDeliveryId() {
+        IErpOrderService erpOrderService = getErpOrderService();
+        // 获取ERP订单号列表,如果有对应方法则调用
+        // List<String> list = liveOrderMapper.selectErpCode();
+        // for (String s : list) {
+        //     ErpOrderQueryRequert request = new ErpOrderQueryRequert();
+        //     request.setCode(s);
+        //     ErpOrderQueryResponse response = erpOrderService.getOrder(request);
+        //     if (response.getOrders() != null && response.getOrders().size() > 0) {
+        //         for (ErpOrderQuery orderQuery : response.getOrders()) {
+        //             if (orderQuery.getDeliverys() != null && orderQuery.getDeliverys().size() > 0) {
+        //                 for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
+        //                     if (delivery.getDelivery() && StringUtils.isNotEmpty(delivery.getMail_no())) {
+        //                         LiveOrder order = new LiveOrder();
+        //                         order.setExtendOrderId(s);
+        //                         order.setDeliverySn(delivery.getMail_no());
+        //                         order.setStatus(2);
+        //                         liveOrderMapper.updateDelivery(order);
+        //                     }
+        //                 }
+        //             }
+        //         }
+        //     }
+        // }
+    }
+
+    public void changeStatus() {
+//         获取需要更新物流状态的订单ID列表,如果有对应方法则调用
+//         List<Long> list = liveOrderMapper.selectOrderId();
+//         for (Long orderId : list) {
+//             LiveOrder order = liveOrderMapper.selectLiveOrderByOrderId(String.valueOf(orderId));
+//             String lastFourNumber = "";
+//             if (order.getDeliverySn() != null && order.getDeliverySn().equals(ShipperCodeEnum.SF.getValue())) {
+//                 lastFourNumber = order.getUserPhone();
+//                 if (lastFourNumber != null && lastFourNumber.length() == 11) {
+//                     lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
+//                 }
+//             }
+//             ExpressInfoDTO dto = expressService.getExpressInfo(order.getOrderCode(), order.getDeliverySn(), order.getDeliverySn(), lastFourNumber);
+//             LiveOrder map = new LiveOrder();
+//             map.setDeliveryStatus(Integer.parseInt(dto.getState()));
+//             map.setOrderId(orderId);
+//             map.setDeliveryType(dto.getStateEx());
+//             liveOrderMapper.updateLiveOrder(map);
+//         }
+    }
+
+    public void subCompanyMoney() {
+        // 获取需要扣减公司金额的支付ID列表,如果有对应方法则调用
+        // List<Long> list = liveOrderPaymentMapper.selectPaymentIds();
+        // for (Long paymentId : list) {
+        //     LiveOrderPayment payment = liveOrderPaymentService.selectLiveOrderPaymentByPaymentId(paymentId);
+        //     if (payment.getCompanyId() != null && payment.getCompanyId() > 0) {
+        //         companyService.subCompanyPaymentMoney(payment);
+        //     }
+        // }
+    }
+
+    public void updateOrderItem() throws ParseException {
+        List<Long> ids = liveOrderService.selectOrderIdByNoErp();
+        for (Long id : ids) {
+            liveOrderService.createOmsOrder(id);
+        }
+    }
+
+    //每天执行一次
+    public void syncExpress() {
+        List<Long> ids = liveOrderService.selectSyncExpressIds();
+        for (Long id : ids) {
+            liveOrderService.syncExpress(id);
+        }
+    }
+
+    public void returnPayStatus() {
+        // 获取需要查询支付状态的支付ID列表,如果有对应方法则调用
+        // List<String> ids = liveOrderPaymentMapper.selectPayStatusIds();
+        // for (String id : ids) {
+        //     OrderQueryDTO o = new OrderQueryDTO();
+        //     o.setUpOrderId(id);
+        //     OrderResult orderResult = ybPayService.getOrder(o);
+        //     if ("0".equals(orderResult.getState())) {
+        //         String[] order = orderResult.getLowOrderId().split("-");
+        //         if (orderResult.getStatus().equals("100")) {
+        //             switch (order[0]) {
+        //                 case "live":
+        //                     liveOrderService.payConfirm(1, null, order[1], o.getUpOrderId(), orderResult.getBankTrxId(), orderResult.getBankOrderId());
+        //                 case "live_remain":
+        //                     liveOrderService.payConfirm(1, null, order[1], o.getUpOrderId(), orderResult.getBankTrxId(), orderResult.getBankOrderId());
+        //                 case "payment":
+        //                     liveOrderPaymentService.payConfirm(order[1], o.getUpOrderId(), orderResult.getBankTrxId(), orderResult.getBankOrderId());
+        //             }
+        //         }
+        //     }
+        // }
+    }
+
+    public void AddTuiMoney() {
+        // 获取需要添加推荐金额的订单ID列表,如果有对应方法则调用
+        // List<Long> ids = liveOrderMapper.selectAddTuiMoney();
+        // for (Long id : ids) {
+        //     FsStoreOrderAddTuiMoneyParam param = new FsStoreOrderAddTuiMoneyParam();
+        //     param.setOrderId(id);
+        //     liveOrderService.addTuiMoney(param);
+        // }
+    }
+
+    public void selectPayMoneyLessOne() {
+        // 获取支付金额小于1的订单列表,如果有对应方法则调用
+        // List<LiveOrder> list = liveOrderMapper.selectPayMoneyLessOne();
+        // for (LiveOrder order : list) {
+        //     LiveAfterSalesParam param = new LiveAfterSalesParam();
+        //     param.setOrderCode(order.getOrderCode());
+        //     param.setServiceType(0);
+        //     param.setRefundAmount(order.getPayMoney());
+        //     param.setReasons("超时未处理,自动申请退款");
+        //     List<LiveAfterSalesProductParam> productParams = new ArrayList<>();
+        //     List<LiveOrderItem> items = liveOrderItemMapper.selectLiveOrderItemByOrderId(order.getOrderId());
+        //     for (LiveOrderItem item : items) {
+        //         LiveAfterSalesProductParam param1 = new LiveAfterSalesProductParam();
+        //         param1.setProductId(item.getProductId());
+        //         param1.setNum(item.getNum());
+        //         productParams.add(param1);
+        //     }
+        //     param.setProductList(productParams);
+        //     liveAfterSalesService.applyForAfterSales(order.getUserId(), param);
+        // }
+    }
+
+    public void deleteCustomer() {
+        // 删除客户逻辑
+    }
+
+    private IErpOrderService getErpOrderService() {
+        //判断是否开启erp
+        IErpOrderService erpOrderService = null;
+        FsSysConfig erpConfig = configUtil.getSysConfig();
+        Integer erpOpen = erpConfig.getErpOpen();
+        if (erpOpen != null && erpOpen == 1) {
+            //判断erp类型
+            Integer erpType = erpConfig.getErpType();
+            if (erpType != null) {
+                if (erpType == 1) {
+                    //管易
+                    erpOrderService = gyOrderService;
+                } else if (erpType == 2) {
+                    //旺店通
+                    erpOrderService = wdtOrderService;
+                } else if (erpType == 3) {
+                    //代服
+                    erpOrderService = hzOMSOrderService;
+                } else if (erpType == 4) {
+                    //瀚智
+                    erpOrderService = dfOrderService;
+                } else if (erpType == 5) {
+                    erpOrderService = jSTOrderService;
+                } else if (erpType == 6) {
+                    erpOrderService = k9OrderService;
+                }
+            }
+        }
+        return erpOrderService;
+    }
+
+    /**
+     * 提醒证件到期任务
+     */
+    public void remindCertValidation() {
+        log.info("提醒店铺证件到期任务执行... 当前时间: {}", LocalTime.now());
+
+        // 从配置表获取需要比较的表和字段
+        List<DateComparisonConfigDTO> tablesToCheck = jdbcTemplate.query(
+                "SELECT table_name, date_column,in_advance,user_column,phone_column,remind_words,platform,cert_type" +
+                        " FROM date_comparison_config", (rs, rowNum) -> {
+                    return DateComparisonConfigDTO.builder()
+                            .tableName(rs.getString("table_name"))//表名
+                            .certType(rs.getString("cert_type"))//证件类型
+                            .dateColumn(rs.getString("date_column"))//日期字段
+                            .userColumn(rs.getString("user_column"))//用户字段
+                            .remindWords(rs.getString("remindWords"))//提醒内容
+                            .phoneColumn(rs.getString("phone_column"))//提醒手机
+                            .inAdvance(rs.getInt("inAdvance"))//提前天数
+                            .platform(rs.getString("platform")).build();//平台
+                });
+
+        tablesToCheck.forEach(dto -> {
+            //获取证件失效日期字段小于当前时间加提前天数的用户和电话号码
+            String sql = String.format("SELECT %s , %s " +
+                            "FROM %s " +
+                            "WHERE %s >= DATE_SUB(CURDATE(), INTERVAL %d DAY)",
+                    dto.getUserColumn(),
+                    dto.getPhoneColumn(),
+                    dto.getTableName(),
+                    dto.getDateColumn(),
+                    dto.getInAdvance()
+            );
+            List<Map<String, Object>> users = jdbcTemplate.queryForList(sql);
+            users.forEach(user -> {
+                String userName = (String) user.get(dto.getUserColumn());
+                String phone = (String) user.get(dto.getPhoneColumn());
+                String remindWords = String.format("【%s平台提示】尊敬的%s用户,店铺%s证件即将到期,请及时处理!",
+                        dto.getPlatform(),
+                        userName,
+                        dto.getCertType());
+                // 使用phone发送remindWords短信
+                // TODO 发送通知
+            });
+        });
+    }
+
+    /**
+     * 禁用店铺
+     */
+    public void disable() {
+        log.info("禁用店铺任务执行... 当前时间: {}", LocalTime.now());
+        // 从配置表获取需要禁用的表和字段
+        List<DateComparisonConfigDTO> toDisable = jdbcTemplate.query(
+                "SELECT table_name, date_column,invalid_expression,status_column" +
+                        " FROM date_comparison_config " +
+                        " WHERE is_do_invalid = '1'", (rs, rowNum) -> DateComparisonConfigDTO.builder()
+                        .tableName(rs.getString("table_name"))//表名
+                        .dateColumn(rs.getString("date_column"))//日期字段
+                        .invalidExpression(rs.getString("invalid_expression"))//失效表达式
+                        .statusColumn(rs.getString("status_column"))//状态字段
+                        .build());
+
+        toDisable.forEach(dto -> {
+            //更新证件失效日期字段小于当前时间的数据
+            String sql = String.format("UPDATE %s " +
+                            "SET %s = %s " +
+                            "WHERE %s < CURDATE()",
+                    dto.getTableName(),
+                    dto.getStatusColumn(),
+                    dto.getInvalidExpression(),
+                    dto.getDateColumn());
+            jdbcTemplate.update(sql);
+        });
+    }
+
+    public void getOrderDeliveryStatus() {
+        IErpOrderService erpOrderService = getErpOrderService();
+        List<LiveOrder> orders = null;
+        if (erpOrderService != null && erpOrderService == dfOrderService) {
+            // 获取已发货订单列表,如果有对应方法则调用
+             orders = liveOrderMapper.selectShippedOrder();
+             if (orders != null && !orders.isEmpty()) {
+                 List<CompletableFuture<Void>> futures = new ArrayList<>();
+                 for (LiveOrder order : orders) {
+                     CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
+                         erpOrderService.getOrderLiveDeliveryStatus(order);
+                     });
+                     futures.add(future);
+                 }
+                 CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
+             }
+        }
+    }
+}

+ 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");

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

@@ -7,14 +7,16 @@ 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;
-import com.fs.task.LiveTask;
 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;
 
@@ -29,8 +31,7 @@ import java.util.Map;
 public class LiveController extends BaseController {
     @Autowired
     private ILiveService liveService;
-    @Autowired
-    private LiveTask liveTask;
+
 
     /**
      * 查询直播列表

+ 12 - 0
fs-admin/src/main/java/com/fs/live/controller/LiveDataController.java

@@ -5,6 +5,7 @@ import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.utils.SecurityUtils;
 import com.fs.live.domain.LiveData;
+import com.fs.live.param.LiveDataParam;
 import com.fs.live.service.ILiveDataService;
 import com.fs.live.vo.LiveUserFirstVo;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -41,6 +42,17 @@ public class LiveDataController extends BaseController {
         return getDataTable(list);
     }
 
+    /**
+     * 查询新直播数据列表
+     */
+    @PreAuthorize("@ss.hasPermi('liveData:liveData:list')")
+    @PostMapping("/listLiveData")
+    public R listLiveData(@RequestBody LiveDataParam param, HttpServletRequest request)
+    {
+        startPage();
+        return liveDataService.listLiveData(param);
+    }
+
     /**
      * 查询直播数据列表
      * */

+ 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;
+    }
 }

+ 6 - 9
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.*;
@@ -43,7 +46,6 @@ import com.fs.live.vo.*;
 import com.fs.store.domain.FsStoreDelivers;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.mapper.SysConfigMapper;
-import com.fs.task.LiveTask;
 import io.swagger.annotations.ApiOperation;
 import org.apache.http.util.Asserts;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -53,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;
@@ -93,8 +96,7 @@ public class LiveOrderController extends BaseController
 //    private FsWarehousesMapper fsWarehousesMapper;
     @Autowired
     IErpOrderService erpOrderService;
-    @Autowired
-    private LiveTask liveTask;
+
 
 
     @Autowired
@@ -253,12 +255,7 @@ public class LiveOrderController extends BaseController
         return getDataTable(list);
     }
 
-    @GetMapping("/test")
-    public R test()
-    {
-        liveTask.updateExpress();
-        return R.ok();
-    }
+
     @PreAuthorize("@ss.hasPermi('live:liveOrder:refundOrderMoney')")
     @Log(title = "退款", businessType = BusinessType.UPDATE)
 //    @PreAuthorize("@ss.hasPermi('live:liveOrder:refundOrderMoney')")

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

@@ -1,183 +0,0 @@
-package com.fs.task;
-
-
-import com.fs.erp.domain.ErpDeliverys;
-import com.fs.erp.domain.ErpOrderQuery;
-import com.fs.erp.dto.ErpOrderQueryRequert;
-import com.fs.erp.dto.ErpOrderQueryResponse;
-import com.fs.erp.service.FsJstAftersalePushService;
-import com.fs.erp.service.IErpOrderService;
-import com.fs.his.service.IFsExpressService;
-import com.fs.live.domain.LiveAfterSales;
-import com.fs.live.domain.LiveOrder;
-import com.fs.live.param.LiveAfterSalesAudit1Param;
-import com.fs.live.service.ILiveAfterSalesService;
-import com.fs.live.service.ILiveOrderLogsService;
-import com.fs.live.service.ILiveOrderService;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang.ObjectUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import java.text.ParseException;
-import java.util.List;
-
-/**
- * 定时任务调度
- * @author fs
- */
-@Component("liveTask")
-public class LiveTask {
-    Logger logger = LoggerFactory.getLogger(LiveTask.class);
-
-
-    @Autowired
-    private ILiveOrderService liveOrderService;
-
-    @Autowired
-    private ILiveAfterSalesService afterSalesService;
-
-
-    @Autowired
-    private IErpOrderService erpOrderService;
-
-
-    @Autowired
-    private IFsExpressService expressService;
-
-
-    @Autowired
-    private ILiveOrderLogsService orderLogsService;
-
-
-//    @Autowired
-//    private FsWarehousesMapper fsWarehousesMapper;
-
-    @Autowired
-    public FsJstAftersalePushService fsJstAftersalePushService;
-
-    /**
-     * 超时订单自动取消
-     */
-    public void orderCancel(){
-        liveOrderService.orderCancel();
-    }
-
-
-    /**
-     * 发货任务
-     */
-    public void deliveryOp() {
-//        List<LiveOrder> list = liveOrderService.selectDeliverPenddingData();
-//
-//        for (LiveOrder order : list) {
-//            String orderCode = order.getOrderCode();
-//            ErpOrderQueryRequert request = new ErpOrderQueryRequert();
-//            request.setCode(order.getExtendOrderId());
-//
-//            try {
-//                // 根据仓库code找erp
-//                if (com.fs.common.utils.StringUtils.isNotBlank(order.getStoreHouseCode())) {
-//                    String erp = fsWarehousesMapper.selectErpByCode(order.getStoreHouseCode());
-//                    ErpContextHolder.setErpType(erp);
-//                }
-//                ErpOrderQueryResponse response = erpOrderService.getOrderLive(request);
-//                if (CollectionUtils.isNotEmpty(response.getOrders())) {
-//                    for (ErpOrderQuery orderQuery : response.getOrders()) {
-//                        if (CollectionUtils.isNotEmpty(orderQuery.getDeliverys())) {
-//                            // 部分发货或者全部发货
-//                            if (ObjectUtils.equals(orderQuery.getDelivery_state(), 1) || ObjectUtils.equals(orderQuery.getDelivery_state(), 2)) {
-//
-//                                orderLogsService.create(order.getOrderId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
-//                                        OrderLogEnum.DELIVERY_GOODS.getDesc());
-//
-//                                for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
-//
-//                                    FsExpress express = expressService.selectFsExpressByOmsCode(delivery.getExpress_code());
-//                                    if (express == null) {
-//                                        logger.warn("当前express_code: {} 不存在!", delivery.getExpress_code());
-//                                        continue;
-//                                    }
-//
-//                                    if (delivery.getDelivery()) {
-//                                        liveOrderService.deliveryOrder(orderCode, delivery.getMail_no(),
-//                                                delivery.getExpress_code(), delivery.getExpress_name());
-//                                    }
-//                                }
-//
-//                                logger.info("订单 {} 发货信息同步成功", order.getOrderCode());
-//                            }
-//                        }
-//                    }
-//                }
-//            } catch (Exception e) {
-//                logger.error(String.format("[发货任务]调用erp查询接口失败!原因: %s", e));
-//            }
-//
-//        }
-    }
-
-
-        /**
-         * 退款自动处理 24小时未审核自动审核通过 每小时执行一次
-         */
-    public void refundOp() {
-        //获取所有退款申请
-        List<LiveAfterSales> list = afterSalesService.selectLiveAfterSalesByDoAudit();
-        if (list != null) {
-            for (LiveAfterSales afterSales : list) {
-                //仅退款
-//                if (afterSales.getServiceType().equals(0)) {
-                LiveAfterSalesAudit1Param audit1Param = new LiveAfterSalesAudit1Param();
-                audit1Param.setSalesId(afterSales.getId());
-                audit1Param.setOperator("平台");
-                afterSalesService.audit1(audit1Param);
-//                }
-            }
-        }
-    }
-
-    /**
-     * 批量推管易
-     * @throws ParseException 解析异常
-     */
-    public void updateOrderItem() throws ParseException {
-        List<Long> ids = liveOrderService.selectOrderIdByNoErp();
-        for (Long id : ids) {
-            try{
-                liveOrderService.createOmsOrder(id);
-            }catch (Exception e){
-                logger.error("推送管易失败 {}",id,e);
-            }
-        }
-    }
-
-
-    /**
-     * 同步物流状态
-     */
-    public void syncExpress() {
-        List<Long> ids = liveOrderService.selectSyncExpressIds();
-        for (Long id : ids) {
-            liveOrderService.syncExpress(id);
-        }
-    }
-
-    /**
-     * 更新发货状态
-     */
-    public void updateExpress() {
-        List<LiveOrder> list = liveOrderService.selectUpdateExpress();
-
-        for (LiveOrder order : list) {
-            try{
-                liveOrderService.syncDeliveryOrder(order);
-            }catch (Exception e) {
-                logger.error("获取订单是否发货失败!原因: ",e);
-            }
-        }
-
-    }
-}

+ 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

+ 30 - 0
fs-company/src/main/java/com/fs/company/controller/course/FsUserCoursePeriodController.java

@@ -5,6 +5,7 @@ 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.domain.entity.SysDictData;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.exception.CustomException;
@@ -72,6 +73,25 @@ public class FsUserCoursePeriodController extends BaseController {
         return getDataTable(list);
     }
 
+
+    /**
+     * @Description: 营期key value 值
+     * @Param:
+     * @Return:
+     * @Author xgb
+     * @Date 2025/11/18 14:59
+     */
+    @GetMapping("/listLabel")
+    public TableDataInfo listLabel(FsUserCoursePeriod fsUserCoursePeriod)
+    {
+        startPage();
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        fsUserCoursePeriod.setCompanyId(loginUser.getCompany().getCompanyId().toString());
+        List<SysDictData> list = fsUserCoursePeriodService.selectFsUserCoursePeriodListLabel(fsUserCoursePeriod);
+        return getDataTable(list);
+    }
+
+
     @PostMapping("/page")
     @ApiOperation("自定义查询主列表分页")
     public R pageList(@RequestBody FsUserCoursePeriod fsUserCoursePeriod)
@@ -145,6 +165,16 @@ public class FsUserCoursePeriodController extends BaseController {
         fsUserCoursePeriod.setCompanyId(loginUser.getCompany().getCompanyId().toString());
         return toAjax(fsUserCoursePeriodService.updateFsUserCoursePeriod(fsUserCoursePeriod));
     }
+    /**
+     * 修改会员营期单独注册状态
+     */
+    @PreAuthorize("@ss.hasPermi('course:period:edit')")
+    @Log(title = "会员营期", businessType = BusinessType.UPDATE)
+    @PutMapping("/editIsNeedRegisterMember")
+    public AjaxResult editIsNeedRegisterMember(@RequestBody FsUserCoursePeriod fsUserCoursePeriod)
+    {
+        return toAjax(fsUserCoursePeriodService.editIsNeedRegisterMember(fsUserCoursePeriod));
+    }
 
     /**
      * 删除会员营期

+ 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, "订单数据");
     }
 

+ 2 - 1
fs-service/src/main/java/com/fs/course/dto/FsCourseQuestionBankImportDTO.java

@@ -30,7 +30,8 @@ public class FsCourseQuestionBankImportDTO {
     @Excel(name = "选项B(必填)")
     private String questionB;
 
-    @Excel(name = "选项C(必填)")
+    // 鹤颜堂项目有两个答案的
+    @Excel(name = "选项C(非必填)")
     private String questionC;
 
     @Excel(name = "选项D(非必填)")

+ 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;
+}

+ 9 - 0
fs-service/src/main/java/com/fs/course/mapper/FsUserCoursePeriodDaysMapper.java

@@ -122,4 +122,13 @@ public interface FsUserCoursePeriodDaysMapper extends BaseMapper<FsUserCoursePer
 
     @Select("SELECT distinct period_id from fs_user_course_period_days  where day_date >=#{periodSTime} and day_date <=#{periodETime} ")
     List<Long> selectFsUserCoursePeriodDaysByTime(@Param("periodSTime") String periodSTime,@Param("periodETime") String periodETime);
+
+    /**
+     * @Description: 根据id获取当前营期的所有的大于该id数据lesson的id
+     * @Param:
+     * @Return:
+     * @Author xgb
+     * @Date 2025/11/18 11:04
+     */
+    List<Long> selectFsUserCoursePeriodDaysForLastById(FsUserCoursePeriodDays param);
 }

+ 3 - 0
fs-service/src/main/java/com/fs/course/mapper/FsUserCoursePeriodMapper.java

@@ -1,5 +1,6 @@
 package com.fs.course.mapper;
 
+import com.fs.common.core.domain.entity.SysDictData;
 import com.fs.course.domain.FsUserCoursePeriod;
 import com.fs.course.param.CompanyRedPacketParam;
 import com.fs.course.param.PeriodStatisticCountParam;
@@ -170,4 +171,6 @@ public interface FsUserCoursePeriodMapper
             "</foreach> " +
             "</script> ")
     List<Long> selectFsUserCoursePeriodListByPeriodId(@Param("periodIds") List<Long> qwUserIds,@Param("companyId") Long companyId);
+
+    List<SysDictData> selectFsUserCoursePeriodListLabel(FsUserCoursePeriod fsUserCoursePeriod);
 }

+ 2 - 0
fs-service/src/main/java/com/fs/course/param/FsCourseWatchLogListParam.java

@@ -69,6 +69,8 @@ public class FsCourseWatchLogListParam implements Serializable {
 
     private List<Long> periodIds;//训练营期ID
 
+    private Long periodId;//训练营期ID
+
     private String customPageStr;
 
     private Long lastId;

+ 4 - 0
fs-service/src/main/java/com/fs/course/service/IFsUserCoursePeriodService.java

@@ -1,5 +1,6 @@
 package com.fs.course.service;
 
+import com.fs.common.core.domain.entity.SysDictData;
 import com.fs.course.domain.FsUserCoursePeriod;
 import com.fs.course.param.PeriodStatisticCountParam;
 import com.fs.course.vo.FsCourseStaticsCountVO;
@@ -101,4 +102,7 @@ public interface IFsUserCoursePeriodService
 
     List<Long> selectFsUserCoursePeriodListByPeriodId(List<Long> periodIds,Long companyId);
 
+    int editIsNeedRegisterMember(FsUserCoursePeriod fsUserCoursePeriod);
+
+    List<SysDictData> selectFsUserCoursePeriodListLabel(FsUserCoursePeriod fsUserCoursePeriod);
 }

+ 13 - 7
fs-service/src/main/java/com/fs/course/service/impl/FsCourseQuestionBankServiceImpl.java

@@ -539,13 +539,13 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
     }
 
     /**
-     * 验证选项
+     * 验证选项 鹤颜堂项目允许两个答案
      */
     private ValidationResult validateOptions(FsCourseQuestionBankImportDTO importDTO) {
         if (StringUtils.isBlank(importDTO.getQuestionA()) ||
-                StringUtils.isBlank(importDTO.getQuestionB()) ||
-                StringUtils.isBlank(importDTO.getQuestionC())) {
-            return ValidationResult.fail("选项A、B、C不能为空");
+                StringUtils.isBlank(importDTO.getQuestionB())
+                ) {
+            return ValidationResult.fail("选项A、B不能为空");
         }
         return ValidationResult.success();
     }
@@ -672,7 +672,9 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
         // 构建选项
         addOption(questionArray, importDTO.getQuestionA(), answerList.contains("A"), 0);
         addOption(questionArray, importDTO.getQuestionB(), answerList.contains("B"), 1);
-        addOption(questionArray, importDTO.getQuestionC(), answerList.contains("C"), 2);
+        if (StringUtils.isNotBlank(importDTO.getQuestionC())) {
+            addOption(questionArray, importDTO.getQuestionC(), answerList.contains("C"), 2);
+        }
 
         if (StringUtils.isNotBlank(importDTO.getQuestionD())) {
             addOption(questionArray, importDTO.getQuestionD(), answerList.contains("D"), 3);
@@ -703,8 +705,12 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
         Map<String, String> questionMap = new HashMap<>();
         questionMap.put("A", importDTO.getQuestionA().trim());
         questionMap.put("B", importDTO.getQuestionB().trim());
-        questionMap.put("C", importDTO.getQuestionC().trim());
-        questionMap.put("D", importDTO.getQuestionD().trim());
+        if(StringUtils.isNotBlank(importDTO.getQuestionC())){
+            questionMap.put("C", importDTO.getQuestionC().trim());
+        }
+        if(StringUtils.isNotBlank(importDTO.getQuestionD())){
+            questionMap.put("D", importDTO.getQuestionD().trim());
+        }
 
         List<String> selectedAnswers = answerList.stream()
                 .map(questionMap::get)

+ 78 - 24
fs-service/src/main/java/com/fs/course/service/impl/FsUserCoursePeriodDaysServiceImpl.java

@@ -344,35 +344,89 @@ public class FsUserCoursePeriodDaysServiceImpl extends ServiceImpl<FsUserCourseP
 
     @Override
     public R updateCourseTime(UpdateCourseTimeVo vo) {
-        List<FsUserCoursePeriodDays> list = fsUserCoursePeriodDaysMapper.selectBatchIds(vo.getIds());
-        list.forEach(day -> {
+        // 批量更新
+        if(vo.getBatchUpdateSwitch()!=null && vo.getBatchUpdateSwitch()==1
+                && vo.getIds()!=null && vo.getIds().size()==1){
+            Long id=vo.getIds().get(0);
+
+            FsUserCoursePeriodDays info= fsUserCoursePeriodDaysMapper.selectFsUserCoursePeriodDaysById(id);
+
+            if(info==null || info.getPeriodId()==null || info.getLesson()==null){
+                return R.error(400, "该课程参数异常,请联系管理员");
+            }
+            // 根据id获取当前营期的所有的大于该id数据lesson的id
+            FsUserCoursePeriodDays param = new FsUserCoursePeriodDays();
+            param.setPeriodId(info.getPeriodId());
+            param.setLesson(info.getLesson());
+            List<Long> ids = fsUserCoursePeriodDaysMapper.selectFsUserCoursePeriodDaysForLastById(param);
+            List<FsUserCoursePeriodDays> list = fsUserCoursePeriodDaysMapper.selectBatchIds(ids);
+            list.forEach(day -> {
+
+                // 调整时间为直接接收前端传入的年月日,不使用营期的日期(2025年6月11日 10点41分)
+                day.setStartDateTime(vo.getStartTime());
+                day.setEndDateTime(vo.getEndTime1());
+
+
+                SysConfig config = sysConfigMapper.selectConfigByConfigKey("joinTime.switch.config");
+                if (ObjectUtils.isNotEmpty(config)&&config.getConfigValue().equals("1")){
+                    day.setLastJoinTime(vo.getEndTime1());
+                }else {
+                    day.setLastJoinTime(vo.getJoinTime());
+                }
+
+                // 把营期时间改成开始时间
+                day.setDayDate(vo.getStartTime().toLocalDate());
+                // 设置状态
+                LocalDateTime compareDayTime = LocalDateTime.now();
+                if(compareDayTime.isAfter(day.getStartDateTime()) && compareDayTime.isBefore(day.getEndDateTime())){
+                    day.setStatus(1);
+                } else if(compareDayTime.isBefore(day.getStartDateTime())){
+                    day.setStatus(0);
+                } else {
+                    day.setStatus(2);
+                }
+                fsUserCoursePeriodDaysMapper.updateById(day);
+
+                // 时间加一天
+                vo.setStartTime(vo.getStartTime().plusDays(1));
+                vo.setEndTime1(vo.getEndTime1().plusDays(1));
+                vo.setJoinTime(vo.getJoinTime().plusDays(1));
+            });
+
+        }else {
+            List<FsUserCoursePeriodDays> list = fsUserCoursePeriodDaysMapper.selectBatchIds(vo.getIds());
+            list.forEach(day -> {
 //            day.setStartDateTime(LocalDateTime.of(day.getDayDate(), vo.getStartTime()));
 //            day.setEndDateTime(LocalDateTime.of(day.getDayDate(), vo.getEndTime1()));
 //            day.setLastJoinTime(LocalDateTime.of(day.getDayDate(), vo.getJoinTime()));
-            // 调整时间为直接接收前端传入的年月日,不使用营期的日期(2025年6月11日 10点41分)
-            day.setStartDateTime(vo.getStartTime());
-            day.setEndDateTime(vo.getEndTime1());
+                // 调整时间为直接接收前端传入的年月日,不使用营期的日期(2025年6月11日 10点41分)
+                day.setStartDateTime(vo.getStartTime());
+                day.setEndDateTime(vo.getEndTime1());
+
+                SysConfig config = sysConfigMapper.selectConfigByConfigKey("joinTime.switch.config");
+                if (ObjectUtils.isNotEmpty(config)&&config.getConfigValue().equals("1")){
+                    day.setLastJoinTime(vo.getEndTime1());
+                }else {
+                    day.setLastJoinTime(vo.getJoinTime());
+                }
+
+                // 把营期时间改成开始时间
+                day.setDayDate(vo.getStartTime().toLocalDate());
+                // 设置状态
+                LocalDateTime compareDayTime = LocalDateTime.now();
+                if(compareDayTime.isAfter(day.getStartDateTime()) && compareDayTime.isBefore(day.getEndDateTime())){
+                    day.setStatus(1);
+                } else if(compareDayTime.isBefore(day.getStartDateTime())){
+                    day.setStatus(0);
+                } else {
+                    day.setStatus(2);
+                }
+                fsUserCoursePeriodDaysMapper.updateById(day);
+            });
+        }
+
 
-            SysConfig config = sysConfigMapper.selectConfigByConfigKey("joinTime.switch.config");
-            if (ObjectUtils.isNotEmpty(config)&&config.getConfigValue().equals("1")){
-                day.setLastJoinTime(vo.getEndTime1());
-            }else {
-                day.setLastJoinTime(vo.getJoinTime());
-            }
 
-            // 把营期时间改成开始时间
-            day.setDayDate(vo.getStartTime().toLocalDate());
-            // 设置状态
-            LocalDateTime compareDayTime = LocalDateTime.now();
-            if(compareDayTime.isAfter(day.getStartDateTime()) && compareDayTime.isBefore(day.getEndDateTime())){
-                day.setStatus(1);
-            } else if(compareDayTime.isBefore(day.getStartDateTime())){
-                day.setStatus(0);
-            } else {
-                day.setStatus(2);
-            }
-            fsUserCoursePeriodDaysMapper.updateById(day);
-        });
         return R.ok();
     }
 

+ 11 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsUserCoursePeriodServiceImpl.java

@@ -3,6 +3,7 @@ package com.fs.course.service.impl;
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.fs.common.core.domain.entity.SysDictData;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.exception.CustomException;
 import com.fs.common.exception.ServiceException;
@@ -310,4 +311,14 @@ public class FsUserCoursePeriodServiceImpl implements IFsUserCoursePeriodService
     public List<Long> selectFsUserCoursePeriodListByPeriodId(List<Long> periodIds, Long companyId) {
         return fsUserCoursePeriodMapper.selectFsUserCoursePeriodListByPeriodId(periodIds,companyId);
     }
+
+    @Override
+    public int editIsNeedRegisterMember(FsUserCoursePeriod fsUserCoursePeriod) {
+        return fsUserCoursePeriodMapper.updateFsUserCoursePeriod(fsUserCoursePeriod);
+    }
+
+    @Override
+    public List<SysDictData> selectFsUserCoursePeriodListLabel(FsUserCoursePeriod fsUserCoursePeriod) {
+        return fsUserCoursePeriodMapper.selectFsUserCoursePeriodListLabel(fsUserCoursePeriod);
+    }
 }

+ 38 - 15
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -604,26 +604,49 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         if(qwGroupChatUsers == null || qwGroupChatUsers.isEmpty()){
             return R.error("群参数异常");
         }
-        QwExternalContact qwExternalContact =
-                qwExternalContactMapper.selectOne(new QueryWrapper<QwExternalContact>()
+        //群聊寻找用户新逻辑
+        QwExternalContact qwExternalContact = null;
+        if( null != param.getUserId() && null == qwExternalContact){
+            try {
+                qwExternalContact =  qwExternalContactMapper.selectOne(new QueryWrapper<QwExternalContact>()
                         .eq("user_id", qwGroupChat.getOwner())
                         .eq("fs_user_id", param.getUserId())
                         .eq("corp_id", param.getCorpId())
                         .eq("status",0));
-        if(null == qwExternalContact){
-            try{
-                //修改成通过昵称匹配
-                qwExternalContact =
-                        qwExternalContactMapper.selectOne(new QueryWrapper<QwExternalContact>()
-                                .eq("user_id", qwGroupChat.getOwner())
-                                .eq("name", user.getNickName())
-                                .eq("corp_id", param.getCorpId())
-                                .eq("status",0));
-            } catch(Exception e){
-                log.error("群聊用户昵称匹配异常,参数user_id:{},name:{},corp_id:{}",qwGroupChat.getOwner(),user.getNickName(),param.getCorpId(),e);
+            } catch (Exception e){
+                log.error("群聊用户id匹配异常,参数user_id:{},fs_user_id:{},corp_id:{}",qwGroupChat.getOwner(),param.getUserId(),param.getCorpId(),e);
+            }
+        }
+        //找当前群中的用户匹配
+        if(StringUtils.isNotBlank(param.getChatId()) && null == qwExternalContact){
+            List<QwExternalContact> groupChatUserByChatIdAndUserName = qwExternalContactMapper.getGroupChatUserByChatIdAndUserName(qwGroupChat.getOwner(), user.getNickName(), param.getCorpId(), param.getChatId());
+            //没找到用户 || 找到的用户数量大于1 使用userid查询匹配
+            if(null == groupChatUserByChatIdAndUserName || groupChatUserByChatIdAndUserName.isEmpty() || groupChatUserByChatIdAndUserName.size() > 1){
+                log.error("群聊用户昵称匹配异常,参数user_id:{},name:{},corp_id:{},chatId:{}",qwGroupChat.getOwner(),user.getNickName(),param.getCorpId(),param.getChatId());
+            } else {
+                qwExternalContact =  groupChatUserByChatIdAndUserName.get(0);
             }
-
         }
+//        QwExternalContact qwExternalContact =  qwExternalContactMapper.selectOne(new QueryWrapper<QwExternalContact>()
+//                            .eq("user_id", qwGroupChat.getOwner())
+//                            .eq("fs_user_id", param.getUserId())
+//                            .eq("corp_id", param.getCorpId())
+//                            .eq("status",0));
+//
+//        if(null == qwExternalContact){
+//            try{
+//                //修改成通过昵称匹配
+//                qwExternalContact =
+//                        qwExternalContactMapper.selectOne(new QueryWrapper<QwExternalContact>()
+//                                .eq("user_id", qwGroupChat.getOwner())
+//                                .eq("name", user.getNickName())
+//                                .eq("corp_id", param.getCorpId())
+//                                .eq("status",0));
+//            } catch(Exception e){
+//                log.error("群聊用户昵称匹配异常,参数user_id:{},name:{},corp_id:{}",qwGroupChat.getOwner(),user.getNickName(),param.getCorpId(),e);
+//            }
+//
+//        }
         if(qwExternalContact==null){
             return addCustomerService(param.getQwUserId(),msg);
         }
@@ -1444,7 +1467,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             //查询是否绑定小程序
             FsUserWx fsUserWx = fsUserWxService.selectByAppIdAndUserId(param.getAppId(),user.getUserId(),1);
             if (fsUserWx ==null){
-                return R.error("openId参数错误,请清理缓存重新授权");
+                return R.error(401,"openId参数错误,请清理缓存重新授权");
             }else {
                 packetParam.setOpenId(fsUserWx.getOpenId());
             }

+ 3 - 0
fs-service/src/main/java/com/fs/course/vo/UpdateCourseTimeVo.java

@@ -21,4 +21,7 @@ public class UpdateCourseTimeVo {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime joinTime;
     private LocalDate dayDate;
+
+    // 批量修改开关 0 关闭 1 开启 默认关闭 打开的话修改时间,后续的时间会一起改变
+    private Integer batchUpdateSwitch;
 }

+ 435 - 5
fs-service/src/main/java/com/fs/erp/service/impl/DfOrderServiceImpl.java

@@ -52,6 +52,9 @@ import com.fs.hisStore.service.IFsExpressScrmService;
 import com.fs.hisStore.service.IFsStoreOrderScrmService;
 import com.fs.hisStore.vo.FsStoreOrderItemVO;
 import com.fs.live.domain.LiveOrder;
+import com.fs.live.domain.LiveOrderItem;
+import com.fs.live.mapper.LiveOrderItemMapper;
+import com.fs.live.mapper.LiveOrderMapper;
 import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.QwUserMapper;
@@ -156,10 +159,15 @@ public class DfOrderServiceImpl implements IErpOrderService {
     @Autowired
     private FsIntegralOrderMapper fsIntegralOrderMapper;
 
+    @Autowired
+    private LiveOrderMapper liveOrderMapper;
+
+    @Autowired
+    private LiveOrderItemMapper liveOrderItemMapper;
 
     @Override
     public ErpOrderResponse addOrder(ErpOrder order) {
-        if (order.getIsIntegralOrder())
+        if (!Objects.isNull(order.getIsIntegralOrder()) && order.getIsIntegralOrder())
             return getErpIntegralOrderResponse(order);
         return getErpOrderResponse(order);
     }
@@ -171,7 +179,51 @@ public class DfOrderServiceImpl implements IErpOrderService {
 
     @Override
     public ErpOrderResponse addLiveOrder(ErpOrder order) {
-        return null;
+        return getLiveErpOrderResponse(order);
+    }
+
+    private ErpOrderResponse getLiveErpOrderResponse(ErpOrder order) {
+        LiveOrder liveOrder = liveOrderMapper.selectLiveOrderByOrderCode(order.getPlatform_code());
+        if (liveOrder == null) {
+            return null;
+        }
+        Long dfAccountId = getSFAccountIndex(liveOrder.getOrderId());
+        //1.获取请求参数
+        ExternalOrderRequestVo vo = getCreateLiveOrderRequestParam(order, liveOrder, dfAccountId);
+        if (vo == null) {
+            return null;
+        }
+        try {
+            Map<String, Object> map = JSON.parseObject(JSON.toJSONString(vo), Map.class);
+            //2.请求
+            log.info("开始推送订单,参数: {}", JSON.toJSONString(map));
+            String response = client.execute(RequestUrlEnum.CREAT_ORDER, map, dfAccountId);
+            DFApiResponse dfApiResponse = JSON.parseObject(response, DFApiResponse.class);
+            //3.处理请求结果
+            if (dfApiResponse != null && "ok".equals(dfApiResponse.getCode())) {
+                //存储订单推送用的哪个账户
+                FsStoreOrderDf df = addDfOrderLive(liveOrder, dfAccountId);
+                log.info("订单推送成功: {}", response);
+                //可以回调 也可以查询订单
+                Map<String, Object> orderResultQueryParam = new HashMap<>();
+                orderResultQueryParam.put("orderNumber", order.getPlatform_code());
+                orderResultQueryParam.put("exInterfaceType", df.getStatus());
+                try {
+                    getOrderLiveResult(orderResultQueryParam, dfAccountId);
+                } catch (Exception e) {
+                    log.info("推送订单完成,查询订单问题{}", e.getMessage());
+                }
+                ErpOrderResponse erpOrderResponse = new ErpOrderResponse();
+                erpOrderResponse.setCode(order.getPlatform_code());
+                erpOrderResponse.setSuccess(true);
+                return erpOrderResponse;
+            } else {
+                throw new RuntimeException(String.format("订单推送失败,原因: %s", dfApiResponse.getMsg()));
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return new ErpOrderResponse();
     }
 
     /**
@@ -286,7 +338,50 @@ public class DfOrderServiceImpl implements IErpOrderService {
 
     @Override
     public ErpOrderResponse refundLiveOrder(ErpRefundOrder order) {
-        return null;
+        //获取代服账户
+        String orderCode = order.getOrderCode();
+        LiveOrder liveOrder = liveOrderMapper.selectLiveOrderByOrderCode(orderCode);
+        FsStoreOrderDf df = fsStoreOrderDfMapper.selectFsStoreOrderDfByOrderId(liveOrder.getOrderId());
+        if (df == null) {
+            return null;
+        }
+        Long dfAccountId = getSFAccountIndex(liveOrder.getOrderId());
+        HashMap<String, Object> map = new HashMap<>();
+        map.put("loginAccount", df.getLoginAccount());
+        FsDfAccount dfAccount = fsDfAccountMapper.selectFsDfAccountById(dfAccountId);
+        if (dfAccount != null && StringUtils.isNotBlank(dfAccount.getCallBackUrl())) {
+            map.put("callBackUrl", dfAccount.getCallBackUrl());
+        }
+        map.put("orderNumber", orderCode);
+        map.put("mailNumber", liveOrder.getDeliverySn());
+        try {
+            //2.请求
+            log.info("开始取消订单,参数: {}", JSON.toJSONString(map));
+            String response = client.execute(RequestUrlEnum.ORDER_CANCEL, map, dfAccountId);
+            DFApiResponse dfApiResponse = JSON.parseObject(response, DFApiResponse.class);
+            //3.处理请求结果
+            if (dfApiResponse != null && "ok".equals(dfApiResponse.getCode())) {
+                //存储订单推送用的哪个账户
+                log.info("订单取消成功: {}", response);
+                //修改df表
+                df.setStatus(2);
+                df.setUpdateTime(DateUtils.getNowDate());
+                fsStoreOrderDfMapper.updateFsStoreOrderDf(df);
+                //可以回调 也可以查询订单
+                Map<String, Object> orderResultQueryParam = new HashMap<>();
+                orderResultQueryParam.put("orderNumber", orderCode);
+                orderResultQueryParam.put("exInterfaceType", 2); //2为查询取消订单结果
+                ErpOrderResponse erpOrderResponse = new ErpOrderResponse();
+                erpOrderResponse.setCode(orderCode);
+                erpOrderResponse.setSuccess(true);
+                return erpOrderResponse;
+            } else {
+                throw new RuntimeException(String.format("订单取消失败,原因: %s", dfApiResponse.getMsg()));
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return new ErpOrderResponse();
     }
 
     @Override
@@ -441,7 +536,30 @@ public class DfOrderServiceImpl implements IErpOrderService {
 
     @Override
     public ErpOrderQueryResponse getLiveOrder(ErpOrderQueryRequert param) {
-        return null;
+        ErpOrderQueryResponse response = new ErpOrderQueryResponse();
+        String orderNumber = param.getCode();
+        if (StrUtil.isNotBlank(orderNumber)) {
+            LiveOrder order = liveOrderMapper.selectLiveOrderByOrderCode(orderNumber);
+            if (order != null) {
+                //获取下单账户
+                FsStoreOrderDf df = fsStoreOrderDfMapper.selectFsStoreOrderDfByOrderId(order.getOrderId());
+                if (df == null) {
+                    return null;
+                }
+                Long dfAccountId = getSFAccountIndex(order.getOrderId());
+                if (dfAccountId != null) {
+                    Map<String, Object> orderResultQueryParam = new HashMap<>();
+                    orderResultQueryParam.put("orderNumber", orderNumber);
+                    orderResultQueryParam.put("exInterfaceType", df.getStatus());
+                    getOrderLiveResult(orderResultQueryParam, dfAccountId);
+                    return response;
+                }
+            }
+            response.setErrorDesc("该订单不存在/顺丰账户不存在");
+        } else {
+            response.setErrorDesc("未获取到原始订单号");
+        }
+        return response;
     }
 
     @Override
@@ -460,7 +578,9 @@ public class DfOrderServiceImpl implements IErpOrderService {
 
     @Override
     public BaseResponse refundUpdateLive(ErpRefundUpdateRequest param) {
-        return null;
+        ErpRefundOrder erpRefundOrder = new ErpRefundOrder();
+        erpRefundOrder.setOrderCode(param.getTid());
+        return refundLiveOrder(erpRefundOrder);
     }
 
     @Override
@@ -790,7 +910,97 @@ public class DfOrderServiceImpl implements IErpOrderService {
 
     @Override
     public void getOrderLiveDeliveryStatus(LiveOrder order) {
+        Map<String, Object> map = new HashMap<>();
+        Long dfAccountId = getSFAccountIndex(order.getOrderId());
+        map.put("orderNumber", order.getOrderCode());
+        map.put("mailNumber", order.getDeliverySn());
+        try {
+            String response = client.execute(RequestUrlEnum.ORDER_DELIVERY_STATUS, map, dfAccountId);
+            DFApiResponse dfApiResponse = JSON.parseObject(response, DFApiResponse.class);
+            if ("运单不存在".equals(dfApiResponse.getMsg())) {
+                //查看原来物流状态
+                cancelOrderLive(order);
+                log.info("代服管家 getOrderDeliveryStatus: {}", response);
+                return;
+            }
+            //3.处理请求结果
+            if (dfApiResponse != null && "ok".equals(dfApiResponse.getCode())) {
+                String jsonString = JSON.toJSONString(dfApiResponse.getResult());
+                DFOrderStatusResultRequest temp = JSON.parseObject(jsonString, DFOrderStatusResultRequest.class);
+                //0待揽收 1已揽收 2运输中 3派送中 4异常件 5退回件 6退回签收 7转寄件 8作废件 9已签收 10 已取消
+                Integer deliveryStatus = 0;
+                String stateEx = "0";
+                LiveOrder liveOrderMap = new LiveOrder();
+                liveOrderMap.setOrderId(order.getOrderId());
+                Integer status = temp.getStatus();
+                switch (status) {
+                    case 0:
+                    case 1:
+                    case 2:
+                        deliveryStatus = status;
+                        stateEx = status.toString();
+                        break;
+                    case 3:
+                        deliveryStatus = 2;
+                        stateEx = "202";
+                        break;
+                    case 4:
+                        deliveryStatus = status;
+                        stateEx = status.toString();
+                        break;
+                    case 5:
+                        deliveryStatus = 4;
+                        stateEx = "407";
+                        break;
+                    case 6:
+                        deliveryStatus = status;
+                        stateEx = "406";
+                        break;
+                    case 9:
+                        deliveryStatus = 3;
+                        stateEx = "301";
+                        break;
+                    case 10:
+                        String mailNumber = temp.getMailNumber();
+                        List<LiveOrder> liveOrders = liveOrderMapper.selectLiveOrderList(new LiveOrder() {{
+                            setDeliverySn(mailNumber);
+                        }});
+                        if (liveOrders != null && !liveOrders.isEmpty()) {
+                            liveOrders.forEach(tempOrder -> {
+                                cancelOrderLive(tempOrder);
+                                log.info("代服管家 订单取消成功: {}", response);
+                            });
+                        }
+                        break;
+                }
+                liveOrderMap.setDeliveryStatus(deliveryStatus);
+                liveOrderMap.setDeliveryType(stateEx);
+                liveOrderMapper.updateLiveOrder(liveOrderMap);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
 
+    private void cancelOrderLive(LiveOrder order) {
+        Integer deliveryStatus = order.getDeliveryStatus();
+        if (deliveryStatus == null || deliveryStatus == 0) {
+            //没有物流信息
+            //修改订单状态 方便后续重新发货
+            order.setStatus(1);
+            order.setExtendOrderId("");
+            order.setDeliverySn("");
+            liveOrderMapper.updateLiveOrder(order);
+        } else {
+            //有物流信息->售后处理
+            //取消订单
+            // TODO: 实现直播订单退款逻辑
+        }
+        FsStoreOrderDf df = new FsStoreOrderDf();
+        df.setOrderId(order.getOrderId());
+        df.setStatus(2);
+        df.setUpdateTime(new Date());
+        fsStoreOrderDfMapper.updateFsStoreOrderDf(df);
     }
 
     private void cancelOrder(FsStoreOrder order) {
@@ -1865,4 +2075,224 @@ public class DfOrderServiceImpl implements IErpOrderService {
         }
     }
 
+    private ExternalOrderRequestVo getCreateLiveOrderRequestParam(ErpOrder order, LiveOrder liveOrder, Long dfAccountId) {
+        ExternalOrderRequestVo vo = new ExternalOrderRequestVo();
+        FsDfAccount dfAccount = fsDfAccountMapper.selectFsDfAccountById(dfAccountId);
+        if (dfAccount == null) {
+            return null;
+        }
+        String loginAccount = dfAccount.getLoginAccount();
+        vo.setMonthlyCard(dfAccount.getMonthlyCard());
+        vo.setExpressProductCode(dfAccount.getExpressProductCode());
+        vo.setLoginAccount(loginAccount);
+        String callBackUrl = dfAccount.getCallBackUrl();
+        if (StringUtils.isNotBlank(callBackUrl)) {
+            vo.setCallBackUrl(callBackUrl);
+        }
+        FsStoreOrderDf temp = fsStoreOrderDfMapper.selectFsStoreOrderDfByOrderId(liveOrder.getOrderId());
+        if (temp != null) {
+            vo.setParcelQuantity(temp.getParcelQuantity());
+        }
+        vo.setOrderNumber(order.getPlatform_code());
+        int orderPayMethod = 0;
+        BigDecimal couponPrice = liveOrder.getCouponPrice();
+        if (couponPrice == null) {
+            couponPrice = BigDecimal.ZERO;
+        }
+        if ("1".equals(liveOrder.getPayType())) {
+            orderPayMethod = 1;
+        } else {
+            orderPayMethod = 2;
+            vo.setCollectingMoney(liveOrder.getDeliveryPayMoney().doubleValue());
+            vo.setCollectionCardNumber(dfAccount.getMonthlyCard());
+        }
+        vo.setOrderPayMethod(orderPayMethod);
+        vo.setConsignmentNumber(Integer.valueOf(liveOrder.getTotalNum()));
+        vo.setBuyerMessage(liveOrder.getRemark());
+        vo.setSenderName(dfAccount.getSenderName());
+        vo.setSenderPhone(dfAccount.getSenderPhone());
+        vo.setSenderProvince(dfAccount.getSenderProvince());
+        vo.setSenderCity(dfAccount.getSenderCity());
+        vo.setSenderDistrict(dfAccount.getSenderDistrict());
+        vo.setSenderAddress(dfAccount.getSenderAddress());
+        vo.setReceiverName(order.getReceiver_name());
+        vo.setReceiverPhone(order.getReceiver_mobile());
+        vo.setReceiverTelephone(order.getReceiver_phone());
+        vo.setReceiverProvince(order.getReceiver_province());
+        vo.setReceiverCity(order.getReceiver_city());
+        vo.setReceiverDistrict(order.getReceiver_district());
+        vo.setReceiverAddress(order.getReceiver_address());
+        vo.setExpressPayMethod(1);
+        StringBuilder consignmentStr = new StringBuilder();
+        List<LiveOrderItem> items = liveOrderItemMapper.selectLiveOrderItemByOrderId(liveOrder.getOrderId());
+        if (items != null && !items.isEmpty()) {
+            ArrayList<ExteriorOrderSkuVo> orderSkus = new ArrayList<>();
+            items.forEach(item -> {
+                ExteriorOrderSkuVo skuVo = new ExteriorOrderSkuVo();
+                FsStoreProductScrm product = fsStoreProductScrmMapper.selectFsStoreProductById(item.getProductId());
+                Asserts.check(ObjectUtils.isNotNull(product), "该产品不存在! 产品id: {} ", item.getProductId());
+                skuVo.setProductName(product.getProductName());
+                com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(item.getJsonInfo());
+                skuVo.setSkuCode(jsonObject.getString("sku"));
+                String barCode = jsonObject.getString("barCode");
+                if (StringUtils.isNotBlank(barCode)) {
+                    skuVo.setProductCode(barCode);
+                } else {
+                    skuVo.setProductCode(item.getProductId().toString());
+                }
+                skuVo.setAttributeNames(jsonObject.getString("sku"));
+                skuVo.setProductNumber(Math.toIntExact(item.getNum()));
+                skuVo.setPrice(product.getPrice().doubleValue());
+                skuVo.setSubAmount(product.getPrice().doubleValue() * item.getNum());
+                consignmentStr.append(product.getProductName()).append("*").append(item.getNum()).append(",");
+                orderSkus.add(skuVo);
+            });
+            if (consignmentStr.length() > 0) {
+                consignmentStr.deleteCharAt(consignmentStr.length() - 1);
+            }
+            if (consignmentStr.length() > 100) {
+                consignmentStr.delete(consignmentStr.length() - 4, consignmentStr.length());
+                consignmentStr.append("...");
+            }
+            vo.setOrderSkus(orderSkus);
+            vo.setConsignment(consignmentStr.toString());
+        }
+        return vo;
+    }
+
+    private FsStoreOrderDf addDfOrderLive(LiveOrder liveOrder, Long dfAccountId) {
+        FsStoreOrderDf df = new FsStoreOrderDf();
+        df.setOrderId(liveOrder.getOrderId());
+        df.setOrderCode(liveOrder.getOrderCode());
+        FsDfAccount dfAccount = fsDfAccountMapper.selectFsDfAccountById(dfAccountId);
+        df.setAppKey(dfAccount.getDfAppKey());
+        df.setAppSecret(dfAccount.getDfAppsecret());
+        df.setLoginAccount(dfAccount.getLoginAccount());
+        df.setMonthlyCard(dfAccount.getMonthlyCard());
+        df.setExpressProductCode(dfAccount.getExpressProductCode());
+        df.setTotalPrice(liveOrder.getPayMoney());
+        df.setPlatformPrice(liveOrder.getPayPrice());
+        df.setStatus(1);
+        FsStoreOrderDf temp = fsStoreOrderDfMapper.selectFsStoreOrderDfByOrderId(df.getOrderId());
+        if (temp != null) {
+            df.setUpdateTime(DateUtils.getNowDate());
+            fsStoreOrderDfMapper.updateFsStoreOrderDf(df);
+        } else {
+            df.setCreateTime(DateUtils.getNowDate());
+            fsStoreOrderDfMapper.insertFsStoreOrderDf(df);
+        }
+        return df;
+    }
+
+    private void getOrderLiveResult(Map<String, Object> map, Long dfAccountId) {
+        try {
+            String status = map.get("exInterfaceType").toString();
+            log.info("开始查询订单结果,参数为: {}", JSON.toJSONString(map));
+            String response = client.execute(RequestUrlEnum.ORDER_RESULT, map, dfAccountId);
+            DFApiResponse dfApiResponse = JSON.parseObject(response, DFApiResponse.class);
+            if (dfApiResponse != null && "ok".equals(dfApiResponse.getCode())) {
+                log.info("查询订单结果,结果: {}", JSON.toJSONString(dfApiResponse));
+                Object result = dfApiResponse.getResult();
+                if (result != null) {
+                    String jsonString = JSON.toJSONString(result);
+                    if ("1".equals(status)) {
+                        BspOrderResponseWrapper bspOrderResponse = JSONUtil.toBean(jsonString, BspOrderResponseWrapper.class);
+                        if (bspOrderResponse != null) {
+                            String failMsg = bspOrderResponse.getFailMsg();
+                            if (StringUtils.isNotBlank(failMsg)) {
+                                if (failMsg.equals("暂未结果, 请稍后再查")) {
+                                    return;
+                                }
+                                String orderNumber = bspOrderResponse.getOrderNumber();
+                                try {
+                                    rollBackOrderLive(orderNumber, failMsg);
+                                } catch (Exception e) {
+                                    log.info("{}订单获取运单失败,订单状态回滚失败,失败原因:{},失败信息为:{}", orderNumber,e.getMessage(),failMsg);
+                                }
+                            } else {
+                                setExpressLive(bspOrderResponse);
+                            }
+                        }
+                    } else if ("2".equals(status)) {
+                        DFCancelOrderResultResponse cancelResponse = JSONUtil.toBean(jsonString, DFCancelOrderResultResponse.class);
+                        if (cancelResponse != null) {
+                            if (cancelResponse.getIsCancelSuss() == 1) {
+                                log.info("查询订单取消成功,返回结果{}", JSON.toJSONString(cancelResponse));
+                            } else {
+                                log.info("查询订单取消失败,返回结果{}", JSON.toJSONString(cancelResponse));
+                            }
+                        }
+                    }
+                }
+            } else {
+                log.info(String.format("查询订单失败,原因: %s", dfApiResponse.getMsg()));
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void rollBackOrderLive(String orderNumber, String failMsg) {
+        LiveOrder liveOrder = liveOrderMapper.selectLiveOrderByOrderCode(orderNumber);
+        LiveOrder tempOrder = new LiveOrder();
+        tempOrder.setOrderId(liveOrder.getOrderId());
+        tempOrder.setExtendOrderId("");
+        liveOrderMapper.updateLiveOrder(tempOrder);
+        FsStoreOrderDf df = new FsStoreOrderDf();
+        df.setOrderId(liveOrder.getOrderId());
+        df.setStatus(0);
+        df.setFailMsg(failMsg);
+        df.setUpdateTime(new Date());
+        fsStoreOrderDfMapper.updateFsStoreOrderDf(df);
+        log.info("{}订单获取运单失败,失败信息为:{}", orderNumber,failMsg);
+    }
+
+    private void setExpressLive(BspOrderResponseWrapper bspResponse) {
+        String orderNumber = bspResponse.getOrderNumber();
+        String mailNumber = bspResponse.getMailNumber();
+        BspOrderResponse bspOrderResponse = bspResponse.getBspResponse();
+        if (bspOrderResponse != null) {
+            AtomicBoolean flag = new AtomicBoolean(false);
+            List<OrderResponse> list = bspOrderResponse.getBody();
+            if (list != null && !list.isEmpty()) {
+                for (OrderResponse orderResponse : list) {
+                    List<RlsInfo> rlsInfo = orderResponse.getRlsInfo();
+                    if (rlsInfo != null && !rlsInfo.isEmpty()) {
+                        for (RlsInfo info : rlsInfo) {
+                            List<RlsDetail> rlsDetails = info.getRlsDetail();
+                            if (rlsDetails != null && !rlsDetails.isEmpty()) {
+                                for (RlsDetail rlsDetail : rlsDetails) {
+                                    String proCode = rlsDetail.getProCode();
+                                    if (StringUtils.isNotBlank(proCode)) {
+                                        LiveOrder order = liveOrderMapper.selectLiveOrderByOrderCode(orderNumber);
+                                        if (order != null && order.getStatus() == 1) {
+                                            FsExpressScrm express = expressScrmService.selectFsExpressByOmsCode(order.getDeliveryCode());
+                                            if (express != null) {
+                                                order.setDeliveryName(proCode);
+                                                order.setDeliverySn(express.getOmsCode());
+                                            }
+                                            order.setStatus(2);
+                                            order.setDeliverySn(mailNumber);
+                                            order.setDeliverySendTime(new Date());
+                                            liveOrderMapper.updateLiveOrder(order);
+                                            redisCache.deleteObject(DELIVERY+":"+order.getExtendOrderId());
+                                            flag.set(true);
+                                        }
+                                        break;
+                                    }
+                                }
+                            }
+                            if (flag.get()) {
+                                break;
+                            }
+                        }
+                    }
+                    if (flag.get()) {
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
 }

+ 4 - 1
fs-service/src/main/java/com/fs/erp/service/impl/ErpOrderServiceImpl.java

@@ -13,6 +13,7 @@ import com.fs.his.domain.FsStoreOrder;
 import com.fs.his.utils.ConfigUtil;
 import com.fs.hisStore.domain.FsStoreOrderScrm;
 import com.fs.live.domain.LiveOrder;
+import com.fs.live.mapper.LiveOrderMapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -24,6 +25,8 @@ public class ErpOrderServiceImpl implements IErpOrderService
     public final static Logger LOGGER = LoggerFactory.getLogger(ErpOrderServiceImpl.class);
     @Autowired
     ConfigUtil configUtil;
+    @Autowired
+    private LiveOrderMapper liveOrderMapper;
     @Override
     public ErpOrderResponse addOrder(ErpOrder order) {
         FsSysConfig sysConfig = configUtil.getSysConfig();
@@ -68,7 +71,7 @@ public class ErpOrderServiceImpl implements IErpOrderService
 
     @Override
     public ErpOrderResponse addLiveOrder(ErpOrder order) {
-        return null;
+        return addOrder(order);
     }
 
     @Override

+ 137 - 0
fs-service/src/main/java/com/fs/erp/service/impl/HzOMSErpOrderServiceImpl.java

@@ -14,7 +14,14 @@ import com.fs.his.domain.*;
 import com.fs.his.service.*;
 import com.fs.his.utils.PhoneUtil;
 import com.fs.hisStore.domain.FsStoreOrderScrm;
+import com.fs.hisStore.domain.FsStoreProductAttrValueScrm;
+import com.fs.hisStore.domain.FsStoreProductScrm;
+import com.fs.hisStore.service.IFsStoreProductAttrValueScrmService;
+import com.fs.hisStore.service.IFsStoreProductScrmService;
 import com.fs.live.domain.LiveOrder;
+import com.fs.live.domain.LiveOrderItem;
+import com.fs.live.mapper.LiveOrderItemMapper;
+import com.fs.live.mapper.LiveOrderMapper;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -50,6 +57,18 @@ public class HzOMSErpOrderServiceImpl implements IErpOrderService {
     @Autowired
     HzOMSClient hzOMSClient;
 
+    @Autowired
+    private LiveOrderMapper liveOrderMapper;
+
+    @Autowired
+    private LiveOrderItemMapper liveOrderItemMapper;
+
+    @Autowired
+    private IFsStoreProductScrmService fsStoreProductScrmService;
+
+    @Autowired
+    private IFsStoreProductAttrValueScrmService fsStoreProductAttrValueScrmService;
+
     @Override
     public ErpOrderResponse addOrder(ErpOrder order) {
         try {
@@ -72,9 +91,127 @@ public class HzOMSErpOrderServiceImpl implements IErpOrderService {
 
     @Override
     public ErpOrderResponse addLiveOrder(ErpOrder order) {
+        try {
+            JSONObject hzOrder = buildHzOMSOrderLive(order.getPlatform_code());
+
+            JSONObject omsOpenPtorderCreate = hzOMSClient.send("oms_open_ptorder_create", hzOrder);
+            ErpOrderResponse res = new ErpOrderResponse();
+            res.setCode("hzomssuccess");
+            return res;
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
         return null;
     }
 
+    private JSONObject buildHzOMSOrderLive(String orderCode) {
+        //通过订单号查询更多订单信息
+        LiveOrder liveOrder = liveOrderMapper.selectLiveOrderByOrderCode(orderCode);
+        FsStore fsStore = fsStoreService.selectFsStoreByStoreId(liveOrder.getStoreId());
+
+        JSONObject obj = new JSONObject();
+        String iordertype = "2"; // 直播订单默认B2C快递配送
+        //订单类型 0 O2O配送订单; 1 O2O 自提订单; 2 B2C 快递配送
+        obj.put("iordertype", iordertype);
+        //订单单号
+        obj.put("cptordercode", liveOrder.getOrderCode());
+        //平台店铺编码 todo 测试环境只能写死 110111 用于联调测试 liveOrder.getStoreId()
+        obj.put("cptshopcode", 110111);
+        //平台店铺名称
+        obj.put("cptshopname", fsStore.getStoreName());
+        Integer iorderstatus = null;
+        //自提且已经支付
+        if ("1".equals(iordertype) && Integer.valueOf(1).equals(liveOrder.getIsPay())) {
+            iorderstatus = 30;
+        } else {
+            if (Integer.valueOf(1).equals(liveOrder.getStatus())) {
+                iorderstatus = 0;
+            } else if (Integer.valueOf(2).equals(liveOrder.getStatus())) {
+                iorderstatus = 5;
+            }
+        }
+        //订单状态 0待接单 5待拣货 10待配送 15配送中 20已完成 25已取消 30待自提
+        obj.put("iorderstatus", iorderstatus);
+
+        String userAddress = liveOrder.getUserAddress();
+        String[] s = null;
+        if (StringUtils.isNotBlank(userAddress)) {
+            s = userAddress.split(" ");
+        } else {
+            throw new RuntimeException("用户收货地址有问题");
+        }
+
+        //收货省
+        obj.put("cprovince", s[0]);
+        //收货市
+        obj.put("ccity", s[1]);
+        //收货区
+        obj.put("carea", s[2]);
+        //收货人密文 无密文填写明文
+        obj.put("creceivers", liveOrder.getRealName());
+        //收货人联系电话密文 无密文填写明文
+        obj.put("creceiversphone", liveOrder.getUserPhone());
+        //收货人详细地址密文 无密文填写明文
+        obj.put("creceiversaddress", userAddress);
+        //收货人脱敏信息
+        obj.put("cdesenreceivers", liveOrder.getRealName());
+        //收货联系电话脱敏信息
+        obj.put("cdesenreceiversphone", PhoneUtil.decryptPhone(liveOrder.getUserPhone()));
+        //收货联系地址脱敏信息
+        obj.put("cdesenreceiversaddress", userAddress);
+        //订单总金额 单位元
+        obj.put("forderamount", liveOrder.getTotalPrice());
+        //支付金额 单位元
+        obj.put("fpayamount", liveOrder.getPayPrice());
+        //订单总优惠 单位元
+        obj.put("fdiscamount", liveOrder.getDiscountMoney());
+        //运费
+        obj.put("ffreight", liveOrder.getPayDelivery());
+        //下单时间 格式 yyyy-MM-dd hh:mm:ss 如:2025-01-01 00:11:22
+        obj.put("dorderstarttime", liveOrder.getCreateTime());
+        //是否处方 0 否 1 是 可选
+        obj.put("iisprescription", 0);
+        //买家备注
+        obj.put("corderremark", liveOrder.getRemark());
+        //支付时间  格式 yyyy-MM-dd hh:mm:ss 如:2025-01-01 00:11:22
+        obj.put("dpurchasetime", liveOrder.getPayTime());
+        List<LiveOrderItem> liveOrderItems = liveOrderItemMapper.selectLiveOrderItemByOrderId(liveOrder.getOrderId());
+        int totalOrderItemCount = liveOrderItems.size();
+        BigDecimal divide = liveOrder.getDiscountMoney().divide(BigDecimal.valueOf(totalOrderItemCount), 2, BigDecimal.ROUND_HALF_UP);
+        JSONArray goodArr = new JSONArray();
+
+        liveOrderItems.forEach(liveOrderItem -> {
+            JSONObject goodItem = new JSONObject();
+            //商品编码
+            goodItem.put("cptgoodsid", liveOrderItem.getProductId());
+            //商品规格编码
+            goodItem.put("cptspeccode", liveOrderItem.getProductAttrValueId());
+
+            FsStoreProductScrm fsStoreProduct = fsStoreProductScrmService.selectFsStoreProductById(liveOrderItem.getProductId());
+            FsStoreProductAttrValueScrm fsStoreProductAttrValue = new FsStoreProductAttrValueScrm();
+            //判断是否含有商品规格信息 有则查询商品规格信息 没有取商品的价格
+            if(null != liveOrderItem.getProductAttrValueId()){
+                fsStoreProductAttrValue = fsStoreProductAttrValueScrmService.selectFsStoreProductAttrValueById(liveOrderItem.getProductAttrValueId());
+            }else{
+                fsStoreProductAttrValue.setPrice(fsStoreProduct.getPrice());
+            }
+            //商品名称
+            goodItem.put("cgoodsname", fsStoreProduct.getProductName());
+            //购买数量
+            goodItem.put("fqty", liveOrderItem.getNum());
+            //原单价
+            goodItem.put("fnormprice", fsStoreProductAttrValue.getPrice());
+
+            //实售单价 优惠后的单价 单位元
+            goodItem.put("fprice", fsStoreProductAttrValue.getPrice().subtract(divide));
+            goodArr.add(goodItem);
+        });
+        //订单商品信息
+        obj.put("ptorder_goods_list", goodArr);
+
+        return obj;
+    }
+
     @Override
     public ErpOrderResponse refundOrder(ErpRefundOrder order) {
         String orderCode = order.getOrderCode();

+ 151 - 1
fs-service/src/main/java/com/fs/erp/service/impl/K9OrderScrmServiceImpl.java

@@ -23,6 +23,9 @@ import com.fs.hisStore.mapper.FsStoreProductScrmMapper;
 import com.fs.hisStore.service.IFsStoreOrderItemScrmService;
 import com.fs.hisStore.vo.FsStoreOrderItemVO;
 import com.fs.live.domain.LiveOrder;
+import com.fs.live.domain.LiveOrderItem;
+import com.fs.live.mapper.LiveOrderItemMapper;
+import com.fs.live.mapper.LiveOrderMapper;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -52,6 +55,13 @@ public class K9OrderScrmServiceImpl implements IErpOrderService {
     private IFsStoreOrderItemScrmService storeOrderItemService;
     @Autowired
     private FsStoreProductScrmMapper productMapper;
+
+    @Autowired
+    private LiveOrderMapper liveOrderMapper;
+
+    @Autowired
+    private LiveOrderItemMapper liveOrderItemMapper;
+
     @Override
     /**
      * 推送erp订单
@@ -67,7 +77,147 @@ public class K9OrderScrmServiceImpl implements IErpOrderService {
 
     @Override
     public ErpOrderResponse addLiveOrder(ErpOrder order) {
-        return null;
+        return addOmsOrderLive(order.getPlatform_code());
+    }
+
+    private ErpOrderResponse addOmsOrderLive(String orderCode) {
+        try {
+            KingbosOrderResponse response = this.createOmsOrderLive(orderCode, NO_DELIVERED.getCode());
+            if (response.getIsSuccess()){
+                log.info("订单推送成功: {}", response);
+                ErpOrderResponse erpOrderResponse = new ErpOrderResponse();
+                erpOrderResponse.setCode(response.getCbilid());
+                return erpOrderResponse;
+            }else {
+                throw new RuntimeException(String.format("订单推送失败,原因: %s",response.getErrmsg()));
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return new ErpOrderResponse();
+    }
+
+    private KingbosOrderResponse createOmsOrderLive(String orderCode, String orderStatus){
+        logger.info("【金博网络订单】开始创建订单,订单Code: {}", orderCode);
+        try {
+            LiveOrder order = liveOrderMapper.selectLiveOrderByOrderCode(orderCode);
+            logger.info("【金博网络订单】订单信息获取成功,订单id: {}", order.getOrderId());
+            logger.info("【金博网络订单】订单信息获取成功,订单号: {}", order.getOrderCode());
+
+            KingbosOrderData data = buildKingbosOrderDataLive(order, orderStatus);
+            logger.info("【金博网络订单】订单数据构建完成,金博订单号: {}", data.getCo_id());
+
+            List<KingbosOrderD1Data> d1Datas = buildOrderDetailDataLive(order, data.getCdo_id());
+            logger.info("【金博网络订单】订单明细数据构建完成,明细数量: {}", d1Datas.size());
+
+            KingbosOrderResponse response = sendOrderRequest(data, d1Datas);
+            if (response.getCbilid()==null){
+                response.setCbilid(order.getExtendOrderId());
+            }
+            return response;
+        } catch (Exception e) {
+            logger.error("【金博网络订单】创建订单失败,订单Code: {}, 错误信息: {}", orderCode, e.getMessage(), e);
+            throw e;
+        }
+    }
+
+    private KingbosOrderData buildKingbosOrderDataLive(LiveOrder order, String orderStatus) {
+        FsErpConfig erpConfig = configUtil.getErpConfig();
+        logger.debug("【金博网络订单】开始构建订单数据,订单号: {}", order.getOrderCode());
+        KingbosOrderData data = new KingbosOrderData();
+        data.setCordersource("MALL");
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        data.setDorder_date(sdf.format(order.getCreateTime()));
+        data.setCplatformtype("99");
+        data.setCshop_id("zk2025");
+        data.setCshop_name("自建商城");
+        String orderSn = "";
+        if (orderStatus.equals(NO_DELIVERED.getCode())){
+            orderSn= IdUtil.getSnowflake(0, 0).nextIdStr();
+        }else if (orderStatus.equals(CANCELLED.getCode())){
+            orderSn = order.getExtendOrderId();
+        }
+
+        data.setCso_id(order.getOrderCode());
+        data.setCo_id(orderSn);
+        data.setCdo_id(orderSn);
+        order.setExtendOrderId(orderSn);
+
+        data.setFpay_amount(order.getPayPrice());
+        data.setFpaid_amount(order.getPayMoney());
+        data.setFfreight(order.getTotalPostage());
+        data.setFfree_amount(order.getCouponPrice());
+        data.setFpostcost(BigDecimal.ZERO);
+
+        data.setCstatus(orderStatus);
+        data.setDmodified(sdf.format(order.getUpdateTime()));
+
+        setReceiverInfoLive(data, order);
+
+        data.setCwarehouse_code(erpConfig.getCwarehouseCode());
+        data.setCwarehouse_name(erpConfig.getCwarehouseName());
+
+        if (!order.getPayType().equals("1")) {
+            data.setBis_cod(1);
+            data.setFshouldpaymoney(order.getDeliveryPayMoney());
+        }
+
+        return data;
+    }
+
+    private void setReceiverInfoLive(KingbosOrderData data, LiveOrder order) {
+        logger.debug("【金博网络订单】开始处理收货信息,订单号: {}", order.getOrderCode());
+        String[] address = order.getUserAddress().split(" ");
+        if (address.length < 3) {
+            logger.error("【金博网络订单】收货地址格式不正确,订单号: {}, 地址: {}", order.getOrderCode(), order.getUserAddress());
+            throw new ServiceException("收货地址格式不正确");
+        }
+
+        data.setCreceiver_state(address[0]);
+        data.setCreceiver_city(address[1]);
+        data.setCreceiver_district(address[2]);
+
+        String detailAddress = address.length > 3 ?
+            String.join("", Arrays.copyOfRange(address, 3, address.length)) :
+            address[2];
+
+        detailAddress = detailAddress.replace("+", "加")
+                                   .replace("\n", "");
+
+        data.setCreceiver_address(detailAddress);
+        data.setCreceiver_name(order.getRealName());
+        data.setCreceiver_mobile(order.getUserPhone());
+    }
+
+    private List<KingbosOrderD1Data> buildOrderDetailDataLive(LiveOrder order, String orderId) {
+        logger.debug("【金博网络订单】开始构建订单明细,订单号: {}", order.getOrderCode());
+        List<LiveOrderItem> orderItems = liveOrderItemMapper.selectLiveOrderItemByOrderId(order.getOrderId());
+        List<KingbosOrderD1Data> d1Datas = orderItems.stream()
+                .map(item -> buildOrderDetailItemLive(item, orderId))
+                .collect(Collectors.toList());
+
+        logger.debug("【金博网络订单】订单明细构建完成,订单号: {}, 明细数量: {}", order.getOrderCode(), d1Datas.size());
+        return d1Datas;
+    }
+
+    private KingbosOrderD1Data buildOrderDetailItemLive(LiveOrderItem orderItem, String orderId) {
+        FsStoreCartDTO cartDTO = JSONUtil.toBean(orderItem.getJsonInfo(), FsStoreCartDTO.class);
+        BigDecimal quantity = new BigDecimal(orderItem.getNum());
+
+        KingbosOrderD1Data item = new KingbosOrderD1Data();
+        item.setCdo_id(orderId);
+        item.setCo_id(orderId);
+        item.setCsku_id(cartDTO.getBarCode());
+        item.setCgoodsid(cartDTO.getBarCode());
+        item.setCname(cartDTO.getProductName());
+        item.setCshop_sku_id(cartDTO.getSku());
+        item.setIqty(quantity);
+        item.setFprice(cartDTO.getPrice());
+        item.setFamount(quantity.multiply(cartDTO.getPrice()));
+        item.setCordersource("MALL");
+        item.setFpromoamount(BigDecimal.ZERO);
+
+        return item;
     }
 
 

+ 181 - 1
fs-service/src/main/java/com/fs/erp/service/impl/WdtErpOrderServiceImpl.java

@@ -33,6 +33,9 @@ import com.fs.hisStore.service.IFsStoreOrderItemScrmService;
 import com.fs.hisStore.service.IFsStoreOrderScrmService;
 import com.fs.hisStore.service.IFsStoreProductScrmService;
 import com.fs.live.domain.LiveOrder;
+import com.fs.live.domain.LiveOrderItem;
+import com.fs.live.mapper.LiveOrderItemMapper;
+import com.fs.live.mapper.LiveOrderMapper;
 import com.hc.openapi.tool.util.StringUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
@@ -71,6 +74,12 @@ public class WdtErpOrderServiceImpl implements IErpOrderService {
     @Autowired
     private IFsStoreProductScrmService fsStoreProductScrmService;
 
+    @Autowired
+    private LiveOrderMapper liveOrderMapper;
+
+    @Autowired
+    private LiveOrderItemMapper liveOrderItemMapper;
+
 //    @Value("${fsConfig.erpWdShopCode}")
 //    private String shopCode;
 
@@ -106,7 +115,178 @@ public class WdtErpOrderServiceImpl implements IErpOrderService {
 
     @Override
     public ErpOrderResponse addLiveOrder(ErpOrder order) {
-        return null;
+        return getErpOrderResponseLive(order);
+    }
+
+    private ErpOrderResponse getErpOrderResponseLive(ErpOrder order) {
+        FsSysConfig sysConfig = configUtil.getSysConfig();
+        String shopCode = sysConfig.getErpWdShopCode();
+
+        ErpWdtBusinessRequestParams erpWdtBusinessRequestParams = new ErpWdtBusinessRequestParams();
+        erpWdtBusinessRequestParams.setShopNo(shopCode);
+        erpWdtBusinessRequestParams.setSwitchMode(0);
+        ErpWdtTrade erpWdtTrade = new ErpWdtTrade();
+        LiveOrder liveOrder = liveOrderMapper.selectLiveOrderByOrderCode(order.getPlatform_code());
+        BigDecimal couponPrice = liveOrder.getCouponPrice();
+        if (couponPrice == null) {
+            couponPrice = BigDecimal.ZERO;
+        }
+
+        // 平台状态
+        erpWdtTrade.setTradeStatus(TradeStatus.PAID_WAITING_FOR_SHIPMENT.getValue());
+
+        // 订单id
+        erpWdtTrade.setTid(order.getPlatform_code());
+
+        // 如果是货到付款
+        if("2".equals(liveOrder.getPayType())){
+            // 支付状态
+            erpWdtTrade.setPayStatus(PaymentStatus.PARTIALLY_PAID.getValue());
+            // 发货条件
+            erpWdtTrade.setDeliveryTerm(DeliveryTerm.CASH_ON_DELIVERY.getValue());
+            // 货到付款金额 = 物流代收金额-优惠金额
+            erpWdtTrade.setCodAmount(liveOrder.getPayDelivery().subtract(couponPrice));
+
+        } else if("3".equals(liveOrder.getPayType())){
+            // 支付状态
+            erpWdtTrade.setPayStatus(PaymentStatus.UNPAID.getValue());
+            // 发货条件
+            erpWdtTrade.setDeliveryTerm(DeliveryTerm.CASH_ON_DELIVERY.getValue());
+            // 货到付款金额 = 物流代收金额-优惠金额
+            erpWdtTrade.setCodAmount(liveOrder.getPayDelivery().subtract(couponPrice));
+        } else { // 如果是线上付款
+            // 支付状态
+            erpWdtTrade.setPayStatus(PaymentStatus.FULLY_PAID.getValue());
+            // 发货条件
+            erpWdtTrade.setDeliveryTerm(DeliveryTerm.PAYMENT_BEFORE_DELIVERY.getValue());
+        }
+
+        // 下单时间
+        erpWdtTrade.setTradeTime(order.getDeal_datetime());
+        // 支付时间
+        erpWdtTrade.setPayTime(order.getDeal_datetime());
+        // 分销类别
+        erpWdtTrade.setFenxiaoType(FenxiaoType.JINGXIAO.getValue());
+        // 客户网名
+        erpWdtTrade.setBuyerNick(order.getReceiver_name());
+        // 收件人姓名
+        erpWdtTrade.setReceiverName(order.getReceiver_name());
+        // 省份
+        erpWdtTrade.setReceiverProvince(order.getReceiver_province());
+        // 市
+        erpWdtTrade.setReceiverCity(order.getReceiver_city());
+        // 区
+        erpWdtTrade.setReceiverDistrict(order.getReceiver_district());
+        // 详细地址
+        erpWdtTrade.setReceiverAddress(order.getReceiver_address());
+        // 手机
+        erpWdtTrade.setReceiverMobile(order.getReceiver_mobile());
+        // 固定电话
+        erpWdtTrade.setReceiverTelno(order.getReceiver_mobile());
+        // 买家备注
+        erpWdtTrade.setBuyerMessage(order.getBuyer_memo());
+        // 卖家备注
+        erpWdtTrade.setSellerMemo(order.getSeller_memo());
+        erpWdtTrade.setWarehouseNo(order.getWarehouse_code());
+
+        // 运费金额
+        erpWdtTrade.setPostAmount(liveOrder.getPayDelivery());
+        // 已付金额
+        if(ObjectUtils.isNotNull(liveOrder)){
+            erpWdtTrade.setPaid(liveOrder.getPayMoney());
+        }
+
+        List<LiveOrderItem> liveOrderItems = liveOrderItemMapper.selectLiveOrderItemByOrderId(liveOrder.getOrderId());
+        List<ErpWdtOrder> erpWdtOrderList = new ArrayList<>();
+        // 商品总价
+        BigDecimal totalPrice = liveOrder.getTotalPrice();
+
+        // 总折扣金额 = 优惠券金额 + 折扣金额
+        BigDecimal totalDiscountPrice = BigDecimal.ZERO;
+        // 折扣金额
+        BigDecimal discountPrice = totalPrice.subtract(liveOrder.getPayPrice());
+        totalDiscountPrice = couponPrice.add(discountPrice);
+
+        // 防止除零错误
+        if (totalPrice.compareTo(BigDecimal.ZERO) == 0) {
+            totalPrice = BigDecimal.ONE;
+        }
+
+        for (LiveOrderItem liveOrderItem : liveOrderItems) {
+            ErpWdtOrder erpWdtOrder = new ErpWdtOrder();
+            //平台订单货品表主键
+            erpWdtOrder.setOid(String.format("%s%s",liveOrder.getOrderCode(),liveOrderItem.getItemId()));
+            erpWdtOrder.setNum(BigDecimal.valueOf(liveOrderItem.getNum()));
+            FsStoreProductScrm fsStoreProduct = fsStoreProductScrmService.selectFsStoreProductById(liveOrderItem.getProductId());
+            Asserts.check(ObjectUtils.isNotNull(fsStoreProduct),"该产品不存在! 产品id: {} ",liveOrderItem.getProductId());
+            // 单价
+            erpWdtOrder.setPrice(fsStoreProduct.getPrice());
+            // 状态
+            erpWdtOrder.setStatus(TradeStatus.PAID_WAITING_FOR_SHIPMENT.getValue());
+            // 退款状态
+            erpWdtOrder.setRefundStatus(RefundStatus.NO_REFUND.getValue());
+
+            // 平台货品ID
+            erpWdtOrder.setGoodsId(String.valueOf(fsStoreProduct.getProductId()));
+            JSONObject jsonObject = JSON.parseObject(liveOrderItem.getJsonInfo());
+            erpWdtOrder.setSpecId(jsonObject.getString("sku"));
+            erpWdtOrder.setGoodsNo(jsonObject.getString("barCode"));
+            erpWdtOrder.setSpecNo(jsonObject.getString("sku"));
+            // 货品名称
+            erpWdtOrder.setGoodsName(fsStoreProduct.getProductName());
+            // 调整
+            erpWdtOrder.setAdjustAmount(BigDecimal.ZERO);
+            // 优惠
+            erpWdtOrder.setDiscount(BigDecimal.ZERO);
+            // 分摊优惠
+            // 分摊比例
+            BigDecimal price = fsStoreProduct.getPrice().multiply(BigDecimal.valueOf(liveOrderItem.getNum()));
+            BigDecimal divide = price.divide(totalPrice, RoundingMode.HALF_UP);
+            erpWdtOrder.setShareDiscount(divide.multiply(totalDiscountPrice));
+
+            erpWdtOrderList.add(erpWdtOrder);
+        }
+
+        // 最后一个商品的分摊优惠等于总优惠减去前面分摊优惠之和
+        Asserts.check(CollectionUtils.isNotEmpty(erpWdtOrderList),"订单 {} 商品不能为空!", order.getPlatform_code());
+        long size = erpWdtOrderList.size();
+        if(size > 1) {
+            ErpWdtOrder erpWdtOrder = erpWdtOrderList.get(erpWdtOrderList.size() - 1);
+            erpWdtOrder.setShareDiscount(totalDiscountPrice.subtract(erpWdtOrderList.stream()
+                    .limit(size - 1L)
+                    .map(item -> Optional.ofNullable(item.getShareDiscount()).orElse(BigDecimal.ZERO))
+                    .reduce(BigDecimal.ZERO, BigDecimal::add)));
+        }
+
+        erpWdtTrade.setOrderList(erpWdtOrderList);
+        erpWdtBusinessRequestParams.setTradeList(new ArrayList<>(Arrays.asList(erpWdtTrade)));
+
+        Map<String,String> map = new HashMap<>();
+        map.put("shop_no",erpWdtBusinessRequestParams.getShopNo());
+        map.put("switch_mode", String.valueOf(erpWdtBusinessRequestParams.getSwitchMode()));
+        map.put("trade_list", convertToSnakeCase(erpWdtBusinessRequestParams.getTradeList()));
+
+
+        try {
+            String response = client.execute("trade_push.php", map);
+            ParserConfig config = new ParserConfig();
+            config.propertyNamingStrategy = PropertyNamingStrategy.CamelCase;
+            ErpWdtApiResponse erpWdtApiResponse = JSON.parseObject(response, ErpWdtApiResponse.class,config);
+            if(ObjectUtil.equal(0,erpWdtApiResponse.getCode())){
+                log.info("订单推送成功: {}", response);
+                ErpOrderResponse erpOrderResponse = new ErpOrderResponse();
+                erpOrderResponse.setCode(order.getPlatform_code());
+                erpOrderResponse.setSuccess(true);
+                erpOrderResponse.setRequestRawData(JSON.toJSONString(map));
+                erpOrderResponse.setResponseRawData(response);
+                return erpOrderResponse;
+            } else {
+                throw new RuntimeException(String.format("订单推送失败,原因: %s",erpWdtApiResponse.getMessage()));
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return new ErpOrderResponse();
     }
 
     /**

+ 3 - 3
fs-service/src/main/java/com/fs/his/service/impl/FsIntegralOrderServiceImpl.java

@@ -356,7 +356,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
         order.setIntegral(totalIntegral.toString());
         order.setItemJson(JSONUtil.toJsonStr(goodsItem));
         order.setUserName(address.getRealName());
-        order.setUserAddress(address.getProvince()+address.getCity()+address.getDistrict()+address.getDetail());
+        order.setUserAddress(address.getProvince()+" "+address.getCity()+" "+address.getDistrict()+" "+address.getDetail());
         order.setUserPhone(address.getPhone());
         order.setCreateTime(new Date());
         order.setCompanyUserId(companyUserId);
@@ -855,7 +855,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
         List<ErpOrderPayment> payments = new ArrayList<>();
         ErpOrderPayment payment = new ErpOrderPayment();
         payment.setPay_type_code("weixin");
-        payment.setPayment(order.getPayMoney().doubleValue());
+        payment.setPayment(0d);
         if (order.getPayTime() != null) {
             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
             String timeString = sdf.format(Date.from((order.getPayTime().atZone(ZoneId.systemDefault()).toInstant())));
@@ -935,7 +935,7 @@ public class FsIntegralOrderServiceImpl implements IFsIntegralOrderService
             JSONObject jsonObject = (JSONObject) obj;
             ErpOrderItem item = new ErpOrderItem();
             item.setOid(jsonObject.getString("goodsId"));
-            item.setItem_code(jsonObject.getString("barCode").trim());//商品编码
+            item.setItem_code(jsonObject.getString("barCode"));//商品编码
             item.setPrice(jsonObject.getString("otPrice"));//市场价
             item.setQty(jsonObject.getInteger("num"));//数量
             item.setRefund(0);

+ 3 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsPrescribeServiceImpl.java

@@ -513,6 +513,9 @@ public class FsPrescribeServiceImpl implements IFsPrescribeService
         fsPrescribe.setUserId(packageOrder.getUserId());
         fsPrescribe.setPrescribeCode(IdUtil.getSnowflake(0, 0).nextIdStr());
         FsPackagePatientDTO patJson = JSON.parseObject(packageOrder.getPatientJson(),FsPackagePatientDTO.class);
+        if(patJson == null || patJson.getPatientId() == null){
+            return null;
+        }
         long currentTimeMillis = System.currentTimeMillis();
         long ageInMillis = currentTimeMillis - patJson.getBirthday();
         long ageInSeconds = ageInMillis / 1000;

+ 1 - 1
fs-service/src/main/java/com/fs/his/service/impl/FsStoreOrderServiceImpl.java

@@ -4215,7 +4215,7 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService {
                 Long doctorID = iFsDoctorService.selectFsDoctorDoctorByPackage();
                 packageOrder.setDoctorId(doctorID);
             }
-            if (packageSubType == 3 ) {
+            if (packageSubType == 3 && !CloudHostUtils.hasCloudHostName("金牛明医")) {
                 inquiryOrderService.createOrderByPackageOrderStatus4(packageOrder);
             }
             prescribeId = fsPrescribeService.insertFsPrescribeByPackageOrder(packageOrder);

+ 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/FsMenuScrm.java

@@ -33,5 +33,7 @@ public class FsMenuScrm extends BaseEntity
 
     private Integer menuType;//菜单类型
 
+    private String appId;
+
 
 }

+ 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();
+
 }

+ 7 - 6
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductScrmMapper.java

@@ -202,6 +202,12 @@ public interface FsStoreProductScrmMapper
             "<if test = 'maps.storeId != null'> " +
             "and p.store_id = #{maps.storeId}" +
             "</if>" +
+            " <if test = 'maps.cateIds != null and maps.cateIds.size() > 0'>\n" +
+            "        and p.cate_id in \n" +
+            "        <foreach collection='maps.cateIds' item='cateId' open='(' separator=',' close=')'>\n" +
+            "            #{cateId}\n" +
+            "        </foreach>\n" +
+            "    </if>"+
             "<if test = 'maps.defaultOrder != null and maps.defaultOrder==\"desc\"  '> " +
             "order by p.sort desc,product_id desc" +
             "</if>" +
@@ -217,12 +223,7 @@ public interface FsStoreProductScrmMapper
             "<if test = 'maps.salesOrder != null  and maps.salesOrder==\"asc\" '> " +
             "order by p.sales asc " +
             "</if>" +
-            " <if test = 'maps.cateIds != null and maps.cateIds.size() > 0'>\n" +
-            "        and p.cate_id in \n" +
-            "        <foreach collection='maps.cateIds' item='cateId' open='(' separator=',' close=')'>\n" +
-            "            #{cateId}\n" +
-            "        </foreach>\n" +
-            "    </if>"+
+
             "<if test = 'maps.newOrder != null and maps.newOrder==\"desc\" '> " +
             "and p.is_new =1 order by p.create_time desc  " +
             "</if>" +

+ 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)

+ 2 - 0
fs-service/src/main/java/com/fs/live/mapper/LiveMapper.java

@@ -144,4 +144,6 @@ public interface LiveMapper
 
     List<Live> selectLiveShowReadyStartLiveList(@Param("companyIds") List<Long> companyIds);
 
+    @Select("select * from live where is_audit = 1 and id_del = 0 and status in (1,2,4) and live_type in (2,3) order by create_time desc")
+    List<Live> liveListAll();
 }

+ 29 - 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")
@@ -416,4 +417,31 @@ public interface LiveOrderMapper {
 
 
     List<LiveOrderVoZm> selectLiveOrderListZm(LiveOrder liveOrder);
+
+    @Select(" SELECT * from live_order WHERE item_json is NULL ORDER BY create_time DESC  LIMIT 30")
+    List<LiveOrder> selectLiveOrderItemJson();
+
+    @Update(" UPDATE live_order SET item_json=#{itemJson} WHERE order_id=#{orderId}")
+    void updateLiveOrderItemJson(LiveOrder storeOrder);
+
+    @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);
 }

+ 19 - 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;
 
@@ -236,4 +238,21 @@ public interface ILiveOrderService {
     List<LiveOrderVoZm> selectLiveOrderListZm(LiveOrder liveOrder);
 
     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);
 }

+ 3 - 0
fs-service/src/main/java/com/fs/live/service/ILiveService.java

@@ -1,6 +1,7 @@
 package com.fs.live.service;
 
 
+import com.fs.common.core.page.PageRequest;
 import com.fs.live.vo.LiveVo;
 import com.fs.common.core.domain.R;
 import com.fs.live.domain.Live;
@@ -189,4 +190,6 @@ public interface ILiveService
     void updateGlobalVisible(long liveId, Integer status);
 
     String getGotoWxAppLiveLink(String linkStr, String appid);
+
+    R liveListAll(PageRequest pageRequest);
 }

+ 280 - 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 需要检查
@@ -2891,6 +2906,268 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
 
     }
 
+    @Override
+    public List<LiveOrder> selectLiveOrderItemJson() {
+        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)

+ 21 - 0
fs-service/src/main/java/com/fs/live/service/impl/LiveServiceImpl.java

@@ -6,6 +6,7 @@ import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 
+import com.fs.common.core.page.PageRequest;
 import com.fs.common.exception.base.BaseException;
 import com.fs.company.mapper.CompanyMapper;
 import com.fs.core.config.WxMaConfiguration;
@@ -31,6 +32,7 @@ import com.fs.live.utils.ProcessManager;
 import com.fs.live.vo.*;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.service.ISysConfigService;
+import com.github.pagehelper.PageInfo;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import me.chanjar.weixin.common.error.WxErrorException;
@@ -448,6 +450,25 @@ public class LiveServiceImpl implements ILiveService
         return "";
     }
 
+
+
+    @Override
+    public R liveListAll(PageRequest pageRequest) {
+        int start = (pageRequest.getCurrentPage() - 1) * pageRequest.getPageSize();
+        int end = pageRequest.getCurrentPage() * pageRequest.getPageSize() - 1;
+        List<Live> lives = baseMapper.liveListAll();
+
+        // 对结果进行分页处理
+        List<Live> pageLives = lives.stream()
+                .skip(start)
+                .limit(pageRequest.getPageSize())
+                .collect(Collectors.toList());
+
+        PageInfo<Live> result = new PageInfo<>(pageLives);
+        result.setTotal(lives.size());
+        return R.ok().put("data", result);
+    }
+
     /**
      * 修改直播
      *

+ 1 - 0
fs-service/src/main/java/com/fs/live/vo/LiveDataListVo.java

@@ -76,3 +76,4 @@ public class LiveDataListVo {
 
 
 
+

+ 1 - 0
fs-service/src/main/java/com/fs/live/vo/LiveDataStatisticsVo.java

@@ -57,3 +57,4 @@ public class LiveDataStatisticsVo {
 
 
 
+

+ 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;
 
     /** 更新时间*/

+ 5 - 2
fs-service/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java

@@ -404,8 +404,8 @@ public interface QwExternalContactMapper extends BaseMapper<QwExternalContact> {
     @Select("SELECT id,external_user_id,name,avatar,remark,description,fs_user_id FROM  qw_external_contact " +
             " WHERE user_id = #{map.userId}   " +
             "AND corp_id =#{map.corpId} " +
-            "AND external_user_id = #{map.externalUserId}" +
-            "AND `status` != 4 " +
+            "AND external_user_id = #{map.externalUserId} " +
+            "AND `status` != 4 AND `status` != 5 " +
             "ORDER BY id desc " +
             "limit 1 ")
     QwExternalContact getQwExternalContactDetails(@Param("map")QwExternalContactHParam param);
@@ -539,4 +539,7 @@ public interface QwExternalContactMapper extends BaseMapper<QwExternalContact> {
     QwExternalContact selectQwUserListVOByQwUserIdAndCorpIdAndExternalUserId(ExternalContactParam externalContactParam);
 
     void updateJoinGroup(List<Long> longs);
+
+
+    List<QwExternalContact> getGroupChatUserByChatIdAndUserName(@Param("userId")String userId,@Param("userName")String userName,@Param("corpId") String corpId,@Param("chatId") String chatId);
 }

+ 2 - 0
fs-service/src/main/java/com/fs/statis/dto/ModifyMoreDTO.java

@@ -26,4 +26,6 @@ public class ModifyMoreDTO implements Serializable {
      * 公司id
      */
     private String companyIds;
+
+    private String isAudit;
 }

+ 2 - 2
fs-service/src/main/resources/application-druid-bjzm-test.yml

@@ -39,7 +39,7 @@ spring:
             druid:
                 # 主库数据源
                 master:
-                  url: jdbc:mysql://gz-cdb-ofgnuz1n.sql.tencentcdb.com:26872/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                  url: jdbc:mysql://gz-cdb-ofgnuz1n.sql.tencentcdb.com:26872/fs_his?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                   username: root
                   password: Ylrz_1q2w3e4r5t6y
                 # 从库数据源
@@ -94,7 +94,7 @@ spring:
             druid:
                 # 主库数据源
                 master:
-                    url: jdbc:mysql://gz-cdb-ofgnuz1n.sql.tencentcdb.com:26872/fs_his_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    url: jdbc:mysql://gz-cdb-ofgnuz1n.sql.tencentcdb.com:26872/fs_his_sop?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                     username: root
                     password: Ylrz_1q2w3e4r5t6y
                 # 初始连接数

+ 2 - 2
fs-service/src/main/resources/application-druid-bjzm.yml

@@ -39,7 +39,7 @@ spring:
             druid:
                 # 主库数据源
                 master:
-                  url: jdbc:mysql://gz-cdb-ofgnuz1n.sql.tencentcdb.com:26872/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                  url: jdbc:mysql://gz-cdb-ofgnuz1n.sql.tencentcdb.com:26872/fs_his?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                   username: root
                   password: Ylrz_1q2w3e4r5t6y
                 # 从库数据源
@@ -94,7 +94,7 @@ spring:
             druid:
                 # 主库数据源
                 master:
-                    url: jdbc:mysql://gz-cdb-ofgnuz1n.sql.tencentcdb.com:26872/fs_his_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    url: jdbc:mysql://gz-cdb-ofgnuz1n.sql.tencentcdb.com:26872/fs_his_sop?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                     username: root
                     password: Ylrz_1q2w3e4r5t6y
                 # 初始连接数

+ 3 - 1
fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml

@@ -151,7 +151,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="maps.sopId != null  and maps.sopId != '' ">
                 and l.sop_id = #{maps.sopId}
             </if>
-
+            <if test="maps.periodId != null">
+                and l.period_id = #{maps.periodId}
+            </if>
             <if test="maps.periodIds != null and maps.periodIds.size() > 0">
                 and l.period_id in
                 <foreach item="periodId" index="index" collection="maps.periodIds" open="(" separator="," close=")">

+ 4 - 0
fs-service/src/main/resources/mapper/course/FsUserCoursePeriodDaysMapper.xml

@@ -239,4 +239,8 @@
         ORDER BY
             a.day_date
     </select>
+
+    <select id="selectFsUserCoursePeriodDaysForLastById" resultType="java.lang.Long">
+       select id from fs_user_course_period_days where del_flag ='0' and period_id = #{periodId} and lesson &gt;= #{lesson} order by lesson
+    </select>
 </mapper>

+ 6 - 0
fs-service/src/main/resources/mapper/course/FsUserCoursePeriodMapper.xml

@@ -401,4 +401,10 @@
         group by
         `period`.period_id
     </select>
+
+    <select id="selectFsUserCoursePeriodListLabel" resultType="com.fs.common.core.domain.entity.SysDictData">
+        select period_id as dictValue,period_name as dictLabel from fs_user_course_period
+                 where del_flag = '0'
+         <if test="companyId != null">and FIND_IN_SET (#{companyId},company_id) &gt; 0</if>
+    </select>
 </mapper>

+ 6 - 1
fs-service/src/main/resources/mapper/hisStore/FsMenuScrmMapper.xml

@@ -15,10 +15,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="updateTime"    column="update_time"    />
         <result property="sort"    column="sort"    />
         <result property="menuType"    column="menu_type"    />
+        <result property="appId"    column="app_id"    />
     </resultMap>
 
     <sql id="selectFsMenuVo">
-        select menu_id, menu_name,menu_type, icon, is_show,link_type,link_url, create_time, update_time,sort from fs_menu
+        select menu_id, menu_name,menu_type, icon, is_show,link_type,link_url, create_time, update_time,sort,app_id from fs_menu
     </sql>
 
     <select id="selectFsMenuList" parameterType="FsMenuScrm" resultMap="FsMenuResult">
@@ -31,6 +32,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="linkUrl != null "> and link_url = #{linkUrl}</if>
             <if test="sort != null "> and sort = #{sort}</if>
             <if test="menuType != null "> and menu_type = #{menuType}</if>
+            <if test="appId != null and appId != ''"> and app_id = #{appId}</if>
         </where>
         order by sort asc
     </select>
@@ -52,6 +54,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="linkUrl != null">link_url,</if>
             <if test="sort != null">sort,</if>
             <if test="menuType != null">menu_type,</if>
+            <if test="appId != null">app_id,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="menuName != null">#{menuName},</if>
@@ -63,6 +66,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="linkUrl != null">#{linkUrl},</if>
             <if test="sort != null">#{sort},</if>
             <if test="menuType != null">#{menuType},</if>
+            <if test="appId != null">#{appId},</if>
          </trim>
     </insert>
 
@@ -78,6 +82,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="linkUrl != null">link_url = #{linkUrl},</if>
             <if test="sort != null">sort = #{sort},</if>
             <if test="menuType != null">menu_type = #{menuType},</if>
+            <if test="appId != null and appId != ''">app_id = #{appId},</if>
         </trim>
         where menu_id = #{menuId}
     </update>

+ 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>

+ 18 - 15
fs-service/src/main/resources/mapper/hisStore/FsStoreProductScrmMapper.xml

@@ -404,21 +404,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         where product_id = #{productId}
     </update>
     <update id="batchModify">
-        <foreach collection="productId" separator=";" item="item">
-            update fs_store_product_scrm set
-                    <if test="goodsStatus != null">
-                        is_show = #{goodsStatus},
-                    </if>
-                    <if test="goodsIsShow != null">
-                        is_display = #{goodsIsShow},
-                    </if>
-                    <if test="companyIds != null and companyIds != ''">
-                        company_ids = #{companyIds}
-                    </if>
-                    <if test="isAudit != null and isAudit != ''">
-                        is_audit = #{isAudit}
-                    </if>
-            where product_id = #{item}
+        update fs_store_product_scrm
+        <set>
+            <if test="goodsStatus != null">
+                is_show = #{goodsStatus},
+            </if>
+            <if test="goodsIsShow != null">
+                is_display = #{goodsIsShow},
+            </if>
+            <if test="companyIds != null and companyIds != ''">
+                company_ids = #{companyIds},
+            </if>
+            <if test="isAudit != null and isAudit != ''">
+                is_audit = #{isAudit}
+            </if>
+        </set>
+        where product_id in
+        <foreach collection="productId" item="item" open="(" close=")" separator=",">
+            #{item}
         </foreach>
     </update>
 

+ 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>

+ 9 - 0
fs-service/src/main/resources/mapper/qw/QwExternalContactMapper.xml

@@ -790,4 +790,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <update id="updateJoinGroup">
         update qw_external_contact set join_group = 1 where id in <foreach collection="ids" open="(" separator="," close=")" item="item">#{item}</foreach>
     </update>
+
+    <select id="getGroupChatUserByChatIdAndUserName"  resultType="com.fs.qw.domain.QwExternalContact">
+            select t1.* from qw_external_contact t1
+            inner join qw_group_chat_user t2 on t1.external_user_id  = t2.user_id and t2.chat_id = #{chatId}
+            where t1.name = #{userName}
+            and t1.user_id = #{userId}
+            and t1.corp_id = #{corpId}
+            and t1.status = 0
+     </select>
 </mapper>

+ 16 - 0
fs-user-app/src/main/java/com/fs/app/controller/live/LiveController.java

@@ -110,6 +110,22 @@ public class LiveController extends AppBaseController {
 		return liveFacadeService.liveList(pageRequest);
 	}
 
+	@Login
+	@ApiOperation("直播间列表")
+	@GetMapping("/liveListAll")
+	@ApiResponse(code = 200, message = "", response = LiveInfoVo.class)
+	public R liveListAll(PageRequest pageRequest) {
+/*		PageHelper.startPage(Integer.parseInt(ServletUtils.getParameter("pageNum")) ,Integer.parseInt(ServletUtils.getParameter("pageSize")) );
+		try {
+			List<Live> list = liveService.liveList();
+			PageInfo<Live> result = new PageInfo<>(list);
+			return R.ok().put("data", result);
+		} catch (Exception e) {
+			return R.error("操作异常");
+		}*/
+		return liveService.liveListAll(pageRequest);
+	}
+
 	@Login
 	@ApiOperation("直播间列表")
 	@GetMapping("/liveList/{companyId}")

+ 5 - 2
fs-user-app/src/main/java/com/fs/app/controller/store/CompanyUserScrmController.java

@@ -260,11 +260,14 @@ public class CompanyUserScrmController extends AppBaseController {
 
     @ApiOperation("获取公司收款码")
     @GetMapping("/getCompanyWxaCodeByPayment")
-    public R getCompanyWxaCodeByPayment(@RequestParam("companyId")Long companyId,@RequestParam(value = "appId", required = false) String appId, @RequestParam(required = false) Long companyUserId, HttpServletRequest request){
+    public R getCompanyWxaCodeByPayment(@RequestParam("companyId")Long companyId,
+                                        @RequestParam(value = "appId", required = false) String appId,
+                                        @RequestParam(required = false) Long companyUserId,
+                                        HttpServletRequest request){
 
         String json = configService.selectConfigByKey("his.pay");
         PayConfigDTO payConfigDTO = JSONUtil.toBean(json, PayConfigDTO.class);
-        if (appId == null || appId.trim().isEmpty()) {
+        if (appId == null || appId.trim().isEmpty() ) {
             appId = payConfigDTO.getAppId();
         }
         //获取用户码

+ 1 - 2
fs-user-app/src/main/java/com/fs/app/controller/store/IndexScrmController.java

@@ -72,8 +72,7 @@ public class IndexScrmController extends AppBaseController {
 	@ApiOperation("读取菜单数据")
 	@GetMapping("/getMenu")
 	@Cacheable("menu")
-	public R getMenu(HttpServletRequest request){
-		FsMenuScrm map=new FsMenuScrm();
+	public R getMenu(FsMenuScrm map){
 		map.setIsShow(1);
 		map.setMenuType(1);
 		List<FsMenuScrm> list=menuService.selectFsMenuList(map);