소스 검색

Merge branch 'refs/heads/master' into 企微聊天

ct 2 달 전
부모
커밋
20792edfd2
31개의 변경된 파일397개의 추가작업 그리고 107개의 파일을 삭제
  1. 4 0
      fs-admin/src/main/java/com/fs/his/controller/FsUserController.java
  2. 6 0
      fs-admin/src/main/java/com/fs/hisStore/task/ExpressTask.java
  3. 12 0
      fs-company/src/main/java/com/fs/company/controller/live/LiveController.java
  4. 22 0
      fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java
  5. 9 9
      fs-service/src/main/java/com/fs/course/dto/FsOrderDeliveryNoteDTO.java
  6. 1 1
      fs-service/src/main/java/com/fs/gtPush/service/impl/uniPush2ServiceImpl.java
  7. 15 0
      fs-service/src/main/java/com/fs/his/domain/FsUser.java
  8. 1 1
      fs-service/src/main/java/com/fs/his/mapper/FsStoreOrderMapper.java
  9. 1 0
      fs-service/src/main/java/com/fs/hisStore/param/FsStoreConfirmPackageIdOrderParam.java
  10. 6 0
      fs-service/src/main/java/com/fs/hisStore/param/FsStorePackageOrderCreateParam.java
  11. 11 1
      fs-service/src/main/java/com/fs/hisStore/service/IFsStoreOrderScrmService.java
  12. 123 28
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
  13. 3 0
      fs-service/src/main/java/com/fs/live/mapper/LiveMapper.java
  14. 3 3
      fs-service/src/main/java/com/fs/live/mapper/LiveOrderMapper.java
  15. 2 0
      fs-service/src/main/java/com/fs/live/service/ILiveService.java
  16. 54 49
      fs-service/src/main/java/com/fs/live/service/impl/LiveServiceImpl.java
  17. 1 0
      fs-service/src/main/java/com/fs/live/vo/LiveDataListVo.java
  18. 1 0
      fs-service/src/main/java/com/fs/live/vo/LiveDataStatisticsVo.java
  19. 10 1
      fs-service/src/main/java/com/fs/qw/service/impl/AsyncSopTestService.java
  20. 9 0
      fs-service/src/main/java/com/fs/qw/vo/QwSopCourseFinishTempSetting.java
  21. 3 0
      fs-service/src/main/java/com/fs/qw/vo/QwSopTempSetting.java
  22. 2 0
      fs-service/src/main/java/com/fs/sop/service/impl/QwSopLogsServiceImpl.java
  23. 49 0
      fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java
  24. 5 3
      fs-service/src/main/java/com/fs/wx/order/service/ShippingService.java
  25. 4 4
      fs-service/src/main/java/com/fs/wx/order/service/WeChatAuthFactory.java
  26. 2 2
      fs-service/src/main/resources/application-druid-hst.yml
  27. 9 0
      fs-service/src/main/resources/mapper/his/FsUserMapper.xml
  28. 3 0
      fs-service/src/main/resources/mapper/live/LiveOrderMapper.xml
  29. 4 0
      fs-user-app/src/main/java/com/fs/app/controller/course/CourseFsUserController.java
  30. 17 3
      fs-user-app/src/main/java/com/fs/app/controller/store/CompanyOrderScrmController.java
  31. 5 2
      fs-user-app/src/main/java/com/fs/framework/aspectj/UserOperationLogAspect.java

+ 4 - 0
fs-admin/src/main/java/com/fs/his/controller/FsUserController.java

@@ -190,6 +190,10 @@ public class FsUserController extends BaseController
         if(StringUtils.isNotEmpty(fsUser.getPhone())){
             fsUser.setPhone(encryptPhone(fsUser.getPhone()));
         }
+        if(StringUtils.isNotEmpty(fsUser.getCompanyUserIdMulti())){
+            String[] split = fsUser.getCompanyUserIdMulti().split(",");
+            fsUser.setCompanyUserIds(split);
+        }
 //        List<FsUserVO> list = fsUserService.selectFsUserVOListByProject(fsUser);
 
         // xgb sql执行太慢,优化修改

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

@@ -20,4 +20,10 @@ public class ExpressTask {
         fsStoreOrderScrmService.syncExpressToWx();
     }
 
+
+    //定时任务刷新订单结算状态
+    public void refreshOrderSettlementStatus(){
+        fsStoreOrderScrmService.refreshOrderSettlementStatus();
+    }
+
 }

+ 12 - 0
fs-company/src/main/java/com/fs/company/controller/live/LiveController.java

@@ -51,6 +51,18 @@ public class LiveController extends BaseController
     @Autowired
     private ILiveCompanyCodeService liveCompanyCodeService;
 
+    /**
+     * 查询未结束直播间
+     */
+    @PreAuthorize("@ss.hasPermi('live:live:list')")
+    @GetMapping("/listToLiveNoEnd")
+    public TableDataInfo listToLiveNoEnd(Live live)
+    {
+        startPage();
+        List<Live> list = liveService.listToLiveNoEnd(live);
+        return getDataTable(list);
+    }
+
     /**
      * 查询直播列表
      */

+ 22 - 0
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java

@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.fs.app.taskService.SopLogsTaskService;
+import com.fs.common.config.FSSysConfig;
 import com.fs.common.utils.PubFun;
 import com.fs.common.utils.StringUtils;
 import com.fs.company.domain.Company;
@@ -1097,6 +1098,27 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                         setting.setMiniprogramAppid("未找到匹配的公司的自定义小程序:"+companyId);
                     }
 
+                    break;
+                //直播小程序单独
+                case "12":
+                    String sortLiveLink;
+                    sortLiveLink = "/pages_course/living?companyId=" + companyId + "&companyUserId=" + companyUserId + "&liveId=" + setting.getLiveId();
+
+
+                    String miniprogramLiveTitle = setting.getMiniprogramTitle();
+                    int maxLiveLength = 17;
+                    setting.setMiniprogramTitle(miniprogramLiveTitle.length() > maxLiveLength ? miniprogramLiveTitle.substring(0, maxLiveLength) + "..." : miniprogramLiveTitle);
+                    String json = configService.selectConfigByKey("his.config");
+                    FSSysConfig sysConfig= JSON.parseObject(json,FSSysConfig.class);
+                    setting.setMiniprogramAppid(sysConfig.getAppId());
+                    setting.setMiniprogramPage(sortLiveLink);
+                    setting.setContentType("4");
+                    try {
+                        setting.setMiniprogramPicUrl(StringUtil.strIsNullOrEmpty(setting.getMiniprogramPicUrl()) ? "https://cos.his.cdwjyyh.com/fs/20250331/ec2b4e73be8048afbd526124a655ad56.png" : setting.getMiniprogramPicUrl());
+                    } catch (Exception e) {
+                        log.error("赋值-小程序封面地址失败-" + e);
+                    }
+
                     break;
                 default:
                     break;

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

