Bläddra i källkod

Merge remote-tracking branch 'origin/master'

ct 1 vecka sedan
förälder
incheckning
723f382839
39 ändrade filer med 473 tillägg och 100 borttagningar
  1. 43 31
      fs-admin/src/main/java/com/fs/course/controller/FsUserCourseCompanyStatisticsController.java
  2. 38 0
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreHealthOrderScrmController.java
  3. 35 0
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreOrderScrmController.java
  4. 3 0
      fs-admin/src/main/java/com/fs/live/controller/LiveOrderController.java
  5. 2 2
      fs-admin/src/main/java/com/fs/qw/controller/IpadAllocationRecordsController.java
  6. 5 0
      fs-company-app/src/main/java/com/fs/app/param/FsUserLoginByMpParam.java
  7. 8 0
      fs-company/src/main/java/com/fs/company/controller/store/FsPackageOrderController.java
  8. 22 15
      fs-ipad-task/src/main/java/com/fs/app/service/IpadSendServer.java
  9. 5 0
      fs-service/src/main/java/com/fs/course/domain/FsCoursePlaySourceConfig.java
  10. 11 23
      fs-service/src/main/java/com/fs/course/domain/FsUserCourseCompanyStatistics.java
  11. 3 0
      fs-service/src/main/java/com/fs/course/param/FsCoursePlaySourceConfigCreateParam.java
  12. 3 0
      fs-service/src/main/java/com/fs/course/param/FsCoursePlaySourceConfigEditParam.java
  13. 1 1
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  14. 3 0
      fs-service/src/main/java/com/fs/course/vo/FsCoursePlaySourceConfigVO.java
  15. 5 0
      fs-service/src/main/java/com/fs/his/domain/FsUser.java
  16. 13 0
      fs-service/src/main/java/com/fs/hisStore/domain/FsUserScrm.java
  17. 2 1
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderItemScrmMapper.java
  18. 4 3
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
  19. 15 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderExportVO.java
  20. 10 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderItemExportVO.java
  21. 13 0
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderVO.java
  22. 2 0
      fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java
  23. 3 0
      fs-service/src/main/java/com/fs/live/service/impl/LiveServiceImpl.java
  24. 11 3
      fs-service/src/main/java/com/fs/live/vo/LiveOrderVoZm.java
  25. 3 2
      fs-service/src/main/resources/application-config-dev.yml
  26. 1 0
      fs-service/src/main/resources/application-config-druid-heyantang.yml
  27. 2 0
      fs-service/src/main/resources/application-config-druid-jnmy.yml
  28. 6 5
      fs-service/src/main/resources/application-config-druid-sft.yml
  29. 1 0
      fs-service/src/main/resources/application-config-zkzh.yml
  30. 0 3
      fs-service/src/main/resources/application-druid-jnmy.yml
  31. 1 1
      fs-service/src/main/resources/mapper/course/FsUserCourseCompanyStatisticsMapper.xml
  32. 5 1
      fs-service/src/main/resources/mapper/his/FsUserMapper.xml
  33. 7 5
      fs-service/src/main/resources/mapper/hisStore/FsStoreOrderScrmMapper.xml
  34. 5 1
      fs-service/src/main/resources/mapper/hisStore/FsUserScrmMapper.xml
  35. 9 1
      fs-service/src/main/resources/mapper/live/LiveOrderMapper.xml
  36. 41 0
      fs-user-app/src/main/java/com/fs/app/controller/AppLoginController.java
  37. 46 2
      fs-user-app/src/main/java/com/fs/app/controller/WxH5MpController.java
  38. 44 0
      fs-user-app/src/main/java/com/fs/app/controller/WxUserController.java
  39. 42 0
      fs-user-app/src/main/java/com/fs/app/controller/store/WxUserScrmController.java

+ 43 - 31
fs-admin/src/main/java/com/fs/course/controller/FsUserCourseCompanyStatisticsController.java

@@ -89,44 +89,56 @@ public class FsUserCourseCompanyStatisticsController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:statistics:export')")
     @Log(title = "会员每日看课统计", businessType = BusinessType.EXPORT)
     @GetMapping("/export")
