15 Incheckningar b54a35c441 ... 40151083a2

Upphovsman SHA1 Meddelande Datum
  yfh 40151083a2 Merge remote-tracking branch 'refs/remotes/origin/master' into Payment-Configuration 11 timmar sedan
  xgb cc84bc3be5 多支付商城配置 sql 12 timmar sedan
  xw 76d6d0c4b2 Merge remote-tracking branch 'origin/master' 13 timmar sedan
  xw 58d6ed63f0 客户进入后给前端反倒计时 13 timmar sedan
  yuhongqi e63253d9bb Merge remote-tracking branch 'origin/master' 15 timmar sedan
  yuhongqi 3f5d7dbc4a 成本单价 歧义字段修改 15 timmar sedan
  yuhongqi 0cddff2d44 银行流水为空不导出 15 timmar sedan
  Guos 3868d5418a 上海德宁数据库配置,redis配置 16 timmar sedan
  jzp 7e2e7b5d6b 1.提交配置文件 17 timmar sedan
  ct e2b80286b6 Merge remote-tracking branch 'origin/master' 1 dag sedan
  ct ef1a9dd464 fix:app分享小程序到企微 字段重命名 1 dag sedan
  yuhongqi dcc80021e1 导出订单和数据展示 1 dag sedan
  lmx 6da3b8ebb2 sop发送直播间 1 dag sedan
  xw 3c3ca89e37 Merge remote-tracking branch 'origin/master' 1 dag sedan
  xw 2486f6808e 直播实际开始时间 1 dag sedan
41 ändrade filer med 500 tillägg och 101 borttagningar
  1. 1 1
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreAfterSalesScrmController.java
  2. 1 1
      fs-admin/src/main/java/com/fs/live/controller/LiveAfterSalesController.java
  3. 2 0
      fs-admin/src/main/java/com/fs/live/controller/OrderController.java
  4. 2 0
      fs-company/src/main/java/com/fs/company/controller/live/OrderController.java
  5. 3 1
      fs-company/src/main/java/com/fs/hisStore/controller/FsStoreOrderScrmController.java
  6. 148 50
      fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java
  7. 68 0
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreAfterSalesScrmMapper.java
  8. 2 0
      fs-service/src/main/java/com/fs/hisStore/service/IFsStoreAfterSalesScrmService.java
  9. 41 0
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreAfterSalesScrmServiceImpl.java
  10. 1 1
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderItemExportRefundZMVO.java
  11. 1 1
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderItemExportVO.java
  12. 1 1
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderItemExportZMVO.java
  13. 1 1
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderPromotionExportVO.java
  14. 1 1
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderVO.java
  15. 1 1
      fs-service/src/main/java/com/fs/hisStore/vo/FsStoreProductExportVO.java
  16. 1 1
      fs-service/src/main/java/com/fs/live/domain/LiveOrder.java
  17. 17 0
      fs-service/src/main/java/com/fs/live/domain/LiveWatchLog.java
  18. 2 0
      fs-service/src/main/java/com/fs/live/mapper/LiveAfterSalesMapper.java
  19. 1 1
      fs-service/src/main/java/com/fs/live/param/LiveOrderSearchParam.java
  20. 2 0
      fs-service/src/main/java/com/fs/live/param/MergedOrderQueryParam.java
  21. 2 0
      fs-service/src/main/java/com/fs/live/service/ILiveAfterSalesService.java
  22. 10 0
      fs-service/src/main/java/com/fs/live/service/ILiveCompletionPointsRecordService.java
  23. 54 0
      fs-service/src/main/java/com/fs/live/service/impl/LiveAfterSalesServiceImpl.java
  24. 8 0
      fs-service/src/main/java/com/fs/live/service/impl/LiveCompletionPointsRecordServiceImpl.java
  25. 1 1
      fs-service/src/main/java/com/fs/live/vo/LiveOrderListVo.java
  26. 1 1
      fs-service/src/main/java/com/fs/live/vo/LiveOrderVoZm.java
  27. 1 1
      fs-service/src/main/java/com/fs/live/vo/MergedOrderExportVO.java
  28. 3 3
      fs-service/src/main/java/com/fs/qw/domain/QwCompany.java
  29. 5 0
      fs-service/src/main/java/com/fs/sop/params/SendUserLogsInfoMsgParam.java
  30. 23 1
      fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java
  31. 1 1
      fs-service/src/main/java/com/fs/store/vo/FsStoreProductScrmExportVO.java
  32. 2 2
      fs-service/src/main/resources/application-config-druid-hcl.yml
  33. 2 2
      fs-service/src/main/resources/application-config-druid-hzyy.yml
  34. 2 2
      fs-service/src/main/resources/application-config-druid-jzzx.yml
  35. 2 2
      fs-service/src/main/resources/application-config-druid-sczy.yml
  36. 5 5
      fs-service/src/main/resources/application-druid-shdn.yml
  37. 2 2
      fs-service/src/main/resources/mapper/hisStore/FsStoreProductScrmMapper.xml
  38. 9 0
      fs-service/src/main/resources/mapper/hisStore/MergedOrderMapper.xml
  39. 53 0
      fs-service/src/main/resources/mapper/live/LiveAfterSalesMapper.xml
  40. 16 16
      fs-service/src/main/resources/mapper/qw/QwCompanyMapper.xml
  41. 1 1
      fs-store/src/main/java/com/fs/store/vo/FsStoreProductStoreExcelVO.java

+ 1 - 1
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreAfterSalesScrmController.java

@@ -100,7 +100,7 @@ public class FsStoreAfterSalesScrmController extends BaseController
             return AjaxResult.error("请筛选数据导出");
         }
 