@@ -13,10 +13,10 @@ public class FsOrderDeliveryNoteDTO {
     /**
      * 系统订单号
      * **/
-    @Excel(name = "原始单号",width = 20,sort = 1)
+    @Excel(name = "系统订单号(必填)",width = 20,sort = 1)
     private String orderNumber;
 
-//    @Excel(name = "物流公司",width = 30,sort = 2)
+    @Excel(name = "物流公司编号(必填)(SF:顺丰、EMS:邮政、ZTO:中通、JD:京东、DBL:德邦、YTO:圆通)",width = 30,sort = 2)
     private String deliverySn;
 
     @Excel(name = "物流公司",width = 10,sort = 10)
@@ -24,25 +24,25 @@ public class FsOrderDeliveryNoteDTO {
 
     private String deliveryName;
 
-    @Excel(name = "快递单号",width = 20,sort = 23)
+    @Excel(name = "快递单号(必填)",width = 20,sort = 3)
     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;
 
 //    /**

+ 1 - 1
fs-service/src/main/java/com/fs/gtPush/service/impl/uniPush2ServiceImpl.java

@@ -46,7 +46,7 @@ public class uniPush2ServiceImpl implements uniPush2Service {
     public void pushSopAppLinkMsgByExternalIM(String cropId, String linkTile, String linkDescribe,String linkImageUrl, String link, Long companyUserId,Long fsUserId) throws JsonProcessingException {
 
         if (companyUserId!=null&&fsUserId!=null && fsUserId!=0){
-            openIMService.sendCourse(fsUserId,companyUserId,link,linkDescribe,linkImageUrl,cropId);
+            openIMService.sendCourse(fsUserId,companyUserId,link,linkTile,linkImageUrl,cropId);
         }
 
     }

+ 15 - 0
fs-service/src/main/java/com/fs/his/domain/FsUser.java

@@ -96,6 +96,15 @@ public class FsUser extends BaseEntity
     private Long companyId;
     private Long companyUserId;
     private String companyUserName;
+
+    /** 公司用户ID,逗号拼接*/
+    @TableField(exist = false)
+    private String companyUserIdMulti;
+
+    /** 公司用户ID,用于查询*/
+    @TableField(exist = false)
+    private String[] companyUserIds;
+
     @JsonFormat(pattern = "yyyy-MM-dd")
     @Excel(name = "推线日期", width = 30, dateFormat = "yyyy-MM-dd")
     private Date registerDate;
@@ -209,6 +218,12 @@ public class FsUser extends BaseEntity
     @TableField(exist = false)
     private String nickname;
 
+    /**
+     * 昵称-精确查询
+     * **/
+    @TableField(exist = false)
+    private String nicknameExact;
+
     public String getNickname() {
         return nickname;
     }

+ 1 - 1
fs-service/src/main/java/com/fs/his/mapper/FsStoreOrderMapper.java

@@ -375,7 +375,7 @@ public interface FsStoreOrderMapper
             "LEFT JOIN company c on c.company_id =so.company_id " +
             "LEFT JOIN company_user cu on cu.user_id=so.company_user_id " +
             "LEFT JOIN fs_doctor fd on so.follow_doctor_id =fd.doctor_id " +
-            "LEFT JOIN fs_patient pat ON pat.patient_id=p.patient_id  WHERE so.is_del=0  and order_id= #{orderId}")
+            "LEFT JOIN fs_patient pat ON pat.patient_id=p.patient_id  WHERE so.is_del=0  and so.order_id= #{orderId}")
     FsStoreOrderVO selectFsStoreOrderByOrderIdVO(@Param("orderId") Long orderId);
 
     @Update("update fs_store_order set status=-3 where order_id=#{orderId}")

+ 1 - 0
fs-service/src/main/java/com/fs/hisStore/param/FsStoreConfirmPackageIdOrderParam.java

@@ -8,4 +8,5 @@ import lombok.Setter;
 public class FsStoreConfirmPackageIdOrderParam {
     private Long packageId;
     private Long couponUserId;
+    private String createOrderKey;
 }

+ 6 - 0
fs-service/src/main/java/com/fs/hisStore/param/FsStorePackageOrderCreateParam.java

@@ -6,6 +6,7 @@ import lombok.Data;
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Size;
 import java.io.Serializable;
+import java.math.BigDecimal;
 
 @Data
 public class FsStorePackageOrderCreateParam implements Serializable
@@ -22,5 +23,10 @@ public class FsStorePackageOrderCreateParam implements Serializable
     private Long packageId;
     private Long companyUserId;
     private Long couponUserId;
+    @ApiModelProperty(value = "修改后的价格")
+    private BigDecimal payAmount;
+
+    @ApiModelProperty(value = "是否是套餐包制单",example  = "0")
+    private Integer isPackage;
 
 }

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

@@ -185,7 +185,7 @@ public interface IFsStoreOrderScrmService
 
     R addUserCart(long userId, String createOrderKey);
 
-    R updateSalseOrderMoney(String createOrderKey, BigDecimal money,BigDecimal payAmount,Integer payType);
+    R updateSalseOrderMoney(String createOrderKey, BigDecimal money,BigDecimal payAmount,Integer payType, Integer isPackage);
 
     Integer selectFsStoreOrderCountByType(Long companyId, long userId, int type);
 
@@ -335,4 +335,14 @@ public interface IFsStoreOrderScrmService
     R importDeliveryNoteExpress(List<FsOrderDeliveryNoteDTO> dtoList, String miniAppId);
 
     void refreshOrderSettlementStatus();
+
+    /**
+     * 套餐包制单
+     * @param companyUser 销售
+     * @param packageId 套餐包id
+     * @param orderType 订单类型
+     * @param orderMedium 媒体类型
+     * @return
+     */
+    R createPackageSalesOrder(CompanyUser companyUser, String packageId, Integer orderType, Integer orderMedium);
 }

+ 123 - 28
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -121,6 +121,7 @@ import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
 import com.github.binarywang.wxpay.config.WxPayConfig;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.WxPayService;
+import com.google.common.base.Joiner;
 import lombok.Synchronized;
 import lombok.extern.slf4j.Slf4j;
 import me.chanjar.weixin.common.error.WxErrorException;
@@ -375,6 +376,9 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
     @Autowired
     private FsWxExpressTaskMapper fsWxExpressTaskMapper;
 