-    public AjaxResult export(FsUserCourseCompanyStatistics fsUserCourseCompanyStatistics)
-    {
+    public AjaxResult export(FsUserCourseCompanyStatistics fsUserCourseCompanyStatistics) {
+
         List<FsUserCourseCompanyStatistics> list =
                 fsUserCourseCompanyStatisticsService.selectFsUserCourseCompanyStatisticsTotal(fsUserCourseCompanyStatistics);
 
-        Optional.ofNullable(list).orElse(Collections.emptyList())
-                .forEach(item -> {
-                    // 计算完播率 (完播次数 / 观看次数 * 100)
-                    item.setCompleteRate(
-                            Optional.ofNullable(item.getWatchCount())
-                                    .filter(watchCount -> watchCount > 0)
-                                    .map(watchCount -> BigDecimal.valueOf(
-                                                    Optional.ofNullable(item.getCompleteWatchCount()).orElse(0L))
-                                            .multiply(BigDecimal.valueOf(100))
-                                            .divide(BigDecimal.valueOf(watchCount), 2, RoundingMode.HALF_UP)
-                                            .longValue()
-                                    )
-                                    .orElse(0L)
-                    );
-
-                    // 计算正确率 (正确人次 / 答题人次 * 100)
-                    item.setCorrectRate(
-                            Optional.ofNullable(item.getAnswerCount())
-                                    .filter(answerCount -> answerCount > 0)
-                                    .map(answerCount -> BigDecimal.valueOf(
-                                                    Optional.ofNullable(item.getCorrectCount()).orElse(0L))
-                                            .multiply(BigDecimal.valueOf(100))
-                                            .divide(BigDecimal.valueOf(answerCount), 2, RoundingMode.HALF_UP)
-                                            .longValue()
-                                    )
-                                    .orElse(0L)
-                    );
-                });
+        if (list == null) {
+            list = Collections.emptyList();
+        }
+
+        for (FsUserCourseCompanyStatistics item : list) {
 
-        ExcelUtil<FsUserCourseCompanyStatistics> util = new ExcelUtil<FsUserCourseCompanyStatistics>(FsUserCourseCompanyStatistics.class);
+            Long watchCount = item.getWatchCount();
+            Long completeWatchCount = Optional.ofNullable(item.getCompleteWatchCount()).orElse(0L);
+
+            // 完播率 = 完播次数 / 观看次数 * 100  (放大100倍存入long,再格式化两位小数)
+            if (watchCount != null && watchCount > 0) {
+                Long rateValue = BigDecimal.valueOf(completeWatchCount)
+                        .multiply(BigDecimal.valueOf(10000)) // 100*100
+                        .divide(BigDecimal.valueOf(watchCount), 0, RoundingMode.HALF_UP)
+                        .longValue();
+                item.setCompleteRate(rateValue);
+                item.setCompleteRateStr(String.format("%.2f%%", rateValue / 100.0));  // Excel 格式化
+            } else {
+                item.setCompleteRate(0L);
+                item.setCompleteRateStr("0.00%");
+            }
+
+            Long answerCount = item.getAnswerCount();
+            Long correctCount = Optional.ofNullable(item.getCorrectCount()).orElse(0L);
+
+            // 正确率 = 正确人次 / 答题人次 * 100
+            if (answerCount != null && answerCount > 0) {
+                Long rateValue = BigDecimal.valueOf(correctCount)
+                        .multiply(BigDecimal.valueOf(10000))
+                        .divide(BigDecimal.valueOf(answerCount), 0, RoundingMode.HALF_UP)
+                        .longValue();
+                item.setCorrectRate(rateValue);
+                item.setCorrectRateStr(String.format("%.2f%%", rateValue / 100.0));
+            } else {
+                item.setCorrectRate(0L);
+                item.setCorrectRateStr("0.00%");
+            }
+        }
+
+        ExcelUtil<FsUserCourseCompanyStatistics> util = new ExcelUtil<>(FsUserCourseCompanyStatistics.class);
         return util.exportExcel(list, "会员每日看课统计数据");
     }
 
+
+
     /**
      * 获取会员每日看课统计详细信息
      */

+ 38 - 0
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreHealthOrderScrmController.java

@@ -7,14 +7,17 @@ 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.model.LoginUser;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.CloudHostUtils;
+import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.company.service.ICompanyMoneyLogsService;
 import com.fs.course.dto.FsOrderDeliveryNoteDTO;
 import com.fs.erp.service.IErpOrderService;
+import com.fs.framework.web.service.TokenService;
 import com.fs.his.domain.FsStoreOrderDf;
 import com.fs.his.service.IFsStoreOrderDfService;
 import com.fs.his.service.IFsUserService;
@@ -48,6 +51,8 @@ public class FsStoreHealthOrderScrmController extends BaseController {
 
     @Autowired
     private IFsStoreOrderStatusScrmService orderStatusService;
+    @Autowired
+    private TokenService tokenService;
 
     @Autowired
     IErpOrderService erpOrderService;
@@ -93,6 +98,7 @@ public class FsStoreHealthOrderScrmController extends BaseController {
             dataTable.setMsg("knt");
         }
         if (list != null) {
+            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
             for (FsStoreOrderVO vo : list) {
                 if(vo.getPhone()!=null){
                     vo.setPhone(vo.getPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
@@ -105,6 +111,17 @@ public class FsStoreHealthOrderScrmController extends BaseController {
                         vo.setErpAccount(df.getLoginAccount());
                     }
                 }
+                //
+                if (loginUser.getPermissions().contains("his:storeAfterSales:finance") || loginUser.getPermissions().contains("*:*:*")) {
+                    vo.setFPrice(vo.getCost().multiply(BigDecimal.valueOf(vo.getTotalNum())));
+                } else {
+                    vo.setPayPostage(BigDecimal.ZERO);
+                    vo.setCost(BigDecimal.ZERO);
+                    vo.setFPrice(BigDecimal.ZERO);
+                    vo.setPayDelivery(BigDecimal.ZERO);
+                    vo.setBarCode("");
+                    vo.setCateName("");
+                }
 
             }
         }
@@ -269,6 +286,7 @@ public class FsStoreHealthOrderScrmController extends BaseController {
         List<FsStoreOrderItemExportVO> list = orderItemService.selectFsStoreOrderItemListExportVO(param);
         //对手机号脱敏
         if (list != null) {
+            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
             for (FsStoreOrderItemExportVO vo : list) {
                 if (vo.getUserPhone() != null) {
                     String phone = vo.getUserPhone().replaceAll("(\\d{3})\\d*(\\d{1})", "$1****$2");
@@ -281,6 +299,16 @@ public class FsStoreHealthOrderScrmController extends BaseController {
                     } catch (Exception e) {
                     }
                 }
+                //
+                if (loginUser.getPermissions().contains("his:storeAfterSales:finance") || loginUser.getPermissions().contains("*:*:*")) {
+                    vo.setFPrice(vo.getCost().multiply(BigDecimal.valueOf(vo.getTotalNum())));
+                } else {
+                    vo.setPayPostage(BigDecimal.ZERO);
+                    vo.setCost(BigDecimal.ZERO);
+                    vo.setFPrice(BigDecimal.ZERO);
+                    vo.setBarCode("");
+                    vo.setCateName("");
+                }
             }
         }
         ExcelUtil<FsStoreOrderItemExportVO> util = new ExcelUtil<FsStoreOrderItemExportVO>(FsStoreOrderItemExportVO.class);
@@ -314,6 +342,7 @@ public class FsStoreHealthOrderScrmController extends BaseController {
         List<FsStoreOrderItemExportVO> list = orderItemService.selectFsStoreOrderItemListExportVO(param);
         //对手机号脱敏
         if (list != null) {
+            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
             for (FsStoreOrderItemExportVO vo : list) {
                 if (!StringUtils.isEmpty(vo.getJsonInfo())) {
                     try {
@@ -322,6 +351,15 @@ public class FsStoreHealthOrderScrmController extends BaseController {
                     } catch (Exception e) {
                     }
                 }
+                if (loginUser.getPermissions().contains("his:storeAfterSales:finance") || loginUser.getPermissions().contains("*:*:*")) {
+                    vo.setFPrice(vo.getCost().multiply(BigDecimal.valueOf(vo.getTotalNum())));
+                } else {
+                    vo.setPayPostage(BigDecimal.ZERO);
+                    vo.setCost(BigDecimal.ZERO);
+                    vo.setFPrice(BigDecimal.ZERO);
+                    vo.setBarCode("");
+                    vo.setCateName("");
+                }
             }
         }
         ExcelUtil<FsStoreOrderItemExportVO> util = new ExcelUtil<FsStoreOrderItemExportVO>(FsStoreOrderItemExportVO.class);

+ 35 - 0
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreOrderScrmController.java

@@ -194,6 +194,7 @@ public class FsStoreOrderScrmController extends BaseController {
             dataTable.setMsg("knt");
         }
         if (list != null) {
+            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
             for (FsStoreOrderVO vo : list) {
                 if(vo.getPhone()!=null){
                     vo.setPhone(vo.getPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
@@ -206,6 +207,17 @@ public class FsStoreOrderScrmController extends BaseController {
                         vo.setErpAccount(df.getLoginAccount());
                     }
                 }
+                //
+                if (loginUser.getPermissions().contains("his:storeAfterSales:finance") || loginUser.getPermissions().contains("*:*:*")) {
+                    vo.setFPrice(vo.getCost().multiply(BigDecimal.valueOf(vo.getTotalNum())));
+                } else {
+                    vo.setPayPostage(BigDecimal.ZERO);
+                    vo.setCost(BigDecimal.ZERO);
+                    vo.setFPrice(BigDecimal.ZERO);
+                    vo.setPayDelivery(BigDecimal.ZERO);
+                    vo.setBarCode("");
+                    vo.setCateName("");
+                }
             }
         }
         FsStoreOrderListAndStatisticsVo vo = new FsStoreOrderListAndStatisticsVo();
@@ -435,6 +447,8 @@ public class FsStoreOrderScrmController extends BaseController {
         List<FsStoreOrderItemExportVO> list = orderItemService.selectFsStoreOrderItemListExportVO(param);
         //对手机号脱敏
         if (list != null) {
+            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+
             for (FsStoreOrderItemExportVO vo : list) {
                 if (vo.getUserPhone() != null) {
                     String phone = vo.getUserPhone().replaceAll("(\\d{3})\\d*(\\d{1})", "$1****$2");
@@ -450,6 +464,16 @@ public class FsStoreOrderScrmController extends BaseController {
                     } catch (Exception e) {
                     }
                 }
+                //
+                if (loginUser.getPermissions().contains("his:storeAfterSales:finance") || loginUser.getPermissions().contains("*:*:*")) {
+                    vo.setFPrice(vo.getCost().multiply(BigDecimal.valueOf(vo.getTotalNum())));
+                } else {
+                    vo.setPayPostage(BigDecimal.ZERO);
+                    vo.setCost(BigDecimal.ZERO);
+                    vo.setFPrice(BigDecimal.ZERO);
+                    vo.setBarCode("");
+                    vo.setCateName("");
+                }
             }
         }
         ExcelUtil<FsStoreOrderItemExportVO> util = new ExcelUtil<FsStoreOrderItemExportVO>(FsStoreOrderItemExportVO.class);
@@ -486,6 +510,7 @@ public class FsStoreOrderScrmController extends BaseController {
         List<FsStoreOrderItemExportVO> list = orderItemService.selectFsStoreOrderItemListExportVO(param);
         //对手机号脱敏
         if (list != null) {
+            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
             for (FsStoreOrderItemExportVO vo : list) {
                 if (!StringUtils.isEmpty(vo.getJsonInfo())) {
                     try {
@@ -494,6 +519,16 @@ public class FsStoreOrderScrmController extends BaseController {
                     } catch (Exception e) {
                     }
                 }
+                //
+                if (loginUser.getPermissions().contains("his:storeAfterSales:finance") || loginUser.getPermissions().contains("*:*:*")) {
+                    vo.setFPrice(vo.getCost().multiply(BigDecimal.valueOf(vo.getTotalNum())));
+                } else {
+                    vo.setPayPostage(BigDecimal.ZERO);
+                    vo.setCost(BigDecimal.ZERO);
+                    vo.setFPrice(BigDecimal.ZERO);
+                    vo.setBarCode("");
+                    vo.setCateName("");
+                }
             }
         }
         ExcelUtil<FsStoreOrderItemExportVO> util = new ExcelUtil<FsStoreOrderItemExportVO>(FsStoreOrderItemExportVO.class);

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

@@ -178,6 +178,9 @@ public class LiveOrderController extends BaseController
             } else {
                 vo.setCostPrice(BigDecimal.ZERO);
                 vo.setFPrice(BigDecimal.ZERO);
+                vo.setPayDelivery(BigDecimal.ZERO);
+                vo.setBarCode("");
+                vo.setCateName("");
             }
             vo.setCost(vo.getCostPrice());
 

+ 2 - 2
fs-admin/src/main/java/com/fs/qw/controller/IpadAllocationRecordsController.java

@@ -52,7 +52,7 @@ public class IpadAllocationRecordsController extends BaseController {
 
     @Autowired
     private IpadAllocationRecordsMapper ipadAllocationRecordsMapper;
-    @Value("${ipad.url}")
+    @Value("${ipad.watchUrl:https://manwatch.ylrzcloud.com/prod-api}")
     private String ipadServerUrl;
 
     /**
@@ -128,7 +128,7 @@ public class IpadAllocationRecordsController extends BaseController {
         return AjaxResult.success(detailsList);
     }
 
-    @Value("${ipad.companyId:13}")
+    @Value("${ipad.fsCompanyId:13}")
     private Long companyId;
     //发起申请ipad服务器
     @GetMapping("/apply")

+ 5 - 0
fs-company-app/src/main/java/com/fs/app/param/FsUserLoginByMpParam.java

@@ -9,4 +9,9 @@ import java.io.Serializable;
 public class FsUserLoginByMpParam implements Serializable {
     @NotBlank(message = "code参数缺失")
     private String code;
+    
+    /**
+     * 小程序appId
+     */
+    private String appId;
 }

+ 8 - 0
fs-company/src/main/java/com/fs/company/controller/store/FsPackageOrderController.java

@@ -20,6 +20,7 @@ import com.fs.his.service.IFsPackageOrderService;
 import com.fs.his.utils.PhoneUtil;
 import com.fs.his.vo.FsPackageOrderListVO;
 import com.fs.his.vo.FsPackageOrderVO;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
@@ -260,4 +261,11 @@ public class FsPackageOrderController extends BaseController
         return fsPackageOrderService.getWxaCodePackageOrderUnLimit(orderId);
 
     }
+
+    @ApiOperation("修改或者添加患者首诊图片")
+    @PostMapping("/editPatientImages")
+    public R editPatientImages(@RequestParam("orderId")Long orderId,
+                               @RequestParam("imagesList")String imagesList){
+        return fsPackageOrderService.editPatientImages(orderId,imagesList);
+    }
 }

+ 22 - 15
fs-ipad-task/src/main/java/com/fs/app/service/IpadSendServer.java

@@ -13,6 +13,8 @@ import com.fs.company.service.ICompanyMiniappService;
 import com.fs.course.domain.FsCoursePlaySourceConfig;
 import com.fs.course.domain.FsCourseWatchLog;
 import com.fs.course.service.IFsCourseWatchLogService;
+import com.fs.his.domain.FsUser;
+import com.fs.his.mapper.FsUserMapper;
 import com.fs.ipad.IpadSendUtils;
 import com.fs.ipad.vo.*;
 import com.fs.qw.domain.QwExternalContact;
@@ -34,6 +36,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDateTime;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -52,7 +55,8 @@ public class IpadSendServer {
     private final IQwUserVideoService qwUserVideoService;
     private final RedisCache redisCache;
     private final ICompanyMiniappService companyMiniappService;
-
+    private final FsUserMapper fsUserMapper;
+    private static final List<String> PROJECT_NAMES = Arrays.asList("济南联志健康", "北京存在文化");
     private void sendMiniProgram(BaseVo vo, QwSopCourseFinishTempSetting.Setting content, Map<String, FsCoursePlaySourceConfig> miniMap, Long companyId) {
         String appid = content.getMiniprogramAppid();
         if(companyId != null && content.getMiniType() != null){
@@ -63,20 +67,25 @@ public class IpadSendServer {
             }
             String signProjectName = SpringUtils.getProperty("cloud_host.company_name");
             //区分新老用户,新用户发送备用小程序,老用户发送主小程序
-            if(signProjectName.equals("济南联志健康")){
+            if(PROJECT_NAMES.contains(signProjectName)){
+                log.info("ID:{}, qwUserId:{},externalId:{},进入区分发小程序逻辑", vo.getId(), vo.getQwUserId(), vo.getExId());
                 if(!vo.isRoom()){
+                    log.info("qwUserId:{},externalId:{},不是群聊", vo.getQwUserId(), vo.getExId());
                     try {
-                        log.error("1.打印小程序信息------------------》:{}",appid);
-                        log.error("2.打印企业信息------------------》:{}",companyId);
-                        QwExternalContact qwExternalContact = qwExternalContactMapper.selectOne(new LambdaQueryWrapper<QwExternalContact>().eq(QwExternalContact::getQwUserId,vo.getQwUserId()).eq(QwExternalContact::getExternalUserId,vo.getExId()));
-                        log.error("3.打印外部联系人ID-------------------》{}",qwExternalContact.getId());
-                        LocalDateTime createTime = qwExternalContact.getCreateTime() == null ? LocalDateTime.now() : DateUtil.dateToLocalDateTime(qwExternalContact.getCreateTime());
-                        LocalDateTime lastTime = LocalDateTime.of(2025, 11, 6, 23, 59, 59);
-                        int listIndex = createTime.isAfter(lastTime) ? 1 : 0 ;
-                        List<CompanyMiniapp> collect2 = list.stream().filter(e -> e.getType().equals(listIndex)).collect(Collectors.toList());
-                        if(!collect2.isEmpty() && collect2.get(0) != null && StringUtils.isNotEmpty(collect2.get(0).getAppId())){
-                            appid = collect2.get(0).getAppId();
-                            log.error("5.打印小程序信息2------------------》:{}",appid);
+                        QwExternalContact qwExternalContact = qwExternalContactMapper.selectOne(new LambdaQueryWrapper<QwExternalContact>().eq(QwExternalContact::getQwUserId,vo.getQwUserId()).eq(QwExternalContact::getExternalUserId,vo.getExId()).last(" limit 1"));
+                        if(qwExternalContact.getFsUserId() != null){
+                            FsUser fsUser = fsUserMapper.selectFsUserByUserId(qwExternalContact.getFsUserId());
+                            LocalDateTime createTime = DateUtil.dateToLocalDateTime(fsUser.getCreateTime());
+                            log.info("ID:{}, qwUserId:{},externalId:{},已绑定小程序,判断时间:{}", vo.getId(), vo.getQwUserId(), vo.getExId(), createTime);
+                            LocalDateTime lastTime = LocalDateTime.of(2025, 11, 6, 23, 59, 59);
+                            int listIndex = createTime.isAfter(lastTime) ? 1 : 0 ;
+                            List<CompanyMiniapp> collect2 = list.stream().filter(e -> e.getType().equals(listIndex)).collect(Collectors.toList());
+                            if(!collect2.isEmpty() && collect2.get(0) != null && StringUtils.isNotEmpty(collect2.get(0).getAppId())){
+                                appid = collect2.get(0).getAppId();
+                                log.info("ID:{}, qwUserId:{},externalId:{},发送小程序:{}", vo.getId(), vo.getQwUserId(), vo.getExId(), appid);
+                            }
+                        }else{
+                            log.info("ID:{}, qwUserId:{},externalId:{},未绑定小程序用户", vo.getId(), vo.getQwUserId(), vo.getExId());
                         }
                     } catch (Exception e) {
                         e.printStackTrace();
@@ -87,12 +96,10 @@ public class IpadSendServer {
             }
         }
         FsCoursePlaySourceConfig courseMaConfig = miniMap.get(appid);
-        log.error("8.打印小程序配置信息------------------》:{}",1);
         if(courseMaConfig == null){
             List<CompanyMiniapp> list = companyMiniappService.list(new QueryWrapper<CompanyMiniapp>().eq("company_id", companyId).eq("type", 1));
             if(!list.isEmpty() && list.get(0) != null && StringUtils.isNotEmpty(list.get(0).getAppId())){
                 courseMaConfig = miniMap.get(list.get(0).getAppId());
-                log.error("9.打印小程序配置信息--------最终------------------》:{}",courseMaConfig);
             }
         }
         if(courseMaConfig == null){

+ 5 - 0
fs-service/src/main/java/com/fs/course/domain/FsCoursePlaySourceConfig.java

@@ -99,4 +99,9 @@ public class FsCoursePlaySourceConfig {
      * 是否是互医/商城小程序
      */
     private Integer isMall;
+
+    /**
+     * 小程序状态:0正常,1半封禁,2封禁
+     */
+    private Integer status;
 }

+ 11 - 23
fs-service/src/main/java/com/fs/course/domain/FsUserCourseCompanyStatistics.java

@@ -17,67 +17,55 @@ import lombok.EqualsAndHashCode;
  */
 @Data
 @EqualsAndHashCode(callSuper = true)
-public class FsUserCourseCompanyStatistics extends BaseEntity{
+public class FsUserCourseCompanyStatistics extends BaseEntity {
 
-    /** 主键ID */
     private Long id;
 
-    /** 项目ID */
-//    @Excel(name = "项目ID")
     private Long projectId;
 
-    /** 完播次数(人次) */
-    @Excel(name = "完播次数", readConverterExp = "人=次")
+    @Excel(name = "完播次数")
     private Long completeWatchCount;
 
-    /** 观看次数(人次) */
-    @Excel(name = "观看次数", readConverterExp = "人=次")
+    @Excel(name = "观看次数")
     private Long watchCount;
 
-    /** 完播率(完播次数/观看次数) */
-    @Excel(name = "完播率", readConverterExp = "完=播次数/观看次数")
+    /** DB字段,存放放大100倍后的比例整数值,例 12.34% -> 1234 */
     private Long completeRate;
 
-    /** 答题人次 */
     @Excel(name = "答题人次")
     private Long answerCount;
 
-    /** 正确人次 */
     @Excel(name = "正确人次")
     private Long correctCount;
 
-    /** 正确率(正确人次/答题人次) */
-    @Excel(name = "正确率", readConverterExp = "正=确人次/答题人次")
+    /** DB字段,同样放大100倍后存储 */
     private Long correctRate;
 
-    /** 领取次数 */
     @Excel(name = "领取次数")
     private Long receiveCount;
 
-    /** 领取金额(元) */
-    @Excel(name = "领取金额", readConverterExp = "元=")
+    @Excel(name = "领取金额(元)")
     private BigDecimal receiveAmount;
 
-    /** 会员数量 */
     @Excel(name = "会员数量")
     private Long userCount;
 
-    /** 会员黑名单数量 */
     @Excel(name = "会员黑名单数量")
     private Long userBlacklistCount;
 
-    /** 公司ID */
-//    @Excel(name = "公司ID")
     private Long companyId;
 
-    /** 公司名称 */
     @Excel(name = "公司名称")
     private String companyName;
 
-    /** 统计日期 */
     @JsonFormat(pattern = "yyyy-MM-dd")
     @Excel(name = "统计日期", width = 30, dateFormat = "yyyy-MM-dd")
     private Date createDate;
 
+    /** 用于 Excel 导出显示的字符串,不入库 */
+    @Excel(name = "完播率(%)")
+    private String completeRateStr;
 
+    @Excel(name = "正确率(%)")
+    private String correctRateStr;
 }

+ 3 - 0
fs-service/src/main/java/com/fs/course/param/FsCoursePlaySourceConfigCreateParam.java

@@ -54,4 +54,7 @@ public class FsCoursePlaySourceConfigCreateParam {
     @ApiModelProperty("是否是互医/商城小程序")
     private Integer isMall;
     private Long createDeptId;
+
+    @ApiModelProperty("小程序状态:0正常,1半封禁,2封禁")
+    private Integer status;
 }

+ 3 - 0
fs-service/src/main/java/com/fs/course/param/FsCoursePlaySourceConfigEditParam.java

@@ -52,4 +52,7 @@ public class FsCoursePlaySourceConfigEditParam {
     @ApiModelProperty("是否是互医/商城小程序")
     private Integer isMall;
     private Long createDeptId;
+
+    @ApiModelProperty("小程序状态:0正常,1半封禁,2封禁")
+    private Integer status;
 }

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

@@ -1498,7 +1498,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
             // 更新观看记录的奖励类型
             log.setRewardType(config.getRewardType());
             courseWatchLogMapper.updateFsCourseWatchLog(log);
-            return R.ok("红包发送成功");
+            return R.ok("答题成功!");
         }
 
     }

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

@@ -61,4 +61,7 @@ public class FsCoursePlaySourceConfigVO {
      */
     private Integer isMall;
     private Long createDeptId;
+
+    @ApiModelProperty("小程序状态:0正常,1半封禁,2封禁")
+    private Integer status;
 }

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

@@ -174,6 +174,11 @@ public class FsUser extends BaseEntity
      * **/
     private Long qwUserId;
 
+    /**
+     * 小程序appId,多个用逗号分隔
+     */
+    private String appId;
+
 
     /** 推广上级用户ID */
     private Long spreadUserId;

+ 13 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsUserScrm.java

@@ -178,6 +178,19 @@ public class FsUserScrm extends BaseEntity
      * **/
     private Long qwUserId;
 
+    /**
+     * 小程序appId,多个用逗号分隔
+     */
+    private String appId;
+
+    public String getAppId() {
+        return appId;
+    }
+
+    public void setAppId(String appId) {
+        this.appId = appId;
+    }
+
     public void setNickName(String nickname)
     {
         if(StringUtils.isNotEmpty(nickname)){

+ 2 - 1
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreOrderItemScrmMapper.java

@@ -75,9 +75,10 @@ public interface FsStoreOrderItemScrmMapper
     List<FsStoreOrderItemVO> selectFsStoreOrderItemListAndProductByOrderId(Long id);
 
     @Select({"<script> " +
-            "select i.*,o.user_id,o.status, o.real_name,o.user_phone,o.user_address,o.create_time,o.pay_time,o.delivery_sn,o.delivery_name,o.delivery_id, c.company_name ,cu.nick_name as company_user_nick_name ,cu.phonenumber as company_usere_phonenumber,o.upload_time ,CASE WHEN o.certificates IS NULL OR o.certificates = '' THEN 0 ELSE 1 END AS is_upload   " +
+            "select i.*,o.user_id,psps.cost,o.pay_postage,o.total_num,o.status,fspcs.cate_name, o.real_name,o.user_phone,o.user_address,o.create_time,o.pay_time,o.delivery_sn,o.delivery_name,o.delivery_id, c.company_name ,cu.nick_name as company_user_nick_name ,cu.phonenumber as company_usere_phonenumber,o.upload_time ,CASE WHEN o.certificates IS NULL OR o.certificates = '' THEN 0 ELSE 1 END AS is_upload   " +
             " ,p.title as package_name,cts.name as scheduleName from fs_store_order_item_scrm i left join fs_store_order_scrm o on o.id=i.order_id left join fs_user u on o.user_id=u.user_id  " +
             " left join fs_store_product_package_scrm p on o.package_id=p.package_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 company_tcm_schedule cts on cts.id = o.schedule_id " +
+            " left join fs_store_product_scrm psps on i.product_id=psps.product_id left join fs_store_product_category_scrm fspcs on fspcs.cate_id=psps.cate_id " +
             "where 1=1 " +
             "<if test = 'maps.orderCode != null and  maps.orderCode !=\"\"    '> " +
             "and o.order_code like CONCAT('%',#{maps.orderCode},'%') " +

+ 4 - 3
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -2966,9 +2966,8 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         BigDecimal payIntegral = this.getOrderSumPrice(cartInfo, "payIntegral");//获取订单需要的积分
 
         //如果设置满包邮0 表示全局包邮,如果设置大于0表示满这价格包邮,否则走运费模板算法
-        if (storeFreePostage.compareTo(BigDecimal.ZERO) != 0 && totalPrice.compareTo(storeFreePostage) <= 0) {
-            storePostage = this.handlePostage(cartInfo, userAddress);
-        }
+        storePostage = this.handlePostage(cartInfo, userAddress);
+
 
         FsStoreOrderPriceDTO priceGroupDTO = new FsStoreOrderPriceDTO();
         priceGroupDTO.setStorePostage(storePostage);
@@ -4209,6 +4208,7 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                 user.setStatus(1);
                 user.setMaOpenId(session.getOpenid());
                 user.setUnionId(session.getUnionid());
+                user.setAppId(properties.getConfigs().get(0).getAppid());
                 user.setIsWeixinAuth(0);
                 user.setLastIp(ip);
                 user.setCreateTime(new Date());
@@ -4327,6 +4327,7 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                 user.setStatus(1);
                 user.setMaOpenId(session.getOpenid());
                 user.setUnionId(session.getUnionid());
+                user.setAppId(properties.getConfigs().get(0).getAppid());
                 user.setIsWeixinAuth(0);
                 user.setLastIp(ip);
                 user.setCreateTime(new Date());

+ 15 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderExportVO.java

@@ -126,6 +126,21 @@ public class FsStoreOrderExportVO implements Serializable
     @Excel(name = "订单状态", dictType = "store_order_status")
     private String status;
 
+    @Excel(name = "成本价",cellType= Excel.ColumnType.NUMERIC)
+    private BigDecimal cost;
+
+    /** 结算价 */
+    @Excel(name = "结算价",cellType= Excel.ColumnType.NUMERIC)
+    private BigDecimal FPrice;
+
+    /** 商品编码 */
+    @Excel(name = "商品编码")
+    private String barCode;
+
+    /** 商品分类 */
+    @Excel(name = "商品分类")
+    private String cateName;
+
 //    /** 0 未退款 1 申请中 2 已退款 */
 ////    @Excel(name = "0 未退款 1 申请中 2 已退款")
 //    private Integer refundStatus;

+ 10 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderItemExportVO.java

@@ -41,6 +41,16 @@ public class FsStoreOrderItemExportVO implements Serializable
     @Excel(name = "产品价格")
     private BigDecimal price;
 
+    @Excel(name = "成本价")
+    private BigDecimal cost;
+    @Excel(name = "结算价")
+    private BigDecimal FPrice;
+    @Excel(name = "额外运费")
+    private BigDecimal payPostage;
+    private Integer totalNum;
+    @Excel(name = "商品分类")
+    private String cateName;
+
 
     private String jsonInfo;
 

+ 13 - 0
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderVO.java

@@ -194,8 +194,21 @@ public class FsStoreOrderVO implements Serializable
     private Integer isDel;
 
     /** 成本价 */
+    @Excel(name = "成本价")
     private BigDecimal cost;
 
+    /** 结算价 */
+    @Excel(name = "结算价")
+    private BigDecimal FPrice;
+
+    /** 商品编码 */
+    @Excel(name = "商品编码")
+    private String barCode;
+
+    /** 商品分类 */
+    @Excel(name = "商品分类")
+    private String cateName;
+
     /** 核销码 */
     private String verifyCode;
 

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

@@ -3466,6 +3466,8 @@ public class LiveOrderServiceImpl implements ILiveOrderService {
 
         }
 
+        liveOrder.setPayDelivery(storePostage);
+
         return storePostage;
     }
 

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

@@ -245,6 +245,9 @@ public class LiveServiceImpl implements ILiveService
         notifyTask.setTemplateId((String) param.get("templateId"));
         FsUser fsUser = fsUserMapper.selectFsUserById(Long.valueOf((Integer) param.get("userId")));
         String maOpenId = fsUser.getMaOpenId();
+        if (StringUtils.isEmpty(maOpenId)) {
+            maOpenId = (String) param.get("maOpenId");
+        }
         notifyTask.setTouser(maOpenId);
         notifyTask.setPage(String.valueOf(1));
 

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

@@ -98,6 +98,7 @@ public class LiveOrderVoZm{
     @Excel(name = "所属店铺名称")
     private String storeName;
 
+
     @Excel(name = "商品ID")
     private Long productId;
 
@@ -123,6 +124,16 @@ public class LiveOrderVoZm{
     @Excel(name = "结算价格")
     private BigDecimal fPrice;
 
+    /** 支付运费 */
+    @Excel(name = "支付运费")
+    private BigDecimal payDelivery;
+
+    @Excel(name = "商品编码")
+    private String barCode;
+
+    @Excel(name = "商品分类")
+    private String cateName;
+
     /** 支付金额 */
     @Excel(name = "支付金额")
     private BigDecimal payMoney;
@@ -311,9 +322,6 @@ public class LiveOrderVoZm{
 //    @Excel(name = "扩展订单ID")
     private String extendOrderId;
 
-    /** 支付运费 */
-//    @Excel(name = "支付运费")
-    private BigDecimal payDelivery;
 
     /** 剩余金额 */
 //    @Excel(name = "剩余金额")

+ 3 - 2
fs-service/src/main/resources/application-config-dev.yml

@@ -92,10 +92,10 @@ nuonuo:
 tencent_cloud_config:
   secret_id: AKIDiMq9lDf2EOM9lIfqqfKo7FNgM5meD0sT
   secret_key: u5SuS80342xzx8FRBukza9lVNHKNMSaB
-  bucket: jkj-1323137866
+  bucket: cqsft-1323137866
   app_id: 1323137866
   region: ap-chongqing
-  proxy: jkj
+  proxy: cqsft
 tmp_secret_config:
   secret_id: AKIDCj7NSNAovtqeJpBau8GZ4CGB71thXIxX
   secret_key: lTB5zwqqz7CNhzDOWivFWedgfTBgxgBT
@@ -109,6 +109,7 @@ cloud_host:
 headerImg:
   imgUrl: https://jz-cos-1356808054.cos.ap-chengdu.myqcloud.com/fs/20250515/0877754b59814ea8a428fa3697b20e68.png
 ipad:
+  url:
   ipadUrl: http://ipad.cdwjyyh.com
   aiApi: http://152.136.202.157:3000/api
   voiceApi:

+ 1 - 0
fs-service/src/main/resources/application-config-druid-heyantang.yml

@@ -83,6 +83,7 @@ cloud_host:
 headerImg:
   imgUrl: https
 ipad:
+  url:
   ipadUrl: https://qwipad.yytcdtb.cn
   aiApi: http://127.0.0.1:3000/api
   voiceApi:

+ 2 - 0
fs-service/src/main/resources/application-config-druid-jnmy.yml

@@ -95,6 +95,8 @@ ipad:
   aiApi: http://49.232.181.28:3000/api
   voiceApi: http://139.186.176.122:8009
   commonApi: http://139.186.176.122:7771
+  watchUrl: https://manwatch.ylrzcloud.com/prod-api
+  fsCompanyId: 13
 wx_miniapp_temp:
   pay_order_temp_id: -SjnK9K6cNKASa6AD9Q_c0YT7J1lPTEpPIpqbMJF8F0
   inquiry_temp_id: hwFXVh0AWqeasBsZpa0-urb3CrPeYEwBiy3P6AMMGFQ

+ 6 - 5
fs-service/src/main/resources/application-config-druid-sft.yml

@@ -67,12 +67,12 @@ nuonuo:
   secret: A2EB20764D304D16
 # 存储捅配置
 tencent_cloud_config:
-  secret_id: AKIDpY8d3KcptqdCaoqeVHuKYZMvITULzQta
-  secret_key: cBShmjU4SwNejgS2PYUFnR7dzAC6pW3Q
-  bucket: sft-1361917636
-  app_id: 1361917636
+  secret_id: AKIDiMq9lDf2EOM9lIfqqfKo7FNgM5meD0sT
+  secret_key: u5SuS80342xzx8FRBukza9lVNHKNMSaB
+  bucket: cqsft-1323137866
+  app_id: 1323137866
   region: ap-chongqing
-  proxy: fs
+  proxy: cqsft
 cloud_host:
   company_name: 四福堂
   projectCode: SFT
@@ -80,6 +80,7 @@ cloud_host:
 headerImg:
   imgUrl: https://sft-1361917636.cos.ap-chongqing.myqcloud.com/sft/20250606/b08b1a6212f44f2998423c8c5d7712ee.png
 ipad:
+  url:
   ipadUrl: http://qwipad.cqsft.vip
   aiApi:
   voiceApi:

+ 1 - 0
fs-service/src/main/resources/application-config-zkzh.yml

@@ -144,6 +144,7 @@ nuonuo:
   key: 10924508
   secret: A2EB20764D304D16
 ipad:
+  url:
   ipadUrl: http://qwipad.muyi88.com
   aiApi: http://152.136.202.157:3000/api
   voiceApi:

+ 0 - 3
fs-service/src/main/resources/application-druid-jnmy.yml

@@ -160,8 +160,5 @@ im:
     type: OPENIM
 #是否为新商户,新商户不走mpOpenId
 isNewWxMerchant: true
-ipad:
-    url: https://manwatch.ylrzcloud.com/prod-api
-    companyId: 13
 
 

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

@@ -239,7 +239,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 AND DATE(create_date) <![CDATA[ <= ]]> #{endTime}
             </if>
         </where>
-
+        group by company_id,DATE(create_date)
         <!-- 排序:合计行放最后 -->
         ORDER BY create_time DESC
     </select>

+ 5 - 1
fs-service/src/main/resources/mapper/his/FsUserMapper.xml

@@ -48,11 +48,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="courseMaOpenId"    column="course_ma_open_id"    />
         <result property="qwExtId"    column="qw_ext_id"    />
         <result property="qwUserId"    column="qw_user_id"    />
+        <result property="appId"    column="app_id"    />
         <result property="level" column="level"/>
     </resultMap>
 
     <sql id="selectFsUserVo">
-        select user_id,qw_ext_id,sex,is_buy,`level`,course_ma_open_id,is_push,is_add_qw,source,login_device,is_individuation_push,store_open_id,password,jpush_id, is_vip,vip_start_date,vip_end_date,vip_level,vip_status,nick_name,integral_status, avatar, phone, integral,sign_num, status, tui_user_id, tui_time, tui_user_count, ma_open_id, mp_open_id, union_id, is_del, user_code, remark, create_time, update_time, last_ip, balance,is_weixin_auth,parent_id,qw_user_id,company_id,company_user_id,is_promoter,now_money,brokerage_price,spread_user_id, spread_time,pay_count, spread_count,user_type from fs_user
+        select user_id,qw_ext_id,sex,is_buy,`level`,course_ma_open_id,is_push,is_add_qw,source,login_device,is_individuation_push,store_open_id,password,jpush_id, is_vip,vip_start_date,vip_end_date,vip_level,vip_status,nick_name,integral_status, avatar, phone, integral,sign_num, status, tui_user_id, tui_time, tui_user_count, ma_open_id, mp_open_id, union_id, is_del, user_code, remark, create_time, update_time, last_ip, balance,is_weixin_auth,parent_id,qw_user_id,app_id,company_id,company_user_id,is_promoter,now_money,brokerage_price,spread_user_id, spread_time,pay_count, spread_count,user_type from fs_user
     </sql>
 
     <select id="selectFsUserList" parameterType="FsUser" resultMap="FsUserResult">
@@ -583,6 +584,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isPromoter != null">is_promoter,</if>
             <if test="payCount != null">pay_count,</if>
             <if test="spreadCount != null">spread_count,</if>
+            <if test="appId != null">app_id,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="nickName != null">#{nickName},</if>
@@ -632,6 +634,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isPromoter != null">#{isPromoter},</if>
             <if test="payCount != null">#{payCount},</if>
             <if test="spreadCount != null">#{spreadCount},</if>
+            <if test="appId != null">#{appId},</if>
          </trim>
     </insert>
 
@@ -683,6 +686,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="companyId != null">company_id = #{companyId},</if>
             <if test="orderCount != null">order_count = #{orderCount},</if>
             <if test="companyUserId != null">company_user_id = #{companyUserId},</if>
+            <if test="appId != null">app_id = #{appId},</if>
         </trim>
         where user_id = #{userId}
     </update>

+ 7 - 5
fs-service/src/main/resources/mapper/hisStore/FsStoreOrderScrmMapper.xml

@@ -1572,9 +1572,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         ${maps.params.dataScope} GROUP BY sp.product_id
         ) AS t
     </select>
+<!--    商城订单查询接口-->
     <select id="selectFsStoreOrderListVO" resultType="com.fs.hisStore.vo.FsStoreOrderVO">
         select o.*,u.phone,u.register_code,u.register_date,u.source, c.company_name ,cu.nick_name as company_user_nick_name ,cu.phonenumber as company_usere_phonenumber
-        , csc.name miniProgramName
+        , csc.name miniProgramName,fsp.cost as cost, fspc.cate_name,spavs.bar_code
         from fs_store_order_scrm o
         left join fs_user u on o.user_id=u.user_id
         left join company c on c.company_id=o.company_id
@@ -1583,10 +1584,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             LEFT JOIN fs_store_order_df df on df.order_id=o.id
 
         </if>
-        <if test = "maps.productName != null and  maps.productName !=  '' ">
-            left join fs_store_order_item_scrm oi on o.id = oi.order_id
-            left join fs_store_product_scrm fsp on fsp.product_id = oi.product_id
-        </if>
+        left join fs_store_order_item_scrm oi on o.id = oi.order_id
+        left join fs_store_product_scrm fsp on fsp.product_id = oi.product_id
+        left join fs_store_product_category_scrm fspc on fspc.cate_id = fsp.cate_id
+        left join fs_store_product_attr_value_scrm spavs on fsp.product_id = spavs.product_id
+
         LEFT JOIN (
         SELECT
         sp.*,

+ 5 - 1
fs-service/src/main/resources/mapper/hisStore/FsUserScrmMapper.xml

@@ -71,10 +71,11 @@
         <result property="react"    column="react"    />
         <result property="orderCount"    column="order_count"    />
         <result property="bindCompanyUserId"    column="bind_company_user_id"    />
+        <result property="appId"    column="app_id"    />
     </resultMap>
 
     <sql id="selectFsUserVo">
-        select user_id, username, nick_name, avatar, phone, integral, status, `level`, spread_user_id, spread_time, user_type, is_promoter, pay_count, spread_count, addres, tui_user_id, tui_time, tui_user_count, ma_open_id, mp_open_id, union_id, is_del, user_code, remark, nickname, create_time, update_time, last_ip, now_money, brokerage_price, balance, sign_num, integral_status, is_buy, password, real_name, birthday, id_card, jpush_id, is_vip, vip_start_date, vip_end_date, vip_level, vip_status, sex, store_open_id, is_official_account_auth, is_push, is_individuation_push, is_weixin_auth, company_id, company_user_id, register_date, register_code, test, login_device, source, is_add_qw, qw_user_id, is_show, parent_id, course_ma_open_id, history_app, qw_ext_id, `rank`, react,order_count,bind_company_user_id from fs_user
+        select user_id, username, nick_name, avatar, phone, integral, status, `level`, spread_user_id, spread_time, user_type, is_promoter, pay_count, spread_count, addres, tui_user_id, tui_time, tui_user_count, ma_open_id, mp_open_id, union_id, is_del, user_code, remark, nickname, create_time, update_time, last_ip, now_money, brokerage_price, balance, sign_num, integral_status, is_buy, password, real_name, birthday, id_card, jpush_id, is_vip, vip_start_date, vip_end_date, vip_level, vip_status, sex, store_open_id, is_official_account_auth, is_push, is_individuation_push, is_weixin_auth, company_id, company_user_id, register_date, register_code, test, login_device, source, is_add_qw, qw_user_id, is_show, parent_id, course_ma_open_id, history_app, qw_ext_id, `rank`, react,order_count,bind_company_user_id,app_id from fs_user
     </sql>
 
     <select id="selectFsUserList" parameterType="FsUserScrm" resultMap="FsUserResult">
@@ -447,6 +448,7 @@
             <if test="rank != null">rank,</if>
             <if test="react != null">react,</if>
             <if test="orderCount != null">order_count,</if>
+            <if test="appId != null">app_id,</if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="username != null">#{username},</if>
@@ -513,6 +515,7 @@
             <if test="rank != null">#{rank},</if>
             <if test="react != null">#{react},</if>
             <if test="orderCount != null">#{orderCount},</if>
+            <if test="appId != null">#{appId},</if>
         </trim>
     </insert>
 
@@ -564,6 +567,7 @@
             <if test="isPromoter != null">is_promoter = #{isPromoter},</if>
             <if test="spreadUserId != null">spread_user_id = #{spreadUserId},</if>
             <if test="brokeragePrice != null">brokerage_price = #{brokeragePrice},</if>
+            <if test="appId != null">app_id = #{appId},</if>
         </trim>
         where user_id = #{userId}
     </update>

+ 9 - 1
fs-service/src/main/resources/mapper/live/LiveOrderMapper.xml

@@ -950,6 +950,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             o.pay_time,
             o.pay_type,
             o.pay_money,
+            o.pay_delivery,
             o.create_time,
             o.update_time,
             o.status,
@@ -997,7 +998,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
             <!-- 门店信息 -->
             s.store_name AS storeName,
-            s.store_id AS storeId
+            s.store_id AS storeId,
+
+            <!-- 门店信息 -->
+            spavs.bar_code,
+            spcs.cate_name
 
         FROM
             live_order o
@@ -1005,6 +1010,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             LEFT JOIN company_user cu ON o.company_user_id = cu.user_id
             LEFT JOIN fs_store_product_scrm p ON o.product_id = p.product_id
             LEFT JOIN fs_store_scrm s ON p.store_id = s.store_id
+            LEFT JOIN fs_store_product_attr_value_scrm spavs ON p.product_id = spavs.product_id
+            LEFT JOIN fs_store_product_category_scrm spcs ON p.cate_id = spcs.cate_id
+
         <where>
             o.is_del = 0
             <if test="orderId != null">

+ 41 - 0
fs-user-app/src/main/java/com/fs/app/controller/AppLoginController.java

@@ -256,6 +256,8 @@ public class AppLoginController extends AppBaseController{
                     user.setSex(sex);
                 }
                 user.setUnionId(unionid);
+                // 新用户 - 添加 appId
+                user.setAppId(openProperties.getAppId());
                 user.setCreateTime(new Date());
                 user.setStatus(1);
                 if (StringUtils.isNotEmpty(param.getJpushId())) {
@@ -266,6 +268,15 @@ public class AppLoginController extends AppBaseController{
                 map.put("unionid",unionid);
                 return R.ok(map);
             } else {
+                // 老用户 - 检查并添加appId(不重复添加)
+                String updatedAppId = addAppIdIfNotExists(user.getAppId(), openProperties.getAppId());
+                if (!updatedAppId.equals(user.getAppId())) {
+                    FsUser userMap = new FsUser();
+                    userMap.setUserId(user.getUserId());
+                    userMap.setAppId(updatedAppId);
+                    userService.updateFsUser(userMap);
+                }
+                
                 if (StringUtils.isNotEmpty(param.getJpushId())) {
                     updateExistingUserJpushId(user, param.getJpushId());
                 }
@@ -621,4 +632,34 @@ public class AppLoginController extends AppBaseController{
             return R.error("用户不存在!");
         }
     }
+
+    /**
+     * 添加appId到用户的appId列表中(如果不存在)
+     * @param currentAppIds 当前用户已有的appId列表(逗号分隔)
+     * @param newAppId 新的appId
+     * @return 更新后的appId列表
+     */
+    private String addAppIdIfNotExists(String currentAppIds, String newAppId) {
+        // 如果新appId为空,返回原值
+        if (StringUtils.isEmpty(newAppId)) {
+            return currentAppIds == null ? "" : currentAppIds;
+        }
+        
+        // 如果当前appId为空,直接返回新appId
+        if (StringUtils.isEmpty(currentAppIds)) {
+            return newAppId;
+        }
+        
+        // 检查是否已存在
+        String[] appIdArray = currentAppIds.split(",");
+        for (String appId : appIdArray) {
+            if (appId.trim().equals(newAppId.trim())) {
+                // 已存在,不需要添加
+                return currentAppIds;
+            }
+        }
+        
+        // 不存在,追加到末尾
+        return currentAppIds + "," + newAppId;
+    }
 }

+ 46 - 2
fs-user-app/src/main/java/com/fs/app/controller/WxH5MpController.java

@@ -166,7 +166,7 @@ public class WxH5MpController {
             }
 
             // 处理用户信息
-            FsUser user = processUserInfoByCourseLoginByMp(wxMpUser);
+            FsUser user = processUserInfoByCourseLoginByMp(wxMpUser, param);
 
             // 生成token并返回结果
             return generateLoginResult(user);
@@ -189,6 +189,11 @@ public class WxH5MpController {
             userUpdate.setUpdateTime(new DateTime());
             userUpdate.setNickName(wxMpUser.getNickname());
             userUpdate.setAvatar(wxMpUser.getHeadImgUrl());
+            // 老用户 - 检查并添加 appId(不重复添加)
+            String updatedAppId = addAppIdIfNotExists(user.getAppId(), param.getAppId());
+            if (!updatedAppId.equals(user.getAppId())) {
+                userUpdate.setAppId(updatedAppId);
+            }
             userService.updateFsUser(userUpdate);
             return userUpdate;
         } else {
@@ -203,13 +208,15 @@ public class WxH5MpController {
             newUser.setUnionId(wxMpUser.getUnionId());
             newUser.setCreateTime(new Date());
             newUser.setStatus(company != null && company.getFsUserIsDefaultBlack() == 1 ? 0 : 1);
+            // 新用户 - 添加 appId
+            newUser.setAppId(param.getAppId());
             userService.insertFsUser(newUser);
 
             return newUser;
         }
     }
 
-    private FsUser processUserInfoByCourseLoginByMp(WxOAuth2UserInfo wxMpUser) {
+    private FsUser processUserInfoByCourseLoginByMp(WxOAuth2UserInfo wxMpUser, FsUserLoginByCourseMpParam param) {
         FsUser user = userService.selectFsUserByUnionId(wxMpUser.getUnionId());
 
         if (user != null) {
@@ -221,6 +228,11 @@ public class WxH5MpController {
             userUpdate.setUpdateTime(new DateTime());
             userUpdate.setNickName(wxMpUser.getNickname());
             userUpdate.setAvatar(wxMpUser.getHeadImgUrl());
+            // 老用户 - 检查并添加 appId(不重复添加)
+            String updatedAppId = addAppIdIfNotExists(user.getAppId(), param.getAppId());
+            if (!updatedAppId.equals(user.getAppId())) {
+                userUpdate.setAppId(updatedAppId);
+            }
             userService.updateFsUser(userUpdate);
             return userUpdate;
         } else {
@@ -234,6 +246,8 @@ public class WxH5MpController {
 //            newUser.setCompanyUserId(companyUser.getUserId());
             newUser.setUnionId(wxMpUser.getUnionId());
             newUser.setCreateTime(new Date());
+            // 新用户 - 添加 appId
+            newUser.setAppId(param.getAppId());
             userService.insertFsUser(newUser);
             return newUser;
         }
@@ -254,6 +268,36 @@ public class WxH5MpController {
         }
     }
 
+    /**
+     * 添加appId到用户的appId列表中(如果不存在)
+     * @param currentAppIds 当前用户已有的appId列表(逗号分隔)
+     * @param newAppId 新的appId
+     * @return 更新后的appId列表
+     */
+    private String addAppIdIfNotExists(String currentAppIds, String newAppId) {
+        // 如果新appId为空,返回原值
+        if (StringUtils.isEmpty(newAppId)) {
+            return currentAppIds == null ? "" : currentAppIds;
+        }
+        
+        // 如果当前appId为空,直接返回新appId
+        if (StringUtils.isEmpty(currentAppIds)) {
+            return newAppId;
+        }
+        
+        // 检查是否已存在
+        String[] appIdArray = currentAppIds.split(",");
+        for (String appId : appIdArray) {
+            if (appId.trim().equals(newAppId.trim())) {
+                // 已存在,不需要添加
+                return currentAppIds;
+            }
+        }
+        
+        // 不存在,追加到末尾
+        return currentAppIds + "," + newAppId;
+    }
+
     private R generateLoginResult(FsUser user) {
         String token = jwtUtils.generateToken(user.getUserId());
         redisCache.setCacheObject("token:" + user.getUserId(), token, 604800, TimeUnit.SECONDS);

+ 44 - 0
fs-user-app/src/main/java/com/fs/app/controller/WxUserController.java

@@ -156,6 +156,8 @@ public class WxUserController extends AppBaseController{
                     user.setAvatar("https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20230725/a848605591384ec29d49773dd58d9345.jpg");
                     user.setStatus(1);
                     user.setMaOpenId(session.getOpenid());
+                    // 新用户 - 添加 appId
+                    user.setAppId(appId);
                     user.setCreateTime(new Date());
                     if(session.getUnionid()!=null){
                         user.setUnionId(session.getUnionid());
@@ -176,6 +178,11 @@ public class WxUserController extends AppBaseController{
                 userMap.setMaOpenId(session.getOpenid());
                 userMap.setPhone(phoneNoInfo.getPhoneNumber());
                 userMap.setUpdateTime(new DateTime());
+                // 老用户 - 检查并添加appId(不重复添加)
+                String updatedAppId = addAppIdIfNotExists(user.getAppId(), appId);
+                if (!updatedAppId.equals(user.getAppId())) {
+                    userMap.setAppId(updatedAppId);
+                }
                 userService.updateFsUser(userMap);
             }
             String token = jwtUtils.generateToken(user.getUserId());
@@ -268,6 +275,8 @@ public class WxUserController extends AppBaseController{
                     user.setAvatar("https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20230725/a848605591384ec29d49773dd58d9345.jpg");
                     user.setStatus(1);
                     user.setCourseMaOpenId(session.getOpenid());
+                    // 新用户 - 添加 appId
+                    user.setAppId(appid);
                     user.setCreateTime(new Date());
                     if(session.getUnionid()!=null){
                         user.setUnionId(session.getUnionid());
@@ -288,6 +297,11 @@ public class WxUserController extends AppBaseController{
                 userMap.setCourseMaOpenId(session.getOpenid());
                 userMap.setPhone(phoneNoInfo.getPhoneNumber());
                 userMap.setUpdateTime(new DateTime());
+                // 老用户 - 检查并添加appId(不重复添加)
+                String updatedAppId = addAppIdIfNotExists(user.getAppId(), appid);
+                if (!updatedAppId.equals(user.getAppId())) {
+                    userMap.setAppId(updatedAppId);
+                }
                 userService.updateFsUser(userMap);
             }
             String token = jwtUtils.generateToken(user.getUserId());
@@ -416,4 +430,34 @@ public class WxUserController extends AppBaseController{
 
     }
 
+    /**
+     * 添加appId到用户的appId列表中(如果不存在)
+     * @param currentAppIds 当前用户已有的appId列表(逗号分隔)
+     * @param newAppId 新的appId
+     * @return 更新后的appId列表
+     */
+    private String addAppIdIfNotExists(String currentAppIds, String newAppId) {
+        // 如果新appId为空,返回原值
+        if (StringUtils.isEmpty(newAppId)) {
+            return currentAppIds == null ? "" : currentAppIds;
+        }
+        
+        // 如果当前appId为空,直接返回新appId
+        if (StringUtils.isEmpty(currentAppIds)) {
+            return newAppId;
+        }
+        
+        // 检查是否已存在
+        String[] appIdArray = currentAppIds.split(",");
+        for (String appId : appIdArray) {
+            if (appId.trim().equals(newAppId.trim())) {
+                // 已存在,不需要添加
+                return currentAppIds;
+            }
+        }
+        
+        // 不存在,追加到末尾
+        return currentAppIds + "," + newAppId;
+    }
+
 }

+ 42 - 0
fs-user-app/src/main/java/com/fs/app/controller/store/WxUserScrmController.java

@@ -314,6 +314,11 @@ public class WxUserScrmController extends AppBaseController {
                     if(session.getUnionid()!=null){
                         userMap.setUnionId(session.getUnionid());
                     }
+                    // 检查并添加appId(不重复添加)
+                    String updatedAppId = addAppIdIfNotExists(checkPhone.getAppId(), param.getAppId());
+                    if (!updatedAppId.equals(checkPhone.getAppId())) {
+                        userMap.setAppId(updatedAppId);
+                    }
                     userService.updateFsUser(userMap);
                 }
                 else{
@@ -324,6 +329,8 @@ public class WxUserScrmController extends AppBaseController {
                     user.setAvatar("https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20230725/a848605591384ec29d49773dd58d9345.jpg");
                     user.setStatus(1);
                     user.setMaOpenId(session.getOpenid());
+                    // 新用户 - 添加 appId
+                    user.setAppId(param.getAppId());
                     user.setCreateTime(new Date());
                     if(session.getUnionid()!=null){
                         user.setUnionId(session.getUnionid());
@@ -344,6 +351,11 @@ public class WxUserScrmController extends AppBaseController {
                 userMap.setMaOpenId(session.getOpenid());
                 userMap.setPhone(phoneNoInfo.getPhoneNumber());
                 userMap.setUpdateTime(new DateTime());
+                // 检查并添加appId(不重复添加)
+                String updatedAppId = addAppIdIfNotExists(user.getAppId(), param.getAppId());
+                if (!updatedAppId.equals(user.getAppId())) {
+                    userMap.setAppId(updatedAppId);
+                }
                 userService.updateFsUser(userMap);
             }
             String token = jwtUtils.generateToken(user.getUserId());
@@ -497,4 +509,34 @@ public class WxUserScrmController extends AppBaseController {
 
     }
 
+    /**
+     * 添加appId到用户的appId列表中(如果不存在)
+     * @param currentAppIds 当前用户已有的appId列表(逗号分隔)
+     * @param newAppId 新的appId
+     * @return 更新后的appId列表
+     */
+    private String addAppIdIfNotExists(String currentAppIds, String newAppId) {
+        // 如果新appId为空,返回原值
+        if (StringUtils.isEmpty(newAppId)) {
+            return currentAppIds == null ? "" : currentAppIds;
+        }
+        
+        // 如果当前appId为空,直接返回新appId
+        if (StringUtils.isEmpty(currentAppIds)) {
+            return newAppId;
+        }
+        
+        // 检查是否已存在
+        String[] appIdArray = currentAppIds.split(",");
+        for (String appId : appIdArray) {
+            if (appId.trim().equals(newAppId.trim())) {
+                // 已存在,不需要添加
+                return currentAppIds;
+            }
+        }
+        
+        // 不存在,追加到末尾
+        return currentAppIds + "," + newAppId;
+    }
+
 }