Browse Source

Merge remote-tracking branch 'origin/康年堂' into 康年堂

# Conflicts:
#	fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreHealthOrderScrmController.java
#	fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
yh 2 ngày trước cách đây
mục cha
commit
79b439df07
26 tập tin đã thay đổi với 386 bổ sung95 xóa
  1. 1 1
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreAfterSalesScrmController.java
  2. 1 1
      fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreHealthOrderScrmController.java
  3. 1 1
      fs-admin/src/main/java/com/fs/live/controller/LiveAfterSalesController.java
  4. 2 0
      fs-admin/src/main/java/com/fs/live/controller/OrderController.java
  5. 2 0
      fs-company/src/main/java/com/fs/company/controller/live/OrderController.java
  6. 53 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. 5 4
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java
  11. 8 5
      fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreProductPackageScrmServiceImpl.java
  12. 17 0
      fs-service/src/main/java/com/fs/live/domain/LiveWatchLog.java
  13. 2 0
      fs-service/src/main/java/com/fs/live/mapper/LiveAfterSalesMapper.java
  14. 2 0
      fs-service/src/main/java/com/fs/live/param/MergedOrderQueryParam.java
  15. 2 0
      fs-service/src/main/java/com/fs/live/service/ILiveAfterSalesService.java
  16. 54 0
      fs-service/src/main/java/com/fs/live/service/impl/LiveAfterSalesServiceImpl.java
  17. 3 3
      fs-service/src/main/java/com/fs/qw/domain/QwCompany.java
  18. 5 0
      fs-service/src/main/java/com/fs/sop/params/SendUserLogsInfoMsgParam.java
  19. 23 1
      fs-service/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java
  20. 9 8
      fs-service/src/main/resources/mapper/hisStore/FsStoreProductPackageScrmMapper.xml
  21. 2 2
      fs-service/src/main/resources/mapper/hisStore/FsStoreProductScrmMapper.xml
  22. 9 0
      fs-service/src/main/resources/mapper/hisStore/MergedOrderMapper.xml
  23. 53 0
      fs-service/src/main/resources/mapper/live/LiveAfterSalesMapper.xml
  24. 16 16
      fs-service/src/main/resources/mapper/qw/QwCompanyMapper.xml
  25. 4 2
      fs-user-app/src/main/java/com/fs/app/controller/StoreOrderController.java
  26. 1 1
      fs-user-app/src/main/java/com/fs/app/controller/store/StoreOrderScrmController.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/hisStore/controller/FsStoreHealthOrderScrmController.java

@@ -110,7 +110,7 @@ public class FsStoreHealthOrderScrmController extends BaseController {
             SysRole sysRole = isCheckPermission();
             LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
             for (FsStoreOrderVO vo : list) {
-                if(vo.getPhone()!=null && sysRole.getIsCheckPhone() != 1){
+                if(StringUtils.isNotEmpty(vo.getPhone()) && sysRole.getIsCheckPhone() != 1){
                     vo.setPhone(vo.getPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
                     vo.setUserPhone(vo.getUserPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2"));
                 }

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

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

@@ -83,7 +83,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 +135,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 +145,7 @@ public class WebSocketServer {
                 redisCache.setCacheObject(entryTimeKey, System.currentTimeMillis(), 24, TimeUnit.HOURS);
             }
             // 如果是重连,不覆盖进入时间,保持原来的进入时间以便正确计算总时长
-            
+
             // 直播间浏览量 +1
             redisCache.incr(PAGE_VIEWS_KEY + liveId, 1);
 
@@ -353,7 +353,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 +371,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 +399,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 +744,7 @@ public class WebSocketServer {
      */
     public void broadcastWebMessage(Long liveId, String message) {
         ConcurrentHashMap<Long, Session> room = getRoom(liveId);
-        
+
         if (room.isEmpty()) {
             return;
         }
@@ -867,7 +870,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 +882,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 +957,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 +1122,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 +1155,7 @@ public class WebSocketServer {
                 }
                 liveWatchUser.setOnlineSeconds(onlineSeconds + durationSeconds);
                 liveWatchUser.setUpdateTime(now);
-                
+
                 // 更新数据库
                 liveWatchUserService.updateLiveWatchUserEntry(liveWatchUser);
                 // 如果 LiveWatchUserEntry 存在,并且当前是直播状态(liveFlag = 1),更新 LiveWatchLog
@@ -1164,15 +1167,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 +1186,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 +1198,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 +1215,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 +1254,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 +1267,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 +1278,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 +1291,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 +1303,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 +1318,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 +1336,7 @@ public class WebSocketServer {
                     log.setFinishTime(now);
                     needUpdate = true;
                 }
-                
+
                 // 如果 logType 已经是 2(完课),不再更新
                 if (needUpdate && (log.getLogType() == null || log.getLogType() != 2)) {
                     log.setLogType(newLogType);
@@ -1341,7 +1344,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);
         }
     }

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

@@ -554,6 +554,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) {

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

@@ -722,8 +722,8 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             }
         }
         String uuid = IdUtil.randomUUID();
-        redisCache.setCacheObject("orderKey:" + uuid, cartParam.getCartIds(), 300, TimeUnit.SECONDS);
-        redisCache.setCacheObject("orderCarts:" + uuid, carts, 300, TimeUnit.SECONDS);
+        redisCache.setCacheObject("orderKey:" + uuid, cartParam.getCartIds(), 2, TimeUnit.DAYS);
+        redisCache.setCacheObject("orderCarts:" + uuid, carts, 2, TimeUnit.DAYS);
         return R.ok().put("orderKey", uuid).put("address", address).put("carts", carts);
 
     }
@@ -3721,7 +3721,8 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
                         throw new CustomException("不是本公司订单");
                     }
                 }