+    @Autowired
+    private IFsStoreCartScrmService fsStoreCartScrmService;
+
     @PostConstruct
     public void initErpServiceMap() {
         erpServiceMap = new HashMap<>();
@@ -1553,14 +1557,24 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
     public R confirmPackageOrder(long uid, FsStoreConfirmPackageIdOrderParam param) {
         FsUserAddressScrm address = userAddressMapper.selectFsUserAddressByDefaultAddress(uid);
         FsStoreProductPackageScrm storeProductPackage = productPackageService.selectFsStoreProductPackageById(param.getPackageId());
-        String uuid = IdUtil.randomUUID();
-        BigDecimal totalMoney = storeProductPackage.getPayMoney();
+        // 由于套餐制单前面有生成oderkey,并且要取修改的价格,所以这里判断,如果有传就用传的orderkey,如果没有就生成(代表走的是直接购买)
+        String uuid;
+        BigDecimal totalMoney;
+        if(param.getCreateOrderKey().isEmpty() ){
+            //直接购买
+            uuid = IdUtil.randomUUID();
+            totalMoney = storeProductPackage.getPayMoney();
+        } else {
+            // 套餐制单
+            uuid = param.getCreateOrderKey();
+            totalMoney = redisCache.getCacheObject("createOrderMoney:" + param.getCreateOrderKey());
+        }
+
         if (param.getCouponUserId() != null) {
             FsStoreCouponUserScrm couponUser = couponUserService.selectFsStoreCouponUserById(param.getCouponUserId());
             if (couponUser != null && couponUser.getStatus() == 0) {
                 if (couponUser.getUseMinPrice().compareTo(storeProductPackage.getPayMoney()) == -1) {
-                    //
-                    totalMoney = totalMoney.subtract(couponUser.getCouponPrice());
+                    totalMoney = totalMoney != null ? totalMoney.subtract(couponUser.getCouponPrice()) : BigDecimal.ZERO.subtract(couponUser.getCouponPrice());
                 }
             }
         }
@@ -1596,29 +1610,37 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             List<StorePackageProductDTO> goodsList = JSONUtil.toList(jsonArray, StorePackageProductDTO.class);
             //检测库存
             Integer totalNum = 0;
-            List<FsStoreCartQueryVO> carts = new ArrayList<>();
-            for (StorePackageProductDTO goods : goodsList) {
-                FsStoreProductAttrValueScrm attrValue = attrValueService.selectFsStoreProductAttrValueById(goods.getId());
-                if (attrValue != null && attrValue.getProductId() != null) {
-                    FsStoreProductScrm product = storeProductService.selectFsStoreProductById(attrValue.getProductId());
-                    if (product != null) {
-                        totalNum += goods.getCount();
-                        FsStoreCartQueryVO vo = new FsStoreCartQueryVO();
-                        vo.setProductId(attrValue.getProductId());
-                        vo.setProductAttrValueId(goods.getId());
-                        vo.setCartNum(goods.getCount());
-                        vo.setProductName(product.getProductName());
-                        vo.setProductAttrName(attrValue.getSku());
-                        vo.setProductImage(product.getImage());
-                        vo.setBarCode(attrValue.getBarCode());
-                        vo.setGroupBarCode(attrValue.getGroupBarCode());
-                        vo.setPrice(product.getPrice());
-                        vo.setProductType(product.getProductType());
-                        carts.add(vo);
+            List<FsStoreCartQueryVO> carts = redisCache.getCacheObject("orderCarts:" + param.getOrderKey());
+            String joinCartIds = null;
+            if(carts == null || carts.isEmpty()){
+                carts = new ArrayList<>();
+                for (StorePackageProductDTO goods : goodsList) {
+                    FsStoreProductAttrValueScrm attrValue = attrValueService.selectFsStoreProductAttrValueById(goods.getId());
+                    if (attrValue != null && attrValue.getProductId() != null) {
+                        FsStoreProductScrm product = storeProductService.selectFsStoreProductById(attrValue.getProductId());
+                        if (product != null) {
+                            totalNum += goods.getCount();
+                            FsStoreCartQueryVO vo = new FsStoreCartQueryVO();
+                            vo.setProductId(attrValue.getProductId());
+                            vo.setProductAttrValueId(goods.getId());
+                            vo.setCartNum(goods.getCount());
+                            vo.setProductName(product.getProductName());
+                            vo.setProductAttrName(attrValue.getSku());
+                            vo.setProductImage(product.getImage());
+                            vo.setBarCode(attrValue.getBarCode());
+                            vo.setGroupBarCode(attrValue.getGroupBarCode());
+                            vo.setPrice(product.getPrice());
+                            vo.setProductType(product.getProductType());
+                            carts.add(vo);
 
+                        }
                     }
+                    cartService.checkProductStock(attrValue.getProductId(), attrValue.getId());
                 }
-                cartService.checkProductStock(attrValue.getProductId(), attrValue.getId());
+            } else {
+                // 如果cartIds不为空,则表示是套餐制单购买,非套餐制单是没有购物车信息的。
+                List<Long> cartIds = carts.stream().map(FsStoreCartQueryVO::getId).collect(Collectors.toList());
+                joinCartIds = Joiner.on(",").join(cartIds);
             }
             //生成分布式唯一值
             String orderSn = IdUtil.getSnowflake(0, 0).nextIdStr();
@@ -1627,6 +1649,7 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             //组合数据
             CompanyUser user = companyUserService.selectCompanyUserById(param.getCompanyUserId());
             FsStoreOrderScrm storeOrder = new FsStoreOrderScrm();
+            storeOrder.setCartId(joinCartIds);
             //修改默认仓库
 
             storeOrder.setStoreHouseCode("CK01");
@@ -1635,7 +1658,13 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                 storeOrder.setCompanyId(user.getCompanyId());
                 storeOrder.setDeptId(user.getDeptId());
             }
-            BigDecimal totalMoney = storeProductPackage.getPayMoney();
+            BigDecimal totalMoney;
+            if(param.getIsPackage() != null && param.getIsPackage() == 1){
+                totalMoney = redisCache.getCacheObject("createOrderMoney:" + param.getOrderKey());
+            } else {
+                totalMoney = storeProductPackage.getPayMoney();
+            }
+
             //优惠券处理
             if (param.getCouponUserId() != null) {
                 FsStoreCouponUserScrm couponUser = couponUserService.selectFsStoreCouponUserById(param.getCouponUserId());
@@ -1700,6 +1729,7 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             //减库存加销量
             this.deStockIncSale(carts);
             //保存购物车商品信息
+            List<FsStoreOrderItemScrm> listOrderItem = new ArrayList<>();
             for (FsStoreCartQueryVO vo : carts) {
                 FsStoreCartDTO fsStoreCartDTO = new FsStoreCartDTO();
                 fsStoreCartDTO.setProductId(vo.getProductId());
@@ -1727,7 +1757,13 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                     item.setIsPrescribe(1);
                 }
                 fsStoreOrderItemMapper.insertFsStoreOrderItem(item);
+                listOrderItem.add(item);
+            }
+            if (!listOrderItem.isEmpty()) {
+                storeOrder.setItemJson(JSONUtil.toJsonStr(listOrderItem));
             }
+            fsStoreOrderMapper.updateFsStoreOrder(storeOrder);
+
             //删除缓存
             redisCache.deleteObject("orderKey:" + param.getOrderKey());
             //添加记录
@@ -2592,7 +2628,7 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
     }
 
     @Override
-    public R updateSalseOrderMoney(String createOrderKey, BigDecimal money, BigDecimal payAmount,Integer payType) {
+    public R updateSalseOrderMoney(String createOrderKey, BigDecimal money, BigDecimal payAmount,Integer payType, Integer isPackage) {
         //货到付款自定义金额
         if (payAmount == null) {
             String configJson = configService.selectConfigByKey("store.config");
@@ -2616,8 +2652,13 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         }
         List<FsStoreCartQueryVO> carts = redisCache.getCacheObject("orderCarts:" + createOrderKey);
         BigDecimal totalMoney = BigDecimal.ZERO;
-        for (FsStoreCartQueryVO vo : carts) {
-            totalMoney = totalMoney.add(vo.getPrice().multiply(new BigDecimal(vo.getCartNum().toString())));
+        if(isPackage == 0){
+            for (FsStoreCartQueryVO vo : carts) {
+                totalMoney = totalMoney.add(vo.getPrice().multiply(new BigDecimal(vo.getCartNum().toString())));
+            }
+        } else {
+            //套餐制单
+            totalMoney = carts.get(0).getPrice();
         }
         if (money.compareTo(totalMoney) == 1) {
             throw new CustomException("价格不能大于商品总价", 501);
@@ -5062,6 +5103,59 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         }
     }
 
+    @Override
+    public R createPackageSalesOrder(CompanyUser companyUser, String packageId, Integer orderType, Integer orderMedium) {
+        FsStoreProductPackageScrm storeProductPackage = productPackageService.selectFsStoreProductPackageById(Long.parseLong(packageId));
+        if(storeProductPackage == null){
+            return R.error("商品套餐不存在");
+        }
+
+        /**
+         * 由于套餐包制单前端页面没有走购物车,因为为了保证后续可以使用之前商品制单的改价接口、创建订单接口、支付等接口,
+         * 也为了保持结构一致,因此这里手动添加购物车
+         */
+        // 获取套餐包的商品信息,然后添加购物车
+        JSONArray jsonArray = JSONUtil.parseArray(storeProductPackage.getProducts());
+        List<StorePackageProductDTO> goodsList = JSONUtil.toList(jsonArray, StorePackageProductDTO.class);
+        String cartIds = "";
+        for (StorePackageProductDTO goods : goodsList) {
+            FsStoreCartParam fsStoreCartParam = new FsStoreCartParam();
+            FsStoreProductAttrValueScrm attrValue = attrValueService.selectFsStoreProductAttrValueById(goods.getId());
+            if (attrValue != null && attrValue.getProductId() != null) {
+                    fsStoreCartParam.setProductId(attrValue.getProductId());
+                    fsStoreCartParam.setCartNum(goods.getCount());
+                    fsStoreCartParam.setIsBuy(1);
+                    fsStoreCartParam.setAttrValueId(goods.getId());
+                R r = fsStoreCartScrmService.addCart(companyUser.getUserId(), fsStoreCartParam);
+                Object id = r.get("id");
+                if(id != null){
+                    cartIds += id + ",";
+                }
+            }
+
+        }
+
+        List<FsStoreCartQueryVO> carts = cartMapper.selectFsStoreCartListByIds(cartIds);
+        String uuid = IdUtil.randomUUID();
+        redisCache.setCacheObject("createOrderKey:" + uuid, companyUser.getCompanyId() + "-" + companyUser.getUserId(), 24, TimeUnit.HOURS);
+
+        // 这里的carts是购物车信息,价格取的套餐包价格
+        for (FsStoreCartQueryVO vo : carts) {
+            vo.setPrice(storeProductPackage.getPayMoney());
+        }
+        redisCache.setCacheObject("orderCarts:" + uuid, carts, 24, TimeUnit.HOURS);
+        if (orderType != null || orderMedium != null) {
+            FsStoreOrderScrm fsStoreOrder = new FsStoreOrderScrm();
+            fsStoreOrder.setOrderMedium(orderMedium);
+            fsStoreOrder.setOrderType(orderType);
+            redisCache.setCacheObject("orderInfo:" + uuid, fsStoreOrder, 24, TimeUnit.HOURS);
+        }
+
+        redisCache.setCacheObject("createOrderMoney:" + uuid, storeProductPackage.getPayMoney(), 24, TimeUnit.HOURS);
+        // 根据前端要求,为了前端方便取值,所以返回的参数key与商品制单的接口保持一致
+        return R.ok().put("orderKey", uuid);
+    }
+
     private static final DateTimeFormatter CST_FORMATTER = DateTimeFormatter
             .ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US)
             .withZone(ZoneId.of("Asia/Shanghai"));
@@ -5098,6 +5192,7 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         map.put("ZTO", "中通");
         map.put("JD", "京东");
         map.put("DBL", "德邦");
+        map.put("YTO", "圆通");
         return map;
     }
 

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

@@ -170,4 +170,7 @@ public interface LiveMapper
             "WHERE l.live_id = #{liveId} " +
             "GROUP BY l.live_id, l.start_time")
     Integer selectLiveFlagByLiveId(@Param("liveId") Long liveId);
+
+    @Select("SELECT * FROM live WHERE is_audit = 1 and is_del = 0 and status in (1,2,4) and live_type in (2,3) order by create_time desc")
+    List<Live> listToLiveNoEnd(Live live);
 }

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

@@ -369,8 +369,8 @@ public interface LiveOrderMapper {
     int batchUpdateErpByOrderIds(@Param("maps")ArrayList<Map<String, String>> maps);
 
     @Select({"<script> " +
-            "select o.order_id,o.order_code,o.item_json,o.pay_price,o.status,o.delivery_id,o.finish_time  from live_order o  " +
-            "where o.is_del=0 and o.is_sys_del=0 " +
+            "select o.order_id,o.order_code,o.item_json,o.pay_price,o.status,o.delivery_sn as delivery_id,o.finish_time  from live_order o  " +
+            "where o.is_del=0 " +
             "<if test = 'maps.status != null and maps.status != \"\"     '> " +
             "and o.status =#{maps.status} " +
             "</if>" +
@@ -389,7 +389,7 @@ public interface LiveOrderMapper {
 
     @Select({"<script> " +
             "select o.*  from live_order o  " +
-            "where o.is_del=0 and o.is_sys_del=0 " +
+            "where o.is_del=0 " +
             "<if test = 'maps.status != null and maps.status != \"\"     '> " +
             "and o.status =#{maps.status} " +
             "</if>" +

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

@@ -192,4 +192,6 @@ public interface ILiveService
     String getGotoWxAppLiveLink(String linkStr, String appid);
 
     R liveListAll(PageRequest pageRequest);
+
+    List<Live> listToLiveNoEnd(Live live);
 }

+ 54 - 49
fs-service/src/main/java/com/fs/live/service/impl/LiveServiceImpl.java

@@ -469,6 +469,11 @@ public class LiveServiceImpl implements ILiveService
         return R.ok().put("data", result);
     }
 
+    @Override
+    public List<Live> listToLiveNoEnd(Live live) {
+        return baseMapper.listToLiveNoEnd(live);
+    }
+
     /**
      * 修改直播
      *
@@ -807,43 +812,43 @@ public class LiveServiceImpl implements ILiveService
         if (exist == null) {
             return R.error("直播间不存在");
         }
-        
+
         // 1. 复制直播间基础信息
         Long newLiveId = copyLiveBasicInfo(exist, live, now);
-        
+
         // 2. 创建直播数据
         createLiveData(newLiveId);
-        
+
         // 3. 复制直播视频
         copyLiveVideos(existLiveId, newLiveId, now);
-        
+
         // 4. 获取所有自动化任务并按类型分组
         List<LiveAutoTask> allTasks = liveAutoTaskService.selectLiveAutoTaskByLiveId(existLiveId);
         Map<Long, List<LiveAutoTask>> tasksByType = allTasks.stream()
                 .collect(Collectors.groupingBy(LiveAutoTask::getTaskType));
-        
+
         // 5. 复制弹幕任务(taskType=3)
         copyBarrageTasks(tasksByType.get(3L), newLiveId, now);
-        
+
         // 6. 复制红包配置及任务(taskType=2)
         Map<Long, Long> redIdMapping = copyRedConfs(existLiveId, newLiveId, tasksByType.get(2L), now);
-        
+
         // 7. 复制抽奖配置及任务(taskType=4)
         Map<Long, Long> lotteryIdMapping = copyLotteryConfs(existLiveId, newLiveId, tasksByType.get(4L), now);
-        
+
         // 8. 复制商品、商品任务、上下架任务及优惠券关系
-        Map<Long, Long> goodsIdMapping = copyGoodsAndTasks(existLiveId, newLiveId, live, 
+        Map<Long, Long> goodsIdMapping = copyGoodsAndTasks(existLiveId, newLiveId, live,
                 tasksByType.get(1L), tasksByType.get(6L), now);
-        
+
         // 9. 复制优惠券关系
         copyCouponRelations(existLiveId, newLiveId, goodsIdMapping);
-        
+
         // 10. 复制优惠券自动化任务(taskType=5)
         copyCouponTasks(tasksByType.get(5L), newLiveId, goodsIdMapping, now);
 
         return R.ok("复制成功");
     }
-    
+
     /**
      * 复制直播间基础信息
      */
@@ -865,7 +870,7 @@ public class LiveServiceImpl implements ILiveService
         }
         return liveEntity.getLiveId();
     }
-    
+
     /**
      * 创建直播数据
      */
@@ -882,7 +887,7 @@ public class LiveServiceImpl implements ILiveService
         liveData.setFollowNum(0L);
         liveDataService.insertLiveData(liveData);
     }
-    
+
     /**
      * 复制直播视频
      */
@@ -897,7 +902,7 @@ public class LiveServiceImpl implements ILiveService
             liveVideoService.insertLiveVideo(videoEntity);
         }
     }