-        List<FsStoreAfterSalesVO> list = fsStoreAfterSalesService.selectFsStoreAfterSalesListVO(fsStoreAfterSales);
+        List<FsStoreAfterSalesVO> list = fsStoreAfterSalesService.selectFsStoreAfterSalesListVOExport(fsStoreAfterSales);
         if("北京卓美".equals(signProjectName)){
             List<FsStoreOrderItemExportRefundZMVO> zmvoList = list.stream()
                     .map(vo -> {

+ 1 - 1
fs-admin/src/main/java/com/fs/live/controller/LiveAfterSalesController.java

@@ -114,7 +114,7 @@ public class LiveAfterSalesController extends BaseController
     {
         PageHelper.clearPage();
         PageHelper.startPage(1, 10000, "");
-        List<LiveAfterSalesVo> list = liveAfterSalesService.selectLiveAfterSalesVoList(liveAfterSales);
+        List<LiveAfterSalesVo> list = liveAfterSalesService.selectLiveAfterSalesVoListExport(liveAfterSales);
         if("北京卓美".equals(signProjectName)){
             List<FsStoreOrderItemExportRefundZMVO> zmvoList = list.stream()
                     .map(vo -> {

+ 2 - 0
fs-admin/src/main/java/com/fs/live/controller/OrderController.java

@@ -88,6 +88,7 @@ public class OrderController extends BaseController
         // 先查询数据,限制查询20001条,用于判断是否超过限制
         PageHelper.startPage(1, maxExportCount + 1);
         List<MergedOrderVO> list = mergedOrderService.selectMergedOrderList(param);
+        list = list.stream().filter(item -> StringUtils.isNotEmpty(item.getBankTransactionId())).collect(Collectors.toList());
         
         // 如果查询结果超过20000条,返回错误提示
         if (list != null && list.size() > maxExportCount) {
@@ -126,6 +127,7 @@ public class OrderController extends BaseController
         // 先查询数据,限制查询20001条,用于判断是否超过限制
         PageHelper.startPage(1, maxExportCount + 1);
         List<MergedOrderVO> list = mergedOrderService.selectMergedOrderList(param);
+        list = list.stream().filter(item -> StringUtils.isNotEmpty(item.getBankTransactionId())).collect(Collectors.toList());
 
         // 如果查询结果超过20000条,返回错误提示
         if (list != null && list.size() > maxExportCount) {

+ 2 - 0
fs-company/src/main/java/com/fs/company/controller/live/OrderController.java

@@ -96,6 +96,7 @@ public class OrderController extends BaseController
         param.setCompanyId(user.getCompanyId());
         PageHelper.startPage(1, maxExportCount + 1);
         List<MergedOrderVO> list = mergedOrderService.selectMergedOrderList(param);
+        list = list.stream().filter(item -> StringUtils.isNotEmpty(item.getBankTransactionId())).collect(Collectors.toList());
 
         // 如果查询结果超过20000条,返回错误提示
         if (list != null && list.size() > maxExportCount) {
@@ -138,6 +139,7 @@ public class OrderController extends BaseController
         param.setCompanyId(user.getCompanyId());
         PageHelper.startPage(1, maxExportCount + 1);
         List<MergedOrderVO> list = mergedOrderService.selectMergedOrderList(param);
+        list = list.stream().filter(item -> StringUtils.isNotEmpty(item.getBankTransactionId())).collect(Collectors.toList());
 
         // 如果查询结果超过20000条,返回错误提示
         if (list != null && list.size() > maxExportCount) {

+ 3 - 1
fs-company/src/main/java/com/fs/hisStore/controller/FsStoreOrderScrmController.java

@@ -43,6 +43,7 @@ import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -182,7 +183,7 @@ public class FsStoreOrderScrmController extends BaseController
                 if (vo.getUserAddress()!=null){
                     vo.setUserAddress(ParseUtils.parseAddress(vo.getUserAddress()));
                 }
-
+                vo.setCost(BigDecimal.ZERO);
             }
         }
 
@@ -391,6 +392,7 @@ public class FsStoreOrderScrmController extends BaseController
                     catch (Exception e){
                     }
                 }
+                vo.setCost(BigDecimal.ZERO);
             }
         }
         ExcelUtil<FsStoreOrderItemExportVO> util = new ExcelUtil<FsStoreOrderItemExportVO>(FsStoreOrderItemExportVO.class);

+ 148 - 50
fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java

@@ -36,7 +36,9 @@ import javax.websocket.*;
 import javax.websocket.server.ServerEndpoint;
 import java.io.EOFException;
 import java.io.IOException;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.concurrent.locks.Lock;
@@ -83,7 +85,7 @@ public class WebSocketServer {
     private final ILiveVideoService liveVideoService = SpringUtils.getBean(ILiveVideoService.class);
     private final ILiveCompletionPointsRecordService completionPointsRecordService = SpringUtils.getBean(ILiveCompletionPointsRecordService.class);
     private static Random random = new Random();
-    
+
     // Redis key 前缀:用户进入直播间时间
     private static final String USER_ENTRY_TIME_KEY = "live:user:entry:time:%s:%s"; // liveId:userId
 
@@ -135,7 +137,7 @@ public class WebSocketServer {
 
             LiveWatchUser liveWatchUserVO = liveWatchUserService.join(fsUser,liveId, userId, location);
             room.put(userId, session);
-            
+
             // 存储用户进入直播间的时间到 Redis(用于计算在线时长)
             // 如果已经存在进入时间,说明是重连,不应该覆盖,保持原来的进入时间
             String entryTimeKey = String.format(USER_ENTRY_TIME_KEY, liveId, userId);
@@ -145,7 +147,7 @@ public class WebSocketServer {
                 redisCache.setCacheObject(entryTimeKey, System.currentTimeMillis(), 24, TimeUnit.HOURS);
             }
             // 如果是重连,不覆盖进入时间,保持原来的进入时间以便正确计算总时长
-            
+
             // 直播间浏览量 +1
             redisCache.incr(PAGE_VIEWS_KEY + liveId, 1);
 
@@ -246,6 +248,9 @@ public class WebSocketServer {
             }
             redisCache.setCacheObject( "live:user:first:entry:" + liveId + ":" + userId, liveUserFirstEntry,1, TimeUnit.HOURS);
 
+            // 推送完课积分倒计时配置信息给前端
+            sendCompletionPointsConfigToUser(session, liveId, userId, live);
+
 
         } else {
             adminRoom.add(session);
@@ -353,7 +358,7 @@ public class WebSocketServer {
                     long watchUserId = (long) userProperties.get("userId");
 
 
-                    
+
                     if (msg.getData() != null && !msg.getData().isEmpty()) {
                         try {
                             Long currentDuration = Long.parseLong(msg.getData());
@@ -371,18 +376,21 @@ public class WebSocketServer {
                                 isLiveStarted = true;
                             } else if (currentLive.getStartTime() != null) {
                                 // 判断当前时间是否已超过开播时间
-                                LocalDateTime now = java.time.LocalDateTime.now();
+                                LocalDateTime now = LocalDateTime.now();
                                 isLiveStarted = now.isAfter(currentLive.getStartTime()) || now.isEqual(currentLive.getStartTime());
                             }
-                            
-                            if (!isLiveStarted) {
-                                break;
-                            }
 
-                            
                             // 使用Hash结构存储:一个直播间一个Hash,包含所有用户的时长
                             String hashKey = "live:watch:duration:hash:" + liveId;
                             String userIdField = String.valueOf(watchUserId);
+
+                            if (!isLiveStarted) {
+                                redisCache.hashDelete(hashKey, userIdField);
+                                log.debug("[心跳-观看时长] 直播未开始,清除预播时长, liveId={}, userId={}", liveId, watchUserId);
+                                break;
+                            }
+
+                            // 直播已开始,记录观看时长
                             // 获取现有时长
                             Object existingDuration = redisCache.hashGet(hashKey, userIdField);
                             // 只有当新的时长更大时才更新
@@ -396,11 +404,11 @@ public class WebSocketServer {
 
                             }
                         } catch (Exception e) {
-                            log.error("[心跳-观看时长] 更新失败, liveId={}, userId={}, data={}", 
+                            log.error("[心跳-观看时长] 更新失败, liveId={}, userId={}, data={}",
                                     liveId, watchUserId, msg.getData(), e);
                         }
                     }
-                    
+
                     sendMessage(session, JSONObject.toJSONString(R.ok().put("data", msg)));
                     break;
                 case "sendMsg":
@@ -741,7 +749,7 @@ public class WebSocketServer {
      */
     public void broadcastWebMessage(Long liveId, String message) {
         ConcurrentHashMap<Long, Session> room = getRoom(liveId);
-        
+
         if (room.isEmpty()) {
             return;
         }
@@ -867,7 +875,7 @@ public class WebSocketServer {
         for (Map.Entry<Long, ConcurrentHashMap<Long, Session>> roomEntry : rooms.entrySet()) {
             Long liveId = roomEntry.getKey();
             ConcurrentHashMap<Long, Session> room = roomEntry.getValue();
-            
+
             // 如果房间为空,跳过
             if (room.isEmpty()) {
                 continue;
@@ -879,12 +887,12 @@ public class WebSocketServer {
             for (Map.Entry<Long, Session> userEntry : room.entrySet()) {
                 Long userId = userEntry.getKey();
                 Session session = userEntry.getValue();
-                
+
                 if (session == null) {
                     toRemove.add(userId);
                     continue;
                 }
-                
+
                 Long lastHeartbeat = heartbeatCache.get(session.getId());
                 if (lastHeartbeat != null && (currentTime - lastHeartbeat) > HEARTBEAT_TIMEOUT) {
                     toRemove.add(userId);
@@ -954,11 +962,11 @@ public class WebSocketServer {
      */
     public void broadcastLikeMessage(Long liveId, String message) {
         ConcurrentHashMap<Long, Session> room = getRoom(liveId);
-        
+
         if (room.isEmpty()) {
             return;
         }
-        
+
         // 使用快照遍历,避免并发修改
         for (Map.Entry<Long, Session> entry : room.entrySet()) {
             Session session = entry.getValue();
@@ -1119,31 +1127,31 @@ public class WebSocketServer {
             // 从 Redis 获取用户进入时间
             String entryTimeKey = String.format(USER_ENTRY_TIME_KEY, liveId, userId);
             Long entryTime = redisCache.getCacheObject(entryTimeKey);
-            
+
             if (entryTime == null) {
                 // 如果没有进入时间记录,可能是旧数据,跳过
                 return;
             }
-            
+
             long currentTimeMillis = System.currentTimeMillis();
             Date now = new Date();
-            
+
             // 计算在线时长(秒)
             long durationSeconds = (currentTimeMillis - entryTime) / 1000;
-            
+
             if (durationSeconds <= 0) {
                 return;
             }
-            
+
             // 获取当前直播/回放状态
             Map<String, Integer> flagMap = liveWatchUserService.getLiveFlagWithCache(liveId);
             Integer currentLiveFlag = flagMap.get("liveFlag");
             Integer currentReplayFlag = flagMap.get("replayFlag");
-            
+
             // 查询用户记录
             LiveWatchUserEntry liveWatchUser = liveWatchUserService.selectLiveWatchAndCompanyUserByFlag(
                     liveId, userId, currentLiveFlag, currentReplayFlag);
-            
+
             if (liveWatchUser != null) {
                 // 累加在线时长
                 Long onlineSeconds = liveWatchUser.getOnlineSeconds();
@@ -1152,7 +1160,7 @@ public class WebSocketServer {
                 }
                 liveWatchUser.setOnlineSeconds(onlineSeconds + durationSeconds);
                 liveWatchUser.setUpdateTime(now);
-                
+
                 // 更新数据库
                 liveWatchUserService.updateLiveWatchUserEntry(liveWatchUser);
                 // 如果 LiveWatchUserEntry 存在,并且当前是直播状态(liveFlag = 1),更新 LiveWatchLog
@@ -1164,15 +1172,15 @@ public class WebSocketServer {
 //                            liveWatchUser.getOnlineSeconds());
 //                }
             }
-            
+
             // 删除 Redis 中的进入时间记录
             redisCache.deleteObject(entryTimeKey);
         } catch (Exception e) {
-            log.error("更新用户在线时长异常:liveId={}, userId={}, error={}", 
+            log.error("更新用户在线时长异常:liveId={}, userId={}, error={}",
                     liveId, userId, e.getMessage(), e);
         }
     }
-    
+
     /**
      * 在连接时更新 LiveWatchLog 的 logType
      * 如果 logType 类型不是 2,修改 logType 类型为 1(看课中)
@@ -1183,7 +1191,7 @@ public class WebSocketServer {
             queryLog.setLiveId(liveId);
             queryLog.setQwUserId(String.valueOf(qwUserId));
             queryLog.setExternalContactId(externalContactId);
-            
+
             List<LiveWatchLog> logs = liveWatchLogService.selectLiveWatchLogList(queryLog);
             if (logs != null && !logs.isEmpty()) {
                 for (LiveWatchLog log : logs) {
@@ -1195,11 +1203,11 @@ public class WebSocketServer {
                 }
             }
         } catch (Exception e) {
-            log.error("更新 LiveWatchLog logType 异常(连接时):liveId={}, userId={}, error={}", 
+            log.error("更新 LiveWatchLog logType 异常(连接时):liveId={}, userId={}, error={}",
                     liveId, userId, e.getMessage(), e);
         }
     }
-    
+
     /**
      * 实时更新用户看课状态(在心跳时调用)
      * 在直播期间实时更新用户的看课状态,而不是等到关闭 WebSocket 或清理无效会话时才更新
@@ -1212,36 +1220,36 @@ public class WebSocketServer {
             // 获取当前直播/回放状态
             Map<String, Integer> flagMap = liveWatchUserService.getLiveFlagWithCache(liveId);
             Integer currentLiveFlag = flagMap.get("liveFlag");
-            
+
             // 只在直播状态(liveFlag = 1)时更新
             if (currentLiveFlag == null || currentLiveFlag != 1) {
                 return;
             }
-            
+
             // 获取用户的 companyId 和 companyUserId(使用带缓存的查询方法)
             LiveUserFirstEntry liveUserFirstEntry = liveUserFirstEntryService.selectEntityByLiveIdUserIdWithCache(liveId, userId);
             if (liveUserFirstEntry == null) {
                 return;
             }
-            
+
             Long companyId = liveUserFirstEntry.getCompanyId();
             Long companyUserId = liveUserFirstEntry.getCompanyUserId();
-            
+
             // 如果 companyId 和 companyUserId 有效,则更新看课状态
             if (companyId != null && companyId > 0 && companyUserId != null && companyUserId > 0) {
                 // 检查是否达到关键观看时长节点,在这些节点实时更新
                 // 关键节点:3分钟(180秒)、20分钟(1200秒)、30分钟(1800秒)
                 boolean isKeyDuration = (watchDuration == 180 || watchDuration == 1200 || watchDuration == 1800) ||
                                        (watchDuration > 180 && watchDuration % 60 == 0); // 每分钟更新一次
-                
+
                 // 使用 Redis 缓存控制更新频率,避免频繁更新数据库
                 // 策略:在关键节点立即更新,其他时候每60秒更新一次
                 String updateLockKey = "live:watch:log:update:lock:" + liveId + ":" + userId;
                 String lastUpdateKey = "live:watch:log:last:duration:" + liveId + ":" + userId;
-                
+
                 // 获取上次更新的时长
                 Long lastUpdateDuration = redisCache.getCacheObject(lastUpdateKey);
-                
+
                 // 如果达到关键节点,或者距离上次更新已超过60秒,则更新
                 boolean shouldUpdate = false;
                 if (isKeyDuration) {
@@ -1251,11 +1259,11 @@ public class WebSocketServer {
                     // 每60秒更新一次
                     shouldUpdate = true;
                 }
-                
+
                 if (shouldUpdate) {
                     // 使用分布式锁,避免并发更新(锁超时时间10秒)
                     Boolean canUpdate = redisCache.setIfAbsent(updateLockKey, "1", 10, TimeUnit.SECONDS);
-                    
+
                     if (Boolean.TRUE.equals(canUpdate)) {
                         // 异步更新,避免阻塞心跳处理
                         CompletableFuture.runAsync(() -> {
@@ -1264,7 +1272,7 @@ public class WebSocketServer {
                                 // 更新上次更新的时长
                                 redisCache.setCacheObject(lastUpdateKey, watchDuration, 2, TimeUnit.HOURS);
                             } catch (Exception e) {
-                                log.error("实时更新看课状态异常:liveId={}, userId={}, error={}", 
+                                log.error("实时更新看课状态异常:liveId={}, userId={}, error={}",
                                         liveId, userId, e.getMessage(), e);
                             } finally {
                                 // 释放锁
@@ -1275,11 +1283,11 @@ public class WebSocketServer {
                 }
             }
         } catch (Exception e) {
-            log.error("实时更新看课状态异常:liveId={}, userId={}, error={}", 
+            log.error("实时更新看课状态异常:liveId={}, userId={}, error={}",
                     liveId, userId, e.getMessage(), e);
         }
     }
-    
+
     /**
      * 根据在线时长更新 LiveWatchLog 的 logType
      * @param liveId 直播间ID
@@ -1288,7 +1296,7 @@ public class WebSocketServer {
      * @param companyUserId 销售ID
      * @param onlineSeconds 在线时长(秒)
      */
-    private void updateLiveWatchLogTypeByDuration(Long liveId, Long userId, Long companyId, 
+    private void updateLiveWatchLogTypeByDuration(Long liveId, Long userId, Long companyId,
                                                    Long companyUserId, Long onlineSeconds) {
         try {
             // 获取直播视频总时长(videoType = 1 的视频,使用带缓存的查询方法)
@@ -1300,13 +1308,13 @@ public class WebSocketServer {
                         .mapToLong(LiveVideo::getDuration)
                         .sum();
             }
-            
+
             // 查询 LiveWatchLog
             LiveWatchLog queryLog = new LiveWatchLog();
             queryLog.setLiveId(liveId);
             queryLog.setCompanyId(companyId);
             queryLog.setCompanyUserId(companyUserId);
-            
+
             List<LiveWatchLog> logs = liveWatchLogService.selectLiveWatchLogList(queryLog);
             if (logs == null || logs.isEmpty()) {
                 return;
@@ -1315,7 +1323,7 @@ public class WebSocketServer {
             for (LiveWatchLog log : logs) {
                 boolean needUpdate = false;
                 Integer newLogType = log.getLogType();
-                
+
                 // ① 如果在线时长 <= 3分钟,修改 logType 为 4(看课中断)
                 if (onlineSeconds <= 180) { // 3分钟 = 180秒
                     newLogType = 4;
@@ -1333,7 +1341,7 @@ public class WebSocketServer {
                     log.setFinishTime(now);
                     needUpdate = true;
                 }
-                
+
                 // 如果 logType 已经是 2(完课),不再更新
                 if (needUpdate && (log.getLogType() == null || log.getLogType() != 2)) {
                     log.setLogType(newLogType);
@@ -1341,7 +1349,7 @@ public class WebSocketServer {
                 }
             }
         } catch (Exception e) {
-            log.error("根据在线时长更新 LiveWatchLog logType 异常:liveId={}, userId={}, error={}", 
+            log.error("根据在线时长更新 LiveWatchLog logType 异常:liveId={}, userId={}, error={}",
                     liveId, userId, e.getMessage(), e);
         }
     }
@@ -1389,5 +1397,95 @@ public class WebSocketServer {
         }
     }
 
+    /**
+     * 向用户推送完课积分倒计时配置信息
+     * 在用户连接WebSocket时调用,让前端能够显示倒计时
+     * @param session WebSocket会话
+     * @param liveId 直播间ID
+     * @param userId 用户ID
+     * @param live 直播信息
+     */
+    private void sendCompletionPointsConfigToUser(Session session, Long liveId, Long userId, Live live) {
+        try {
+
+            boolean isLiveStarted = false;
+            if (live.getStatus() != null && live.getStatus() == 2) {
+                isLiveStarted = true;
+            } else if (live.getStartTime() != null) {
+                LocalDateTime now = LocalDateTime.now();
+                isLiveStarted = now.isAfter(live.getStartTime()) || now.isEqual(live.getStartTime());
+            }
+
+            if (!isLiveStarted) {
+                // 直播未开始,不推送完课配置
+                log.debug("[完课配置推送] 直播未开始,跳过推送, liveId={}, userId={}", liveId, userId);
+                return;
+            }
+
+            String configJson = live.getConfigJson();
+            if (configJson == null || configJson.isEmpty()) {
+                return;
+            }
+
+            JSONObject jsonConfig = JSON.parseObject(configJson);
+            boolean enabled = jsonConfig.getBooleanValue("enabled");
+            if (!enabled) {
+                return;
+            }
+
+            Integer completionRate = jsonConfig.getInteger("completionRate");
+            if (completionRate == null || completionRate <= 0 || completionRate > 100) {
+                return;
+            }
+
+            // 3. 计算完课所需观看时长
+            Long videoDuration = live.getDuration();
+            if (videoDuration == null || videoDuration <= 0) {
+                return;
+            }
+
+            // 完课所需时长(秒) = 视频总时长 × 完课比例 / 100
+            long requiredDuration = (long) Math.ceil(videoDuration * completionRate / 100.0);
+
+            // 4. 获取用户当前观看时长
+            String hashKey = "live:watch:duration:hash:" + liveId;
+            String userIdField = String.valueOf(userId);
+            Object existingDuration = redisCache.hashGet(hashKey, userIdField);
+            long currentDuration = existingDuration != null ? Long.parseLong(existingDuration.toString()) : 0L;
+
+            // 5. 检查今天是否已有完课记录
+            LocalDate today = LocalDate.now();
+            Date currentDate = Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant());
+            LiveCompletionPointsRecord todayRecord = completionPointsRecordService.selectByUserAndDate(liveId, userId, currentDate);
+
+            boolean hasCompletedToday = (todayRecord != null);
+
+            // 6. 构建配置信息
+            JSONObject configData = new JSONObject();
+            configData.put("videoDuration", videoDuration);  // 视频总时长(秒)
+            configData.put("completionRate", completionRate);  // 完课比例(%)
+            configData.put("requiredDuration", requiredDuration);  // 完课所需时长(秒)
+            configData.put("currentDuration", currentDuration);  // 当前观看时长(秒)
+            configData.put("remainingDuration", Math.max(0, requiredDuration - currentDuration));  // 剩余时长(秒)
+            configData.put("hasCompletedToday", hasCompletedToday);  // 今天是否已完课
+
+            // 7. 推送配置消息
+            SendMsgVo sendMsgVo = new SendMsgVo();
+            sendMsgVo.setLiveId(liveId);
+            sendMsgVo.setUserId(userId);
+            sendMsgVo.setCmd("completionPointsConfig");
+            sendMsgVo.setMsg("完课积分配置");
+            sendMsgVo.setData(configData.toJSONString());
+
+            sendMessage(session, JSONObject.toJSONString(R.ok().put("data", sendMsgVo)));
+
+            log.debug("[完课配置推送] 推送成功, liveId={}, userId={}, 所需时长={}秒, 当前时长={}秒, 剩余={}秒",
+                    liveId, userId, requiredDuration, currentDuration, Math.max(0, requiredDuration - currentDuration));
+
+        } catch (Exception e) {
+            log.error("[完课配置推送] 推送失败, liveId={}, userId={}", liveId, userId, e);
+        }
+    }
+
 }
 

+ 68 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreAfterSalesScrmMapper.java

@@ -242,4 +242,72 @@ public interface FsStoreAfterSalesScrmMapper
 
     @Select(" SELECT id FROM fs_store_order_scrm WHERE order_code =#{id}")
     Long selectFsOrderIdByCode(Long id);
+
+    @Select({"<script> " +
+            "select s.*,o.delivery_status,o.delivery_id,u.phone as user_phone,c.company_name ,cu.nick_name as company_user_nick_name ," +
+            "cu.phonenumber as company_usere_phonenumber,o.pay_money,o.id as orderId,o.create_time as orderCreateTime,o.user_phone," +
+            "o.real_name as userName,o.item_json,o.user_address,o.pay_time as orderPayTime,o.pay_price,o.total_postage," +
+            "fsps.bank_serial_no,fsps.bank_transaction_id,o.delivery_id as orderDeliveryId,o.delivery_name as orderDeliveryName,o.delivery_sn as orderDeliverySn," +
+            "o.status as orderStatus,fsps.pay_code as payCode " +
+            " from fs_store_after_sales_scrm s " +
+            " INNER join fs_store_order_scrm o on o.order_code=s.order_code " +
+            " left join fs_user u on s.user_id=u.user_id " +
+            " left join company c on c.company_id=s.company_id " +
+            " left join company_user cu on cu.user_id=s.company_user_id " +
+            " left join fs_store_payment_scrm fsps on fsps.business_order_id = o.id and fsps.status in (-1,1) " +
+            " where 1=1 and s.status = 4 and fsps.bank_transaction_id is not null " +
+            "<if test =\"maps.hfOrderCode != null and  maps.hfOrderCode!='' \"> " +
+            "and fsps.pay_code = #{maps.hfOrderCode} " +
+            "</if>" +
+            "<if test = 'maps.status != null    '> " +
+            "and s.status = #{maps.status} " +
+            "</if>" +
+            "<if test = 'maps.salesStatus != null    '> " +
+            "and s.sales_status = #{maps.salesStatus} " +
+            "</if>" +
+            "<if test = 'maps.orderStatus != null    '> " +
+            "and s.order_status = #{maps.orderStatus} " +
+            "</if>" +
+            "<if test = 'maps.orderCode != null and  maps.orderCode !=  \"\" '> " +
+            "and o.order_code like concat('%', #{maps.orderCode}, '%') " +
+            "</if>" +
+            "<if test = 'maps.deliveryStatus != null    '> " +
+            "and o.delivery_status = #{maps.deliveryStatus} " +
+            "</if>" +
+            "<if test = 'maps.serviceType != null    '> " +
+            "and s.service_type = #{maps.serviceType} " +
+            "</if>" +
+            "<if test = 'maps.companyId != null    '> " +
+            "and s.company_id = #{maps.companyId} " +
+            "</if>" +
+            "<if test = 'maps.companyUserId != null    '> " +
+            "and s.company_user_id = #{maps.companyUserId} " +
+            "</if>" +
+            "<if test = 'maps.deliverySn != null and  maps.deliverySn !=  \"\" '> " +
+            " and ( o.delivery_id like concat('%', #{maps.deliverySn}, '%') or s.delivery_sn like concat('%', #{maps.deliverySn}, '%')) " +
+            "</if>" +
+            "<if test = 'maps.companyUserNickName != null and  maps.companyUserNickName !=  \"\" '> " +
+            "and cu.nick_name like concat('%', #{maps.companyUserNickName}, '%') " +
+            "</if>" +
+            "<if test = 'maps.params != null and maps.params != \"\"   '> " +
+            "<if test = 'maps.params.beginTime != null and maps.params.beginTime != \"\"   '> " +
+            " AND date_format(s.create_time,'%y%m%d') &gt;= date_format(#{maps.params.beginTime},'%y%m%d') " +
+            "</if>" +
+            "<if test = 'maps.params.endTime != null and maps.params.endTime != \"\"   '> " +
+            " AND date_format(s.create_time,'%y%m%d') &lt;= date_format(#{maps.params.endTime},'%y%m%d') " +
+            "</if>" +
+            "</if>" +
+            "<if test = 'maps.consigneePhone != null and  maps.consigneePhone !=\"\"     '> " +
+            "and o.user_phone like CONCAT('%',#{maps.consigneePhone},'%') " +
+            "</if>" +
+            "<if test = 'maps.productName != null and  maps.productName != \"\" '> " +
+            "and EXISTS (SELECT 1 FROM fs_store_order_item_scrm oi WHERE oi.order_id = o.id AND JSON_UNQUOTE(JSON_EXTRACT(oi.json_info, '$.productName')) LIKE CONCAT('%', #{maps.productName}, '%')) " +
+            "</if>" +
+            "<if test = 'maps.deptId != null    '> " +
+            "  AND (o.dept_id = #{maps.deptId} OR o.dept_id IN ( SELECT t.dept_id FROM company_dept t WHERE find_in_set(#{maps.deptId}, ancestors) )) " +
+            "</if>" +
+            " ${maps.params.dataScope} "+
+            "order by s.create_time desc "+
+            "</script>"})
+    List<FsStoreAfterSalesVO> selectFsStoreAfterSalesListVOExport(@Param("maps") FsStoreAfterSalesScrm fsStoreAfterSales);
 }

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

@@ -117,4 +117,6 @@ public interface IFsStoreAfterSalesScrmService
     int noAuditing(FsStoreAfterSalesScrm fsStoreAfterSales);
 
     int storeRefundMoney(FsStoreAfterSalesScrm fsStoreAfterSales);
+
+    List<FsStoreAfterSalesVO> selectFsStoreAfterSalesListVOExport(FsStoreAfterSalesScrm fsStoreAfterSales);
 }

+ 41 - 0
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreAfterSalesScrmServiceImpl.java

@@ -562,6 +562,47 @@ public class FsStoreAfterSalesScrmServiceImpl implements IFsStoreAfterSalesScrmS
         return R.ok();
     }
 
+    @Override
+    @DataScope(deptAlias = "cu", userAlias = "cu")
+    public List<FsStoreAfterSalesVO> selectFsStoreAfterSalesListVOExport(FsStoreAfterSalesScrm fsStoreAfterSales) {
+        List<FsStoreAfterSalesVO> fsStoreAfterSalesVOS = fsStoreAfterSalesMapper.selectFsStoreAfterSalesListVOExport(fsStoreAfterSales);
+        List<Long> orderIds = new ArrayList<>();
+        Map<Long, List<FsStoreOrderItemVO>> orderItemMap = new HashMap<>();
+        if(null != fsStoreAfterSalesVOS && !fsStoreAfterSalesVOS.isEmpty()){
+            orderIds = fsStoreAfterSalesVOS.stream().map(e -> e.getOrderId()).collect(Collectors.toList());
+            if(null != orderIds && !orderIds.isEmpty()){
+                List<FsStoreOrderItemVO> fsStoreOrderItemVOS = fsStoreOrderItemMapper.selectFsStoreOrderItemListByOrderIds(orderIds);
+                orderItemMap = fsStoreOrderItemVOS.stream()
+                        .collect(Collectors.groupingBy(FsStoreOrderItemVO::getOrderId));
+            }
+        }
+        boolean mapEmpty = orderItemMap.isEmpty();
+        if (null != fsStoreAfterSalesVOS && !fsStoreAfterSalesVOS.isEmpty()) {
+            for (FsStoreAfterSalesVO item : fsStoreAfterSalesVOS) {
+                if(!mapEmpty && orderItemMap.containsKey(item.getOrderId())){
+                    List<FsStoreOrderItemVO> orderItems = orderItemMap.get(item.getOrderId());
+                    for (FsStoreOrderItemVO orderItem : orderItems) {
+                        try {
+                            JSONObject jsO = JSONObject.parseObject(orderItem.getJsonInfo());
+                            item.setProductName(StringUtils.isNotBlank(item.getProductName()) ? item.getProductName() + "," + jsO.getString("productName") : jsO.getString("productName"));
+                            item.setProductBarCode(StringUtils.isNotBlank(item.getProductBarCode()) ? item.getProductBarCode() + "," + jsO.getString("barCode") : jsO.getString("barCode"));
+                            item.setSku(StringUtils.isNotBlank(item.getSku()) ? item.getSku() + "," + jsO.getString("sku") : jsO.getString("sku"));
+                            item.setNum(StringUtils.isNotBlank(item.getNum()) ? item.getNum() + "," + jsO.getString("num") : jsO.getString("num"));
+                            item.setPrice(StringUtils.isNotBlank(item.getPrice()) ? item.getPrice() + "," + jsO.getString("price") : jsO.getString("price"));
+                            item.setBarCode(StringUtils.isNotBlank(item.getBarCode()) ? item.getBarCode() + "," + jsO.getString("barCode") : jsO.getString("barCode"));
+                            item.setCost(StringUtils.isNotBlank(item.getCost()) ? item.getCost() + "," + orderItem.getCost() : orderItem.getCost());
+                            item.setCateName(StringUtils.isNotBlank(item.getCateName()) ? item.getCateName() + "," + orderItem.getCateName() : orderItem.getCateName());
+
+                        } catch (Exception ex) {
+                            logger.error("售后订单商品信息转换异常",ex);
+                        }
+                    }
+                }
+            }
+        }
+        return fsStoreAfterSalesVOS;
+    }
+
     @Override
     @DataScope(deptAlias = "cu", userAlias = "cu")
     public List<FsStoreAfterSalesVO> selectFsStoreAfterSalesListVO(FsStoreAfterSalesScrm fsStoreAfterSales) {

+ 1 - 1
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderItemExportRefundZMVO.java

@@ -49,7 +49,7 @@ public class FsStoreOrderItemExportRefundZMVO implements Serializable  {
     @Excel(name = "产品价格",sort =70)
     private String price;
 
-    @Excel(name = "成本价",sort =80)
+    @Excel(name = "成本价",sort =80)
     private String cost;
     @Excel(name = "结算价",sort =90)
     private BigDecimal FPrice;

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

@@ -41,7 +41,7 @@ public class FsStoreOrderItemExportVO implements Serializable
     @Excel(name = "产品价格")
     private BigDecimal price;
 
-    @Excel(name = "成本价")
+    @Excel(name = "成本价")
     private BigDecimal cost;
     @Excel(name = "结算价")
     private BigDecimal FPrice;

+ 1 - 1
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderItemExportZMVO.java

@@ -46,7 +46,7 @@ public class FsStoreOrderItemExportZMVO implements Serializable  {
     @Excel(name = "产品价格",sort =70)
     private BigDecimal price;
 
-    @Excel(name = "成本价",sort =80)
+    @Excel(name = "成本价",sort =80)
     private BigDecimal cost;
     @Excel(name = "结算价",sort =90)
     private BigDecimal FPrice;

+ 1 - 1
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreOrderPromotionExportVO.java

@@ -132,7 +132,7 @@ public class FsStoreOrderPromotionExportVO implements Serializable
     private String packageTitle;
 
     /** 成本价 */
-    @Excel(name = "订单成本价")
+    @Excel(name = "成本价")
     private BigDecimal cost;
 
     private String phone;

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

@@ -194,7 +194,7 @@ public class FsStoreOrderVO implements Serializable
     private Integer isDel;
 
     /** 成本价 */
-    @Excel(name = "成本价")
+    @Excel(name = "成本价")
     private BigDecimal cost;
 
     /** 结算价 */

+ 1 - 1
fs-service/src/main/java/com/fs/hisStore/vo/FsStoreProductExportVO.java

@@ -118,7 +118,7 @@ public class FsStoreProductExportVO implements Serializable {
     private BigDecimal giveIntegral;
 
     /** 成本价 */
-    @Excel(name = "成本价")
+    @Excel(name = "成本价")
     private BigDecimal cost;
 
     /** 是否优品推荐 */

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

@@ -145,7 +145,7 @@ public class LiveOrder extends BaseEntity {
     private String isDel;
 
     /** 成本价 */
-    @Excel(name = "成本价")
+    @Excel(name = "成本价")
     private BigDecimal costPrice;
 
     /** 核销码 */

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

@@ -1,6 +1,8 @@
 package com.fs.live.domain;
 
 import java.util.Date;
+import java.util.Objects;
+
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.fs.common.annotation.Excel;
@@ -86,4 +88,19 @@ public class LiveWatchLog extends BaseEntity{
      */
     private Integer replayBuy;
 
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null || getClass() != obj.getClass()) return false;
+        LiveWatchLog that = (LiveWatchLog) obj;
+        return Objects.equals(liveId, that.liveId) &&
+                Objects.equals(externalContactId, that.externalContactId) &&
+                Objects.equals(qwUserId, that.qwUserId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(liveId, externalContactId, qwUserId);
+    }
+
 }

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

@@ -133,4 +133,6 @@ public interface LiveAfterSalesMapper {
 
     @Select(" select  * from  live_after_sales where order_id = #{orderId} and sales_status = 0 ")
     LiveAfterSales getLiveAfterSalesByOrderId(@Param("orderId") Long orderId);
+
+    List<LiveAfterSalesVo> selectLiveAfterSalesVoListExport(LiveAfterSalesVo liveAfterSales);
 }

+ 1 - 1
fs-service/src/main/java/com/fs/live/param/LiveOrderSearchParam.java

@@ -131,7 +131,7 @@ public class LiveOrderSearchParam extends BaseEntity {
     private String isDel;
 
     /** 成本价 */
-    @Excel(name = "成本价")
+    @Excel(name = "成本价")
     private BigDecimal costPrice;
 
     /** 核销码 */

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

@@ -118,5 +118,7 @@ public class MergedOrderQueryParam extends BaseQueryParam implements Serializabl
 
     /** ERP电话 */
     private String erpPhoneNumber;
+    /** 汇付商户订单号 */
+    private String hfshh;
 }
 

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

@@ -93,4 +93,6 @@ public interface ILiveAfterSalesService {
     Integer selectLiveAfterSalesCount(long l, int i);
 
     R handleImmediatelyRefund(Long orderId);
+
+    List<LiveAfterSalesVo> selectLiveAfterSalesVoListExport(LiveAfterSalesVo liveAfterSales);
 }

+ 10 - 0
fs-service/src/main/java/com/fs/live/service/ILiveCompletionPointsRecordService.java

@@ -2,6 +2,7 @@ package com.fs.live.service;
 
 import com.fs.live.domain.LiveCompletionPointsRecord;
 
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -40,4 +41,13 @@ public interface ILiveCompletionPointsRecordService {
      * @return 完课记录列表
      */
     List<LiveCompletionPointsRecord> getUserRecords(Long liveId, Long userId);
+
+    /**
+     * 根据用户和日期查询完课记录
+     * @param liveId 直播ID
+     * @param userId 用户ID
+     * @param date 日期
+     * @return 完课记录
+     */
+    LiveCompletionPointsRecord selectByUserAndDate(Long liveId, Long userId, Date date);
 }

+ 54 - 0
fs-service/src/main/java/com/fs/live/service/impl/LiveAfterSalesServiceImpl.java

@@ -192,6 +192,59 @@ public class LiveAfterSalesServiceImpl implements ILiveAfterSalesService {
 
 //    @Autowired
 //    private FsStoreDeliversService fsStoreDeliversService;
+
+
+    @Override
+    public List<LiveAfterSalesVo> selectLiveAfterSalesVoListExport(LiveAfterSalesVo liveAfterSales) {
+        List<LiveAfterSalesVo> liveAfterSalesVos = baseMapper.selectLiveAfterSalesVoListExport(liveAfterSales);
+        List<Long> orderIds = new ArrayList<>();
+        Map<Long, List<LiveOrderItemListUVO>> orderItemMap = new HashMap<>();
+        if(null != liveAfterSalesVos && !liveAfterSalesVos.isEmpty()){
+            orderIds = liveAfterSalesVos.stream().map(e -> e.getOrderId()).collect(Collectors.toList());
+            if(null != orderIds && !orderIds.isEmpty()){
+                List<LiveOrderItemListUVO> liveOrderItemListUVOS = liveOrderItemMapper.selectLiveOrderItemListUVOByOrderIds(orderIds);
+                orderItemMap = liveOrderItemListUVOS.stream()
+                        .collect(Collectors.groupingBy(LiveOrderItemListUVO::getOrderId));
+            }
+        }
+        boolean mapEmpty = orderItemMap.isEmpty();
+        for (LiveAfterSalesVo item : liveAfterSalesVos) {
+            if(ObjectUtil.isNotNull(item.getUserId())) {
+                FsUser fsUser = fsUserCacheService.selectFsUserById(item.getUserId());
+                if(ObjectUtil.isNotNull(fsUser)) {
+                    item.setUserName(String.format("%s_%s",fsUser.getUserId(),fsUser.getNickname()));
+                }
+            }
+
+            if(ObjectUtil.isNull(item.getCompanyUserNickName())) {
+                item.setCompanyUserNickName("-");
+            }
+
+            if(ObjectUtil.isNull(item.getCompanyName())){
+                item.setCompanyName("-");
+            }
+
+            if(!mapEmpty && orderItemMap.containsKey(item.getOrderId())){
+                List<LiveOrderItemListUVO> liveOrderItemListUVOS = orderItemMap.get(item.getOrderId());
+                for (LiveOrderItemListUVO liveOrderItemListUVO : liveOrderItemListUVOS) {
+                    try {
+                        JSONObject jsO = JSONObject.parseObject(liveOrderItemListUVO.getJsonInfo());
+                        item.setProductName(StringUtils.isNotBlank(item.getProductName()) ? item.getProductName() + "," + jsO.getString("productName") : jsO.getString("productName"));
+                        item.setProductBarCode(StringUtils.isNotBlank(item.getProductBarCode()) ? item.getProductBarCode() + "," + jsO.getString("barCode") : jsO.getString("barCode"));
+                        item.setSku(StringUtils.isNotBlank(item.getSku()) ? item.getSku() + "," + jsO.getString("sku") : jsO.getString("sku"));
+                        item.setNum(StringUtils.isNotBlank(item.getNum()) ? item.getNum() + "," + jsO.getString("num") : jsO.getString("num"));
+                        item.setPrice(StringUtils.isNotBlank(item.getPrice()) ? item.getPrice() + "," + jsO.getString("price") : jsO.getString("price"));
+                        item.setCost(StringUtils.isNotBlank(item.getCost()) ? item.getCost() + "," + liveOrderItemListUVO.getCost() : liveOrderItemListUVO.getCost());
+                        item.setCateName(StringUtils.isNotBlank(item.getCateName()) ? item.getCateName() + "," + liveOrderItemListUVO.getCateName() : liveOrderItemListUVO.getCateName());
+                    } catch (Exception ex) {
+                        log.error("售后订单商品信息转换异常",ex);
+                    }
+                }
+            }
+
+        }
+        return liveAfterSalesVos;
+    }
     /**
      * 查询售后记录列表
      *
@@ -1124,4 +1177,5 @@ public class LiveAfterSalesServiceImpl implements ILiveAfterSalesService {
 
         return R.ok();
     }
+
 }

+ 8 - 0
fs-service/src/main/java/com/fs/live/service/impl/LiveCompletionPointsRecordServiceImpl.java

@@ -261,6 +261,14 @@ public class LiveCompletionPointsRecordServiceImpl implements ILiveCompletionPoi
         return recordMapper.selectRecordsByUser(liveId, userId);
     }
 
+    /**
+     * 根据用户和日期查询完课记录
+     */
+    @Override
+    public LiveCompletionPointsRecord selectByUserAndDate(Long liveId, Long userId, Date date) {
+        return recordMapper.selectByUserAndDate(liveId, userId, date);
+    }
+
     /**
      * 从直播配置中获取完课积分配置
      */

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

@@ -136,7 +136,7 @@ public class LiveOrderListVo extends BaseEntity {
     private String isDel;
 
     /** 成本价 */
-    @Excel(name = "成本价")
+    @Excel(name = "成本价")
     private BigDecimal costPrice;
 
     /** 核销码 */

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

@@ -118,7 +118,7 @@ public class LiveOrderVoZm{
     @Excel(name = "销售价格")
     private BigDecimal price;
 
-    @Excel(name = "成本价")
+    @Excel(name = "成本价")
     private BigDecimal cost;
 
     @Excel(name = "结算价格")

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

@@ -56,7 +56,7 @@ public class MergedOrderExportVO implements Serializable
     private BigDecimal price;
 
     /** 成本价 */
-    @Excel(name = "成本价")
+    @Excel(name = "成本价")
     private BigDecimal cost;
 
     /** 商品金额 */

+ 3 - 3
fs-service/src/main/java/com/fs/qw/domain/QwCompany.java

@@ -89,11 +89,11 @@ public class QwCompany extends BaseEntity
     /**
      * 御君方云医小程序原始id
      */
-    private String yjfyyAppId;
+    private String shareAppId;
     /**
      * 御君方云医应用id
      */
-    private String yjfyyAgentId;
+    private String shareAgentId;
 
-    private String yjfyySchema;
+    private String shareSchema;
 }

+ 5 - 0
fs-service/src/main/java/com/fs/sop/params/SendUserLogsInfoMsgParam.java

@@ -36,4 +36,9 @@ public class SendUserLogsInfoMsgParam {
 
     private List<String> qwUserIds; //当isMine为1 需要查询该主体下该员工的营期
 
+    /**
+     * 直播间id
+     */
+    private Long liveId;
+
 }

+ 23 - 1
fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java

@@ -489,6 +489,11 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
     }
     @Override
     public R sendUserLogsInfoMsg(SendUserLogsInfoMsgParam param) {
+        Boolean sendLiveMsg = Boolean.FALSE;
+        if(null != param.getLiveId()){
+            sendLiveMsg = Boolean.TRUE;
+        }
+        Boolean sendLiveMsgFinal = sendLiveMsg;
         QwSop qwSop = qwSopMapper.selectQwSopById(param.getSopId());
         List<FastGptChatReplaceWords> words = fastGptChatReplaceWordsMapper.selectAllFastGptChatReplaceWords();
         String json = configService.selectConfigByKey("course.config");
@@ -578,6 +583,9 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                     sopLogs.setCorpId(qwGroupChat.getCorpId());
                     sopLogs.setSort(30000001);
                     sopLogs.setSendType(2);
+                    if(sendLiveMsgFinal){
+                        sopLogs.setSendType(20);
+                    }
                     sopLogs.setExternalUserName(groupUser.getName());
                     sopLogs.setQwUserKey(qwUser.getId());
 
@@ -754,6 +762,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                     setting.setVideoId(param.getVideoId());
                     setting.setCourseId(param.getCourseId());
                     setting.setCourseType(param.getCourseType());
+                    setting.setLiveId(param.getLiveId());
                     sopLogs.setContentJson(JSON.toJSONString(setting));
                     return sopLogs;
                 }).filter(Objects::nonNull).collect(Collectors.toList());
@@ -780,6 +789,9 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                     sopLogs.setCorpId(groupChat.getCorpId());
                     sopLogs.setSort(2);
                     sopLogs.setSendType(6);
+                    if(sendLiveMsgFinal){
+                        sopLogs.setSendType(20);
+                    }
                     sopLogs.setExternalUserName(groupChat.getName());
                     sopLogs.setQwUserKey(qwUser.getId());
                     // 设置实际发送人
@@ -968,6 +980,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                     setting.setVideoId(param.getVideoId());
                     setting.setCourseId(param.getCourseId());
                     setting.setCourseType(param.getCourseType());
+                    setting.setLiveId(param.getLiveId());
                     sopLogs.setContentJson(JSON.toJSONString(setting));
                     return sopLogs;
                 }).collect(Collectors.toList());
@@ -1027,6 +1040,9 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                 sopLogs.setSort(30000000);
                 sopLogs.setSendType(5);
                 sopLogs.setExternalUserName(item.getExternalUserName());
+                   if(sendLiveMsgFinal){
+                       sopLogs.setSendType(20);
+                   }
 
                 QwExternalContact contact = qwExternalContactMapper.selectQwExternalContactByIdForStageStatus(item.getExternalId());
 
@@ -1164,7 +1180,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                             st.setContentType("4");
                             String js = configService.selectConfigByKey("his.config");
                             FSSysConfig sysConfig= JSON.parseObject(js,FSSysConfig.class);
-                            //todo 发个人看课记录处理
+                            //发个人看课记录处理
                             try {
                                     createLiveWatchLogAndInsert(qwUser.getCompanyId().toString(), qwUser.getCompanyUserId().toString(),item.getExternalId().toString(),Long.valueOf(st.getLiveId()),sysConfig.getAppId(),2, qwUserId,param.getCorpId());
 
@@ -1299,6 +1315,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                 setting.setVideoId(param.getVideoId());
                 setting.setCourseId(param.getCourseId());
                 setting.setCourseType(param.getCourseType());
+                setting.setLiveId(param.getLiveId());
 
                 try {
                     sopLogs.setQwUserKey(Long.valueOf(qwUserId));
@@ -1458,6 +1475,9 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
 
         // 遍历分组
         int finalSort = sort;
+        if(null != param.getLiveId()){
+            sendType = 20;
+        }
         int finalSendType = sendType;
         groupedLogs.forEach((key, logs) -> {
 
@@ -1546,6 +1566,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
 
             switch (finalSendType){
                 case 5:
+                case 20:
                     List<QwSopCourseFinishTempSetting.Setting> list = processSetting(item,qwUser, param, words, config, qwCompany,companyUserId,companyId,
                             contact,dataTime, finalDomainName,miniMap,companies,sopLogs);
                     setting.setSetting(list);
@@ -1574,6 +1595,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
             setting.setVideoId(param.getVideoId());
             setting.setCourseId(param.getCourseId());
             setting.setCourseType(param.getCourseType());
+            setting.setLiveId(param.getLiveId());
             try {
                 sopLogs.setQwUserKey(qwUser.getId());
             }catch (Exception e){

+ 1 - 1
fs-service/src/main/java/com/fs/store/vo/FsStoreProductScrmExportVO.java

@@ -118,7 +118,7 @@ public class FsStoreProductScrmExportVO implements Serializable {
     private BigDecimal giveIntegral;
 
     /** 成本价 */
-    @Excel(name = "成本价")
+    @Excel(name = "成本价")
     private BigDecimal cost;
 
     /** 是否优品推荐 */

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

@@ -90,8 +90,8 @@ tmp_secret_config:
 cloud_host:
   company_name: 恒春来
   projectCode: HCL
-  spaceName:
-  volcengineUrl:
+  spaceName: hcl-2114522511
+  volcengineUrl: https://hclvolcengine.ylrztop.com
 #看课授权时显示的头像
 headerImg:
   imgUrl: http://hcl-1b2b.obs.cn-south-1.myhuaweicloud.com/fs/20250815/1755228988455.png

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

@@ -90,8 +90,8 @@ tmp_secret_config:
 cloud_host:
   company_name: 弘珍医药
   projectCode: HZYY
-  spaceName:
-  volcengineUrl:
+  spaceName: hzyy-2114522511
+  volcengineUrl: https://hzyyvolcengine.ylrztop.com
 #看课授权时显示的头像
 headerImg:
   imgUrl: https://hzyy.obs.cn-north-4.myhuaweicloud.com/fs/20250616/1750067609692.png

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

@@ -94,8 +94,8 @@ tmp_secret_config:
 cloud_host:
   company_name: 九州在线
   projectCode: JZZX
-  spaceName:
-  volcengineUrl:
+  spaceName: jzzx-2114522511
+  volcengineUrl: https://jzzxvolcengine.ylrztop.com
 headerImg:
   imgUrl: https://jiuzhouzaixian.obs.cn-southwest-2.myhuaweicloud.com/fs/20250623/1750665141214.png
 ipad:

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

@@ -94,8 +94,8 @@ tmp_secret_config:
 cloud_host:
   company_name: 四川致医
   projectCode: SCZY
-  spaceName:
-  volcengineUrl:
+  spaceName: sczy-2114522511
+  volcengineUrl: https://sczytvolcengine.ylrztop.com
 headerImg:
   imgUrl: https://jiuzhouzaixian.obs.cn-southwest-2.myhuaweicloud.com/fs/20250623/1750665141214.png
 ipad:

+ 5 - 5
fs-service/src/main/resources/application-druid-shdn.yml

@@ -4,12 +4,12 @@ spring:
         include: config-druid-shdn,common
     # redis 配置
     redis:
-        host: 10.206.0.10
-        port: 6579
+        host: 172.17.0.10
+        port: 6379
         # 数据库索引
         database: 0
         # 密码
-        password:
+        password: !@#123QWe
         # 连接超时时间
         timeout: 30s
         lettuce:
@@ -39,7 +39,7 @@ spring:
             druid:
                 # 主库数据源
                 master:
-                  url: jdbc:mysql://172.17.0.12:65535/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                  url: jdbc:mysql://172.17.0.12:3306/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
                   username: root
                   password: QWEqwe123!@#
                 # 从库数据源
@@ -94,7 +94,7 @@ spring:
             druid:
                 # 主库数据源
                 master:
-                    url: jdbc:mysql://172.17.0.12:65535/fs_his_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                    url: jdbc:mysql://172.17.0.12:3306/fs_his_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
                     username: root
                     password: QWEqwe123!@#
                 # 初始连接数

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

@@ -461,11 +461,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </update>
 
     <delete id="deleteFsStoreProductById" parameterType="Long">
-        delete from fs_store_product_scrm where product_id = #{productId}
+        update  fs_store_product_scrm set id_del = 1 where product_id = #{productId}
     </delete>
 
     <delete id="deleteFsStoreProductByIds" parameterType="String">
-        delete from fs_store_product_scrm where product_id in
+        update fs_store_product_scrm set id_del = 1 where product_id in
         <foreach item="productId" collection="array" open="(" separator="," close=")">
             #{productId}
         </foreach>

+ 9 - 0
fs-service/src/main/resources/mapper/hisStore/MergedOrderMapper.xml

@@ -145,6 +145,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
           <if test="maps.appId != null and maps.appId != ''">
             AND csc.appid = #{maps.appId}
           </if>
+        <if test="maps.hfshh != null and maps.hfshh != ''">
+            AND hfshh = #{maps.hfshh}
+        </if>
           group by o.id
           UNION ALL
           -- 商城订单(没有company_user_id的商城订单)
@@ -287,6 +290,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
           <if test="maps.appId != null and maps.appId != ''">
             AND csc.appid = #{maps.appId}
           </if>
+        <if test="maps.hfshh != null and maps.hfshh != ''">
+            AND hfshh = #{maps.hfshh}
+        </if>
         group by o.id
           UNION ALL
           -- 直播订单
@@ -426,6 +432,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
           <if test="maps.deliverySendTimeRange != null and maps.deliverySendTimeRange != ''">
             AND DATE(o.delivery_send_time) BETWEEN SUBSTRING_INDEX(#{maps.deliverySendTimeRange}, '--', 1) AND SUBSTRING_INDEX(#{maps.deliverySendTimeRange}, '--', -1)
           </if>
+        <if test="maps.hfshh != null and maps.hfshh != ''">
+            AND hfshh = #{maps.hfshh}
+        </if>
         group by o.order_id
         ) AS merged_orders
         WHERE 1=1

+ 53 - 0
fs-service/src/main/resources/mapper/live/LiveAfterSalesMapper.xml

@@ -115,6 +115,59 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </if>
         order by las.create_time desc
     </select>
+    <select id="selectLiveAfterSalesVoListExport" parameterType="com.fs.live.vo.LiveAfterSalesVo" resultType="com.fs.live.vo.LiveAfterSalesVo">
+        select las.id, las.live_id, las.store_id, las.refund_amount,
+        las.refund_type, las.reasons, las.explains, las.explain_img, las.delivery_code, las.delivery_sn, las.delivery_name, las.status, las.sales_status,
+        las.order_status, las.create_time, las.is_del, las.user_id, las.consignee, las.phone_number, las.address, las.company_id, las.company_user_id, las.dept_id,
+        cu.nick_name as company_user_nick_name, c.company_name,lo.order_id,lo.order_code,lo.user_phone,lo.item_json,lo.pay_time as orderPayTime,
+        lo.user_address,lo.user_name,lo.pay_price,lo.total_postage,lop.bank_serial_no,lo.delivery_sn as orderDeliveryId,lo.delivery_name as orderDeliveryName,
+        lo.delivery_code as orderDeliverySn,lo.status as orderStatus,lop.bank_transaction_id,lo.pay_money,lop.pay_code as payCode
+        from live_after_sales las
+        left join live_order lo on lo.order_id = las.order_id
+        left join company_user cu on cu.user_id = las.company_user_id
+        left join company c on c.company_id = cu.company_id
+        left join live_order_payment lop on lop.business_id = lo.order_id and lop.status in (1,-1)
+        <if test="productName != null and productName != ''">
+        left join live_order_item loi on loi.order_id = lo.order_id
+        </if>
+
+        where 1=1 and las.status =4 and lop.bank_transaction_id is not null
+            <if test="hfOrderCode != null and hfOrderCode != ''"> and lop.pay_code = #{hfOrderCode}</if>
+            <if test="liveId != null and liveId != ''"> and las.live_id = #{liveId}</if>
+            <if test="companyUserNickName != null and companyUserNickName != ''"> and cu.nick_name like concat(#{companyUserNickName},'%')</if>
+            <if test="storeId != null and storeId != ''"> and las.store_id = #{storeId}</if>
+            <if test="orderCode != null and orderCode != ''"> and lo.order_code = #{orderCode}</if>
+            <if test="productNameQuery != null and productNameQuery != ''"> and JSON_UNQUOTE(JSON_EXTRACT(loi.json_info, '$.productName')) like concat('%', #{productNameQuery}, '%')</if>
+            <if test="refundAmount != null "> and las.refund_amount = #{refundAmount}</if>
+            <if test="refundType != null "> and las.refund_type = #{refundType}</if>
+            <if test="status != null "> and las.status = #{status}</if>
+            <if test="salesStatus != null "> and las.sales_status = #{salesStatus}</if>
+            <if test="orderStatus != null "> and las.order_status = #{orderStatus}</if>
+            <if test="reasons != null  and reasons != ''"> and las.reasons = #{reasons}</if>
+            <if test="explains != null  and explains != ''"> and las.explains = #{explains}</if>
+            <if test="explainImg != null  and explainImg != ''"> and las.explain_img = #{explainImg}</if>
+            <if test="deliveryCode != null  and deliveryCode != ''"> and las.delivery_code = #{deliveryCode}</if>
+            <if test="deliverySn != null  and deliverySn != ''"> and las.delivery_sn = #{deliverySn}</if>
+            <if test="deliveryName != null  and deliveryName != ''"> and las.delivery_name like concat('%', #{deliveryName}, '%')</if>
+            <if test="status != null "> and las.status = #{status}</if>
+            <if test="salesStatus != null "> and las.sales_status = #{salesStatus}</if>
+            <if test="orderStatus != null "> and las.order_status = #{orderStatus}</if>
+            <if test="deliveryStatus != null and deliveryStatus!= ''"> and las.order_status = #{deliveryStatus}</if>
+            <if test="isDel != null  and isDel != ''"> and las.is_del = #{isDel}</if>
+            <if test="userId != null "> and las.user_id = #{userId}</if>
+            <if test="consignee != null  and consignee != ''"> and las.consignee = #{consignee}</if>
+            <if test="phoneNumber != null  and phoneNumber != ''"> and las.phone_number = #{phoneNumber}</if>
+            <if test="address != null  and address != ''"> and las.address = #{address}</if>
+            <if test="companyId != null "> and las.company_id = #{companyId}</if>
+            <if test="companyUserId != null "> and las.company_user_id = #{companyUserId}</if>
+            <if test="deptId != null "> and cu.dept_id = #{deptId}</if>
+            <if test="userPhone != null "> and lo.user_phone like concat(#{userPhone},'%')</if>
+
+        <if test="productName != null and productName != ''">
+        group by las.id
+        </if>
+        order by las.create_time desc
+    </select>
 
     <select id="selectLiveAfterSalesById" parameterType="Long" resultMap="LiveAfterSalesResult">
         <include refid="selectLiveAfterSalesVo"/>

+ 16 - 16
fs-service/src/main/resources/mapper/qw/QwCompanyMapper.xml

@@ -30,13 +30,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="msgPrivateKey"    column="msg_private_key"    />
         <result property="miniAppId"    column="mini_app_id"    />
         <result property="companyServerNum"    column="company_server_num"    />
-        <result property="yjfyyAppId"    column="yjfyy_app_id"    />
-        <result property="yjfyyAgentId"    column="yjfyy_agent_id"    />
-        <result property="yjfyySchema"    column="yjfyy_schema"    />
+        <result property="shareAppId"    column="share_app_id"    />
+        <result property="shareAgentId"    column="share_agent_id"    />
+        <result property="shareSchema"    column="share_schema"    />
     </resultMap>
 
     <sql id="selectQwCompanyVo">
-        select id, corp_id, corp_name, open_secret, open_corp_id, server_agent_id, server_book_corp_id, server_book_secret, token, encoding_aes_key, provider_secret, realm_name_url, notify_url, chat_toolbar, chat_toolbar_oauth, company_ids, status, create_time, update_time, create_by,is_buy,mini_app_id,company_server_num,yjfyy_app_id,yjfyy_agent_id,yjfyy_schema from qw_company
+        select id, corp_id, corp_name, open_secret, open_corp_id, server_agent_id, server_book_corp_id, server_book_secret, token, encoding_aes_key, provider_secret, realm_name_url, notify_url, chat_toolbar, chat_toolbar_oauth, company_ids, status, create_time, update_time, create_by,is_buy,mini_app_id,company_server_num,share_app_id,share_agent_id,share_schema from qw_company
     </sql>
 
     <select id="selectQwCompanyList" parameterType="QwCompany" resultMap="QwCompanyResult">
@@ -61,9 +61,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isBuy != null "> and isBuy = #{isBuy}</if>
             <if test="createDeptId != null "> and create_dept_id = #{createDeptId}</if>
             <if test="createUserId != null "> and create_user_id = #{createUserId}</if>
-            <if test="yjfyyAppId != null  and yjfyyAppId != ''"> and yjfyy_app_id = #{yjfyyAppId}</if>
-            <if test="yjfyyAgentId != null  and yjfyyAgentId != ''"> and yjfyy_agent_id = #{yjfyyAgentId}</if>
-            <if test="yjfyySchema != null  and yjfyySchema != ''"> and yjfyy_schema = #{yjfyySchema}</if>
+            <if test="shareAppId != null  and shareAppId != ''"> and share_app_id = #{shareAppId}</if>
+            <if test="shareAgentId != null  and shareAgentId != ''"> and share_agent_id = #{shareAgentId}</if>
+            <if test="shareSchema != null  and shareSchema != ''"> and share_schema = #{shareSchema}</if>
         </where>
     </select>
 
@@ -105,9 +105,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="companyServerNum != null">company_server_num,</if>
             <if test="createUserId != null != null">create_user_id,</if>
             <if test="createDeptId != null">create_dept_id,</if>
-            <if test="yjfyyAppId != null">yjfyy_app_id,</if>
-            <if test="yjfyyAgentId != null">yjfyy_agent_id,</if>
-            <if test="yjfyySchema != null">yjfyy_schema,</if>
+            <if test="shareAppId != null">share_app_id,</if>
+            <if test="shareAgentId != null">share_agent_id,</if>
+            <if test="shareSchema != null">share_schema,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="corpId != null">#{corpId},</if>
@@ -134,9 +134,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="companyServerNum != null">#{companyServerNum},</if>
             <if test="createUserId != null">#{createUserId},</if>
             <if test="createDeptId != null">#{createDeptId},</if>
-            <if test="yjfyyAppId != null">#{yjfyyAppId},</if>
-            <if test="yjfyyAgentId != null">#{yjfyyAgentId},</if>
-            <if test="yjfyySchema != null">#{yjfyySchema},</if>
+            <if test="shareAppId != null">#{shareAppId},</if>
+            <if test="shareAgentId != null">#{shareAgentId},</if>
+            <if test="shareSchema != null">#{shareSchema},</if>
          </trim>
     </insert>
 
@@ -165,9 +165,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isBuy != null">is_buy = #{isBuy},</if>
             <if test="miniAppId != null">mini_app_id = #{miniAppId},</if>
             <if test="companyServerNum != null">company_server_num = #{companyServerNum},</if>
-            <if test="yjfyyAppId != null">yjfyy_app_id = #{yjfyyAppId},</if>
-            <if test="yjfyyAgentId != null">yjfyy_agent_id = #{yjfyyAgentId},</if>
-            <if test="yjfyySchema != null">yjfyy_schema = #{yjfyySchema},</if>
+            <if test="shareAppId != null">share_app_id = #{shareAppId},</if>
+            <if test="shareAgentId != null">share_agent_id = #{shareAgentId},</if>
+            <if test="shareSchema != null">share_schema = #{shareSchema},</if>
         </trim>
         where id = #{id}
     </update>

+ 1 - 1
fs-store/src/main/java/com/fs/store/vo/FsStoreProductStoreExcelVO.java

@@ -155,7 +155,7 @@ public class FsStoreProductStoreExcelVO extends BaseEntity {
     /**
      * 成本价
      */
-    @Excel(name = "成本价")
+    @Excel(name = "成本价")
     private BigDecimal costPrice;