-                if (o.getStatus() != 2) {
+                //商城待发货状态为1
+                if (o.getStatus() != 1) {
                     throw new CustomException("订单状态不为待发货");
                 }
                 // 判断每个字段是否为null或为空字符串
@@ -4739,7 +4740,7 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         }
         String orderId=redisCache.getCacheObject("isPaying:"+order.getId());
         if(StringUtils.isNotEmpty(orderId)&&orderId.equals(order.getId().toString())){
-            return R.error("正在支付中...");
+            return R.error("请30s后重试...");
         }
         List<FsStorePaymentScrm>  payments=fsStorePaymentMapper.selectFsStorePaymentByOrder(order.getId());
         if(CollectionUtils.isNotEmpty(payments)){

+ 8 - 5
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreProductPackageScrmServiceImpl.java

@@ -1,6 +1,7 @@
 package com.fs.hisStore.service.impl;
 
 import java.util.*;
+import java.util.stream.Collectors;
 
 import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONUtil;
@@ -212,7 +213,7 @@ public class FsStoreProductPackageScrmServiceImpl implements IFsStoreProductPack
     @Override
     public int updateFsStoreProductPackagesByCompany(Long[] packageIds, Long status, Long[] companyIds) {
         //判断套餐商品所属公司
-        Set<String> companySet = new LinkedHashSet<>();
+        Set<Long> companySet = new LinkedHashSet<>();
         List<FsStoreProductPackageScrm> list = fsStoreProductPackageMapper.selectFsPackageListByIds(packageIds);
         if (list != null && !list.isEmpty()) {
             List<Long> productIds = new ArrayList<>();
@@ -222,11 +223,13 @@ public class FsStoreProductPackageScrmServiceImpl implements IFsStoreProductPack
                     List<StorePackageProductDTO> dtos = JSON.parseArray(products, StorePackageProductDTO.class);
                     if (dtos != null && !dtos.isEmpty()) {
                         dtos.forEach(dto -> {
-                            productIds.add(dto.getId());
+                            FsStoreProductAttrValueScrm attrValue=fsStoreProductAttrValueMapper.selectFsStoreProductAttrValueById(dto.getId());
+                            if (attrValue != null) {
+                                productIds.add(attrValue.getProductId());
+                            }
                         });
                     }
                 }
-
             }
             if (!productIds.isEmpty()) {
                 List<FsStoreProductScrm> productScrmList = fsStoreProductMapper.getStoreProductInProductIds(productIds);
@@ -234,7 +237,7 @@ public class FsStoreProductPackageScrmServiceImpl implements IFsStoreProductPack
                     productScrmList.forEach(fsStoreProductScrm -> {
                         String companyIdsTemp = fsStoreProductScrm.getCompanyIds();
                         if (StringUtils.isNotBlank(companyIdsTemp)) {
-                            List<String> companyIdList = Arrays.asList(companyIdsTemp.split(","));
+                            List<Long> companyIdList = Arrays.stream(companyIdsTemp.split(",")).map(Long::valueOf).collect(Collectors.toList());
                             if (!companyIdList.isEmpty()) {
                                 companySet.addAll(companyIdList);
                             }
@@ -246,7 +249,7 @@ public class FsStoreProductPackageScrmServiceImpl implements IFsStoreProductPack
         StringBuilder companyIdsStr = new StringBuilder();
         if (companyIds != null && companyIds.length>0){
             for (Long companyId : companyIds) {
-                if (!companySet.contains(companyId.toString())) {
+                if (!companySet.contains(companyId)) {
                     return 0;
                 }
                 companyIdsStr.append(companyId).append(",");

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

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

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

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

+ 9 - 8
fs-service/src/main/resources/mapper/hisStore/FsStoreProductPackageScrmMapper.xml

@@ -172,14 +172,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </foreach>
     </update>
     <update id="updateFsStoreProductPackagesByCompany">
-        update  fs_store_product_package_scrm set
-        <if test="status != null">
-            status = #{status},
-        </if>
-
-        <if test="companyIds !=null">
-            company_ids = #{companyIds},
-        </if>
+        update  fs_store_product_package_scrm
+        <trim prefix="set" suffixOverrides=",">
+            <if test="status != null">
+                status = #{status},
+            </if>
+            <if test="companyIds != null">
+                company_ids = #{companyIds},
+            </if>
+        </trim>
         where package_id in
         <foreach item="packageId" collection="packageIds" open="(" separator="," close=")">
             #{packageId}

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

+ 4 - 2
fs-user-app/src/main/java/com/fs/app/controller/StoreOrderController.java

@@ -5,6 +5,7 @@ import com.fs.app.annotation.Login;
 
 import com.fs.common.utils.CloudHostUtils;
 import com.fs.his.dto.ExpressInfoDTO;
+import com.fs.his.enums.FsStoreOrderStatusEnum;
 import com.fs.his.param.BillListParam;
 import com.fs.app.param.FsStoreOrderExpressParam;
 import com.fs.app.param.FsStoreOrderFinishParam;
@@ -18,6 +19,7 @@ import com.fs.his.param.*;
 import com.fs.his.service.*;
 import com.fs.his.vo.FsStoreOrderItemListUVO;
 import com.fs.his.vo.FsStoreOrderListUVO;
+import com.fs.hisStore.enums.OrderInfoEnum;
 import com.fs.ybPay.service.IPayService;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
@@ -87,7 +89,7 @@ public class StoreOrderController extends  AppBaseController {
         SimpleDateFormat format = new   SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         String payLimitTime = format.format(calendar.getTime() );
         //处理是否可以申请售后
-        Integer isAfterSales=0;
+        Integer isAfterSales=1;
 //        if(order.getStatus().equals(FsStoreOrderStatusEnum.STATUS_4.getValue())) {
 //            //已完成订单
 //            isAfterSales=1;
@@ -106,7 +108,7 @@ public class StoreOrderController extends  AppBaseController {
 //        else if(order.getStatus()==2||order.getStatus()==3){
 //            isAfterSales=1;
 //        }
-        return R.ok().put("order",order).put("items",list).put("payLimitTime",payLimitTime);
+        return R.ok().put("order",order).put("items",list).put("payLimitTime",payLimitTime).put("isAfterSales",isAfterSales);
     }
 
     @Login

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

@@ -324,7 +324,7 @@ public class StoreOrderScrmController extends AppBaseController {
         RLock lock = redissonClient.getLock(String.format(LOCK_KEY_EDIT_PAY_TYPE,orderId));
         R result = null;
         try {
-            boolean locked = lock.tryLock(100, 10000, TimeUnit.MILLISECONDS);
+            boolean locked = lock.tryLock(100, 30000, TimeUnit.MILLISECONDS);
             if (!locked) {
                 logger.warn("订单支付类型正在修改中,获取锁失败, 订单号: {}", orderId);
                 return R.error("订单正在处理中,请勿重复提交");