-    
+
     /**
      * 复制弹幕任务(taskType=3)
      */
@@ -918,20 +923,20 @@ public class LiveServiceImpl implements ILiveService
             liveAutoTaskService.batchInsertLiveAutoTask(addList);
         }
     }
-    
+
     /**
      * 复制红包配置及任务
      */
-    private Map<Long, Long> copyRedConfs(Long existLiveId, Long newLiveId, 
+    private Map<Long, Long> copyRedConfs(Long existLiveId, Long newLiveId,
                                          List<LiveAutoTask> redTasks, Date now) {
         Map<Long, Long> redIdMapping = new HashMap<>();
         if (redTasks == null) {
             redTasks = Collections.emptyList();
         }
         Map<Long, LiveAutoTask> redTaskMap = redTasks.stream()
-                .collect(Collectors.toMap(task -> parseIdFromContent(task.getContent(), "redId"), 
+                .collect(Collectors.toMap(task -> parseIdFromContent(task.getContent(), "redId"),
                         Function.identity(), (existing, replacement) -> existing));
-        
+
         List<LiveRedConf> liveRedConfs = liveRedConfService.selectByLiveId(existLiveId);
         for (LiveRedConf liveRedConf : liveRedConfs) {
             LiveRedConf newRedConf = new LiveRedConf();
@@ -942,32 +947,32 @@ public class LiveServiceImpl implements ILiveService
             newRedConf.setCreateTime(now);
             newRedConf.setTotalSend(0L);
             liveRedConfService.insertLiveRedConf(newRedConf);
-            
+
             redIdMapping.put(liveRedConf.getRedId(), newRedConf.getRedId());
-            
+
             LiveAutoTask task = redTaskMap.get(liveRedConf.getRedId());
             if (task != null) {
-                LiveAutoTask newTask = createAutoTaskEntity(task, newLiveId, now, 
+                LiveAutoTask newTask = createAutoTaskEntity(task, newLiveId, now,
                         JSON.toJSONString(newRedConf));
                 liveAutoTaskService.directInsertLiveAutoTask(newTask);
             }
         }
         return redIdMapping;
     }
-    
+
     /**
      * 复制抽奖配置及任务
      */
-    private Map<Long, Long> copyLotteryConfs(Long existLiveId, Long newLiveId, 
+    private Map<Long, Long> copyLotteryConfs(Long existLiveId, Long newLiveId,
                                              List<LiveAutoTask> lotteryTasks, Date now) {
         Map<Long, Long> lotteryIdMapping = new HashMap<>();
         if (lotteryTasks == null) {
             lotteryTasks = Collections.emptyList();
         }
         Map<Long, LiveAutoTask> lotteryTaskMap = lotteryTasks.stream()
-                .collect(Collectors.toMap(task -> parseIdFromContent(task.getContent(), "lotteryId"), 
+                .collect(Collectors.toMap(task -> parseIdFromContent(task.getContent(), "lotteryId"),
                         Function.identity(), (existing, replacement) -> existing));
-        
+
         List<LiveLotteryConf> liveLotteryConfs = liveLotteryConfService.selectByLiveId(existLiveId);
         if (!liveLotteryConfs.isEmpty()) {
             List<Long> lotteryIds = liveLotteryConfs.stream()
@@ -975,7 +980,7 @@ public class LiveServiceImpl implements ILiveService
             List<LiveLotteryProductConf> products = liveLotteryProductConfMapper.selectEntityByIds(lotteryIds);
             Map<Long, List<LiveLotteryProductConf>> productsByLotteryId = products.stream()
                     .collect(Collectors.groupingBy(LiveLotteryProductConf::getLotteryId));
-            
+
             for (LiveLotteryConf liveLotteryConf : liveLotteryConfs) {
                 LiveLotteryConf newLotteryConf = new LiveLotteryConf();
                 BeanUtils.copyBeanProp(newLotteryConf, liveLotteryConf);
@@ -985,9 +990,9 @@ public class LiveServiceImpl implements ILiveService
                 newLotteryConf.setCreateTime(now);
                 newLotteryConf.setUpdateTime(now);
                 liveLotteryConfService.insertLiveLotteryConf(newLotteryConf);
-                
+
                 lotteryIdMapping.put(liveLotteryConf.getLotteryId(), newLotteryConf.getLotteryId());
-                
+
                 // 复制奖品
                 List<LiveLotteryProductConf> lotteryProducts = productsByLotteryId.get(liveLotteryConf.getLotteryId());
                 if (lotteryProducts != null) {
@@ -999,10 +1004,10 @@ public class LiveServiceImpl implements ILiveService
                         liveLotteryProductConfMapper.insertLiveLotteryProductConf(newProduct);
                     }
                 }
-                
+
                 LiveAutoTask task = lotteryTaskMap.get(liveLotteryConf.getLotteryId());
                 if (task != null) {
-                    LiveAutoTask newTask = createAutoTaskEntity(task, newLiveId, now, 
+                    LiveAutoTask newTask = createAutoTaskEntity(task, newLiveId, now,
                             JSON.toJSONString(newLotteryConf));
                     liveAutoTaskService.directInsertLiveAutoTask(newTask);
                 }
@@ -1010,7 +1015,7 @@ public class LiveServiceImpl implements ILiveService
         }
         return lotteryIdMapping;
     }
-    
+
     /**
      * 复制商品、商品任务、上下架任务
      */
@@ -1023,25 +1028,25 @@ public class LiveServiceImpl implements ILiveService
         if (shelfTasks == null) {
             shelfTasks = Collections.emptyList();
         }
-        
+
         Map<Long, LiveAutoTask> goodsTaskMap = goodsTasks.stream()
-                .collect(Collectors.toMap(task -> parseIdFromContent(task.getContent(), "goodsId"), 
+                .collect(Collectors.toMap(task -> parseIdFromContent(task.getContent(), "goodsId"),
                         Function.identity(), (existing, replacement) -> existing));
         Map<Long, LiveAutoTask> shelfTaskMap = shelfTasks.stream()
-                .collect(Collectors.toMap(task -> parseIdFromContent(task.getContent(), "goodsId"), 
+                .collect(Collectors.toMap(task -> parseIdFromContent(task.getContent(), "goodsId"),
                         Function.identity(), (existing, replacement) -> existing));
-        
+
         LiveGoods queryParam = new LiveGoods();
         queryParam.setLiveId(existLiveId);
         List<LiveGoodsVo> goodsList = liveGoodsService.selectProductListByLiveId(queryParam);
-        
+
         if (!goodsList.isEmpty()) {
             List<Long> goodsProductIds = goodsList.stream()
                     .map(LiveGoodsVo::getProductId).collect(Collectors.toList());
             Map<Long, FsStoreProductScrm> goodsMap = fsStoreProductScrmMapper
                     .selectFsStoreProductByProductIds(goodsProductIds).stream()
                     .collect(Collectors.toMap(FsStoreProductScrm::getProductId, Function.identity()));
-            
+
             for (LiveGoodsVo liveGoods : goodsList) {
                 LiveGoods newGoods = new LiveGoods();
                 BeanUtils.copyBeanProp(newGoods, liveGoods);
@@ -1051,12 +1056,12 @@ public class LiveServiceImpl implements ILiveService
                 newGoods.setIsShow(false);
                 newGoods.setCompanyId(live.getCompanyId());
                 newGoods.setCompanyUserId(live.getCompanyUserId());
-                newGoods.setStock(goodsMap.containsKey(liveGoods.getProductId()) 
+                newGoods.setStock(goodsMap.containsKey(liveGoods.getProductId())
                         ? goodsMap.get(liveGoods.getProductId()).getStock() : 0);
                 liveGoodsService.insertLiveGoods(newGoods);
-                
+
                 goodsIdMapping.put(liveGoods.getGoodsId(), newGoods.getGoodsId());
-                
+
                 // 复制商品推送任务(taskType=1)
                 LiveAutoTask goodsTask = goodsTaskMap.get(liveGoods.getGoodsId());
                 if (goodsTask != null) {
@@ -1064,17 +1069,17 @@ public class LiveServiceImpl implements ILiveService
                     LiveGoodsVo newGoodsVo = new LiveGoodsVo();
                     BeanUtils.copyBeanProp(newGoodsVo, liveGoods);
                     newGoodsVo.setGoodsId(newGoods.getGoodsId());
-                    LiveAutoTask newTask = createAutoTaskEntity(goodsTask, newLiveId, now, 
+                    LiveAutoTask newTask = createAutoTaskEntity(goodsTask, newLiveId, now,
                             JSON.toJSONString(newGoodsVo));
                     liveAutoTaskService.directInsertLiveAutoTask(newTask);
                 }
-                
+
                 // 复制上下架任务(taskType=6)
                 LiveAutoTask shelfTask = shelfTaskMap.get(liveGoods.getGoodsId());
                 if (shelfTask != null) {
                     JSONObject contentJson = JSON.parseObject(shelfTask.getContent());
                     contentJson.put("goodsId", newGoods.getGoodsId());
-                    LiveAutoTask newTask = createAutoTaskEntity(shelfTask, newLiveId, now, 
+                    LiveAutoTask newTask = createAutoTaskEntity(shelfTask, newLiveId, now,
                             contentJson.toJSONString());
                     liveAutoTaskService.directInsertLiveAutoTask(newTask);
                 }
@@ -1082,7 +1087,7 @@ public class LiveServiceImpl implements ILiveService
         }
         return goodsIdMapping;
     }
-    
+
     /**
      * 复制优惠券关系
      */
@@ -1100,11 +1105,11 @@ public class LiveServiceImpl implements ILiveService
             liveCouponIssueMapper.insertLiveCouponIssueRelation(newRelation);
         }
     }
-    
+
     /**
      * 复制优惠券自动化任务(taskType=5)
      */
-    private void copyCouponTasks(List<LiveAutoTask> couponTasks, Long newLiveId, 
+    private void copyCouponTasks(List<LiveAutoTask> couponTasks, Long newLiveId,
                                  Map<Long, Long> goodsIdMapping, Date now) {
         if (couponTasks == null || couponTasks.isEmpty()) {
             return;
@@ -1117,7 +1122,7 @@ public class LiveServiceImpl implements ILiveService
                     Long newGoodsId = goodsIdMapping.get(liveCoupon.getGoodsId());
                     if (newGoodsId != null) {
                         liveCoupon.setGoodsId(newGoodsId);
-                        LiveAutoTask newTask = createAutoTaskEntity(task, newLiveId, now, 
+                        LiveAutoTask newTask = createAutoTaskEntity(task, newLiveId, now,
                                 JSON.toJSONString(liveCoupon));
                         liveAutoTaskService.directInsertLiveAutoTask(newTask);
                     }
@@ -1127,7 +1132,7 @@ public class LiveServiceImpl implements ILiveService
             }
         }
     }
-    
+
     /**
      * 创建自动化任务实体
      */

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

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

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

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

+ 10 - 1
fs-service/src/main/java/com/fs/qw/service/impl/AsyncSopTestService.java

@@ -27,6 +27,7 @@ import com.fs.voice.utils.StringUtil;
 import com.fs.wxUser.param.CompanyWxUserSopParam;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
 import org.apache.rocketmq.spring.core.RocketMQTemplate;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
@@ -510,7 +511,15 @@ public class AsyncSopTestService {
 
         setting.forEach(item->{
             try {
-                push2Service.pushSopAppLinkMsgByExternalIM(cropId,item.getLinkTitle(),item.getLinkDescribe(),item.getLinkImageUrl(),item.getAppLinkUrl(),companyUserId,fsUserId);
+                String linkImageUrl = item.getLinkImageUrl();
+                String linkTitle = item.getLinkTitle();
+                if (StringUtils.isBlank(linkImageUrl)) {
+                    linkImageUrl = item.getCourseUrl();
+                }
+                if (StringUtils.isBlank(linkTitle)) {
+                    linkTitle = item.getTitle();
+                }
+                push2Service.pushSopAppLinkMsgByExternalIM(cropId, linkTitle,item.getLinkDescribe(), linkImageUrl,item.getAppLinkUrl(),companyUserId,fsUserId);
             } catch (JsonProcessingException e) {
                 e.printStackTrace();
             }

+ 9 - 0
fs-service/src/main/java/com/fs/qw/vo/QwSopCourseFinishTempSetting.java

@@ -80,6 +80,9 @@ public class QwSopCourseFinishTempSetting implements Serializable,Cloneable{
         /** 小程序page路径 */
         private String miniprogramPage;
 
+        /** 直播间ID */
+        private String liveId;
+
         //链接标题
         private String linkTitle;
         //链接描述
@@ -116,6 +119,12 @@ public class QwSopCourseFinishTempSetting implements Serializable,Cloneable{
 
         //课程id
         private Long courseId;
+
+        //封面图片地址 app用的参数
+        private String courseUrl;
+
+        //app显示标题 app用的参数
+        private String title;
         @Override
         public Setting clone() {
             try {

+ 3 - 0
fs-service/src/main/java/com/fs/qw/vo/QwSopTempSetting.java

@@ -112,6 +112,9 @@ public class QwSopTempSetting implements Serializable{
             /** 小程序page路径 */
             private String miniprogramPage;
 
+            /** 直播间Id*/
+            private Long liveId;
+
             //文件地址
             private String fileUrl;
             //视频地址

+ 2 - 0
fs-service/src/main/java/com/fs/sop/service/impl/QwSopLogsServiceImpl.java

@@ -2088,6 +2088,8 @@ public class QwSopLogsServiceImpl extends ServiceImpl<QwSopLogsMapper, QwSopLogs
     // 处理不同类型的内容
     private void processContent(QwSopTempSetting.Content.Setting set, String corpId,
                                 QwMsgTemplateSop templateSop, List<QwMsgTemplateSop.Attachment> attachments,Long courseId) {
+        // 发送直播卡片兼容处理
+        if(set.getContentType() != null && "12".equals(set.getContentType())) set.setContentType("4");
         switch (set.getContentType()) {
             case "1":
                 templateSop.setTextContent(set.getValue());

+ 49 - 0
fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java

@@ -5,6 +5,7 @@ import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.fs.common.config.FSSysConfig;
 import com.fs.common.core.domain.R;
 import com.fs.common.exception.base.BaseException;
 import com.fs.common.utils.PubFun;
@@ -663,6 +664,15 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                             case "7":
                                 createVoiceUrl(st, companyUserId, qwSop);
                                 break;
+                            //直播小程序单独
+                            case "12":
+                                String sortLiveLink = "/pages_course/living?companyId=" + qwUser.getCompanyUserId() + "&companyUserId=" + companyUserId + "&liveId=" + st.getLiveId();
+                                st.setContentType("4");
+                                String js = configService.selectConfigByKey("his.config");
+                                FSSysConfig sysConfig= JSON.parseObject(js,FSSysConfig.class);
+                                st.setMiniprogramAppid(sysConfig.getAppId());
+                                st.setMiniprogramPage(sortLiveLink);
+                                break;
                         }
                     }
                     setting.setSetting(list);
@@ -797,6 +807,15 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                                     createVoiceUrl(st, String.valueOf(qwUser.getCompanyUserId()), qwSop);
                                 }
                                 break;
+                            //直播小程序单独
+                            case "12":
+                                String sortLiveLink = "/pages_course/living?companyId=" + qwUser.getCompanyUserId() + "&companyUserId=" + qwUser.getCompanyUserId() + "&liveId=" + st.getLiveId();
+                                st.setContentType("4");
+                                String js = configService.selectConfigByKey("his.config");
+                                FSSysConfig sysConfig= JSON.parseObject(js,FSSysConfig.class);
+                                st.setMiniprogramAppid(sysConfig.getAppId());
+                                st.setMiniprogramPage(sortLiveLink);
+                                break;
                         }
                     }
                     setting.setSetting(list);
@@ -991,6 +1010,15 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                                 st.setMiniprogramAppid("未找到匹配的公司的自定义小程序:"+companyId);
                             }
 
+                            break;
+                        //直播小程序单独
+                        case "12":
+                            String sortLiveLink = "/pages_course/living?companyId=" + qwUser.getCompanyUserId() + "&companyUserId=" + qwUser.getCompanyUserId() + "&liveId=" + st.getLiveId();
+                            st.setContentType("4");
+                            String js = configService.selectConfigByKey("his.config");
+                            FSSysConfig sysConfig= JSON.parseObject(js,FSSysConfig.class);
+                            st.setMiniprogramAppid(sysConfig.getAppId());
+                            st.setMiniprogramPage(sortLiveLink);
                             break;
                         default:
                             break;
@@ -1442,6 +1470,27 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                         st.setMiniprogramAppid("未找到匹配的公司的自定义小程序:"+companyId);
                     }
 
+                    break;
+                //直播小程序单独
+                case "12":
+                    String sortLiveLink;
+                    sortLiveLink = "/pages_course/living?companyId=" + companyId + "&companyUserId=" + companyUserId + "&liveId=" + st.getLiveId();
+
+
+                    String miniprogramLiveTitle = st.getMiniprogramTitle();
+                    int maxLiveLength = 17;
+                    st.setMiniprogramTitle(miniprogramLiveTitle.length() > maxLiveLength ? miniprogramLiveTitle.substring(0, maxLiveLength) + "..." : miniprogramLiveTitle);
+                    String json = configService.selectConfigByKey("his.config");
+                    FSSysConfig sysConfig= JSON.parseObject(json,FSSysConfig.class);
+                    st.setMiniprogramAppid(sysConfig.getAppId());
+                    st.setMiniprogramPage(sortLiveLink);
+                    st.setContentType("4");
+                    try {
+                        st.setMiniprogramPicUrl(StringUtil.strIsNullOrEmpty(st.getMiniprogramPicUrl()) ? "https://cos.his.cdwjyyh.com/fs/20250331/ec2b4e73be8048afbd526124a655ad56.png" : st.getMiniprogramPicUrl());
+                    } catch (Exception e) {
+                        log.error("赋值-小程序封面地址失败-" + e);
+                    }
+
                     break;
                 default:
                     break;

+ 5 - 3
fs-service/src/main/java/com/fs/wx/order/service/ShippingService.java

@@ -1,5 +1,6 @@
 package com.fs.wx.order.service;
 
+import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.hutool.core.exceptions.ExceptionUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.http.*;
@@ -7,10 +8,12 @@ import cn.hutool.json.JSONUtil;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fs.core.config.WxMaConfiguration;
 import com.fs.wx.order.dto.UploadShippingInfoRequest;
 import com.fs.wx.order.dto.WeChatApiConfig;
 import com.fs.wx.order.dto.WeChatApiResponse;
 import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.error.WxErrorException;
 import org.springframework.stereotype.Service;
 import org.springframework.web.util.UriComponentsBuilder;
 
@@ -30,8 +33,8 @@ public class ShippingService {
      * @param request 发货信息请求体
      * @return 微信 API 的响应
      */
-    public WeChatApiResponse uploadShippingInfo(UploadShippingInfoRequest request) {
-        WeChatAuthService weChatAuthService = WeChatAuthFactory.getWeChatAuthService(request.getAppid());
+    public WeChatApiResponse uploadShippingInfo(UploadShippingInfoRequest request) throws WxErrorException {
+        final WxMaService weChatAuthService = WxMaConfiguration.getMaService(request.getAppid());
         String accessToken = weChatAuthService.getAccessToken(false);
         if (accessToken == null) {
             log.error("获取微信 Access Token 失败");
@@ -81,7 +84,6 @@ public class ShippingService {
                     log.warn("微信接口返回业务错误: code={}, message={}", weChatApiResponse.getErrcode(), weChatApiResponse.getErrmsg());
                     if(ObjectUtil.equal(weChatApiResponse.getErrcode(),40001)) {
                         log.info("token缓存失效,清除token,等待下次执行...");
-                        weChatAuthService.clearToken();
                     }
                 }
                 return weChatApiResponse;

+ 4 - 4
fs-service/src/main/java/com/fs/wx/order/service/WeChatAuthFactory.java

@@ -14,17 +14,17 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
-@Component
-public class WeChatAuthFactory implements ApplicationContextAware, SmartInitializingSingleton {
+//@Component
+public class WeChatAuthFactory  {
     private static ApplicationContext applicationContext;
     private final static Map<String,WeChatAuthService> weChatAuthServices = new ConcurrentHashMap<>();
 
-    @Override
+
     public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException {
         WeChatAuthFactory.applicationContext = applicationContext;
     }
 
-    @Override
+
     public void afterSingletonsInstantiated() {
         PaymentMiniProgramConfigMapper mapper = applicationContext.getBean(PaymentMiniProgramConfigMapper.class);
         List<PaymentMiniProgramConfig> configs = mapper.selectAll();

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

@@ -219,6 +219,6 @@ openIM:
 im:
   type: NONE
 #是否为新商户,新商户不走mpOpenId
-isNewWxMerchant: false
+isNewWxMerchant: true
 
-enableRedPackAccount: 1
+enableRedPackAccount: 0

+ 9 - 0
fs-service/src/main/resources/mapper/his/FsUserMapper.xml

@@ -2001,6 +2001,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test = "maps.nickname != null and  maps.nickname !='' " >
                 AND u.nick_name LIKE CONCAT("%",#{maps.nickname},"%")
             </if >
+            <if test = "maps.nicknameExact != null and  maps.nicknameExact !='' " >
+                AND u.nick_name = #{maps.nicknameExact}
+            </if >
             <if test = "maps.userId != null and  maps.userId !='' " >
                 AND u.user_id = #{maps.userId}
             </if >
@@ -2027,6 +2030,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test = "maps.projectId != null" >
                 AND ucu.project_id = #{maps.projectId}
             </if >
+            <if test = "maps.companyUserIds != null and  maps.companyUserIds.length > 0 " >
+                AND ucu.company_user_id in
+                <foreach collection="maps.companyUserIds" item="item" open="(" close=")" separator=",">
+                    #{item}
+                </foreach>
+            </if >
         </where>
         ORDER BY
         user_id DESC

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

@@ -1067,6 +1067,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="payEndTime != null and payEndTime != ''">
                 AND o.pay_time &lt;= #{payEndTime}
             </if>
+            <if test="userPhone != null and userPhone != ''">
+                AND o.user_phone = #{userPhone}
+            </if>
         </where>
         ORDER BY o.create_time DESC
     </select>

+ 4 - 0
fs-user-app/src/main/java/com/fs/app/controller/course/CourseFsUserController.java

@@ -11,6 +11,7 @@ import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.ResponseResult;
 import com.fs.app.annotation.Login;
 import com.fs.common.core.domain.model.LoginUser;
+import com.fs.common.utils.CloudHostUtils;
 import com.fs.common.utils.SecurityUtils;
 import com.fs.course.dto.BatchSendCourseDTO;
 import com.fs.course.param.*;
@@ -85,6 +86,9 @@ public class CourseFsUserController extends AppBaseController {
     public R getCourseByVideoId(@RequestParam("videoId") Long videoId)
     {
         FsUserCourseVideoH5VO course = courseService.selectFsUserCourseVideoH5VOByVideoId(videoId);
+        if (CloudHostUtils.hasCloudHostName("金牛明医","康年堂")){
+            course.setCourseName("");
+        }
         return R.ok().put("data",course);
     }
 

+ 17 - 3
fs-user-app/src/main/java/com/fs/app/controller/store/CompanyOrderScrmController.java

@@ -64,9 +64,11 @@ public class CompanyOrderScrmController extends AppBaseController {
     @ApiOperation("制单")
     @GetMapping("/createSalesOrder")
     public R createSalesOrder(@RequestParam("token")String token,
-                              @RequestParam("cateIds")String cateIds,
+                              @RequestParam(value = "cateIds", required = false)String cateIds,
                               @RequestParam(value = "orderType",required = false)Integer orderType,
                               @RequestParam(value = "orderMedium",required = false)Integer orderMedium,
+                              @RequestParam(value = "isPackage", required = false, defaultValue = "0")Integer isPackage,
+                              @RequestParam(value = "packageId", required = false)String packageId,
                               HttpServletRequest request){
         Long userId=redisCache.getCacheObject("company-user-token:"+token);
         if(userId==null){
@@ -79,7 +81,18 @@ public class CompanyOrderScrmController extends AppBaseController {
         if(!companyUser.getStatus().equals("0")){
             return R.error("用户已禁用");
         }
-        return orderService.createSalesOrder(companyUser,cateIds,orderType,orderMedium);
+        if(isPackage == 0){
+            return orderService.createSalesOrder(companyUser,cateIds,orderType,orderMedium);
+        } else if(isPackage == 1){
+            // 套餐包制单
+            if (packageId == null){
+                return R.error("套餐包ID不能为空");
+            }
+            return orderService.createPackageSalesOrder(companyUser,packageId,orderType,orderMedium);
+        } else {
+            return R.error("参数错误");
+        }
+
     }
 
     @ApiOperation("改价")
@@ -89,6 +102,7 @@ public class CompanyOrderScrmController extends AppBaseController {
                                    @RequestParam(value = "money",required = false) BigDecimal money,
                                    @RequestParam(value = "payAmount",required = false) BigDecimal payAmount,
                                    @RequestParam(value = "payType",required = false) Integer payType,
+                                   @RequestParam(value = "isPackage",required = false,defaultValue = "0")Integer isPackage,
                                    HttpServletRequest request){
         Long userId=redisCache.getCacheObject("company-user-token:"+token);
         if(userId==null){
@@ -100,7 +114,7 @@ public class CompanyOrderScrmController extends AppBaseController {
         if (payAmount == null){
             payAmount = BigDecimal.ZERO;
         }
-        return orderService.updateSalseOrderMoney(createOrderKey,money,payAmount,payType);
+        return orderService.updateSalseOrderMoney(createOrderKey,money,payAmount,payType, isPackage);
     }
 
     @ApiOperation("商品改价")

+ 5 - 2
fs-user-app/src/main/java/com/fs/framework/aspectj/UserOperationLogAspect.java

@@ -63,7 +63,7 @@ public class UserOperationLogAspect {
     @AfterReturning(pointcut = "@annotation(userOpLog)", returning = "result")
     public void afterReturning(JoinPoint joinPoint,UserOperationLog userOpLog, Object result) {
         FsUserOperationLog operationLog = LOG_HOLDER.get();
-        if (operationLog == null) return;
+        if (operationLog == null || StringUtils.isBlank(operationLog.getOperationType())) return;
 
         try {
             if (operationLog.getUserId() == null){
@@ -111,7 +111,10 @@ public class UserOperationLogAspect {
             //用户
             Long userId =null;
             try {
-                userId = Long.valueOf(jwtUtils.getClaimByToken(ServletUtils.getRequest().getHeader("APPToken")).getSubject().toString());
+                String appToken = ServletUtils.getRequest().getHeader("APPToken");
+                if (StringUtils.isNotBlank(appToken)){
+                    userId = Long.valueOf(jwtUtils.getClaimByToken(appToken).getSubject().toString());
+                }
             } catch (Exception ie){
                 log.info("获取用户id失败");
             }