Browse Source

1、调整发送红包,抽奖问题

yys 1 week ago
parent
commit
90a318316a

+ 26 - 2
fs-live-app/src/main/java/com/fs/live/task/LiveCompletionPointsTask.java

@@ -3,6 +3,7 @@ package com.fs.live.task;
 import com.alibaba.fastjson.JSONObject;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
+import com.fs.common.utils.StringUtils;
 import com.fs.live.domain.Live;
 import com.fs.live.domain.LiveCompletionPointsRecord;
 import com.fs.live.domain.LiveConsoleOpLog;
@@ -10,6 +11,7 @@ import com.fs.live.service.ILiveCompletionCouponService;
 import com.fs.live.service.ILiveCompletionPointsRecordService;
 import com.fs.live.service.ILiveConsoleOpLogService;
 import com.fs.live.service.ILiveService;
+import com.fs.live.vo.LiveCompletionCouponInfoVO;
 import com.fs.live.vo.LiveCompletionCouponNotifyResult;
 import com.fs.live.websocket.bean.SendMsgVo;
 import com.fs.live.websocket.service.WebSocketServer;
@@ -71,7 +73,7 @@ public class LiveCompletionPointsTask {
                             LiveConsoleOpLog.OP_COMPLETION_POINTS,
                             LiveConsoleOpLog.HANDLE_AUTO,
                             record.getId(),
-                            "完课积分" + record.getPointsAwarded() + "分"
+                            resolveCompletionPointsBizName(record)
                     );
                     liveConsoleOpLogService.bindOpLogUser(opLog.getId(), liveId, userId);
                 }
@@ -102,7 +104,7 @@ public class LiveCompletionPointsTask {
                 if (notifyResult == null || !notifyResult.isShouldNotify()) {
                     return;
                 }
-                String bizName = notifyResult.getCoupon() != null ? notifyResult.getCoupon().getTitle() : "完课优惠券";
+                String bizName = resolveCompletionCouponBizName(notifyResult);
                 Long bizId = notifyResult.getCoupon() != null ? notifyResult.getCoupon().getCouponId() : null;
                 LiveConsoleOpLog opLog = liveConsoleOpLogService.saveLog(
                         liveId,
@@ -194,4 +196,26 @@ public class LiveCompletionPointsTask {
     private interface CompletionHandler {
         void handle(Long liveId, Long userId, Long duration);
     }
+
+    private String resolveCompletionPointsBizName(LiveCompletionPointsRecord record) {
+        if (record == null) {
+            return "完课积分";
+        }
+        Integer points = record.getPointsAwarded();
+        if (points != null) {
+            return "完课积分" + points + "分";
+        }
+        return record.getId() != null ? "完课积分 #" + record.getId() : "完课积分";
+    }
+
+    private String resolveCompletionCouponBizName(LiveCompletionCouponNotifyResult notifyResult) {
+        if (notifyResult == null || notifyResult.getCoupon() == null) {
+            return "完课优惠券";
+        }
+        LiveCompletionCouponInfoVO coupon = notifyResult.getCoupon();
+        if (StringUtils.isNotEmpty(coupon.getTitle())) {
+            return coupon.getTitle();
+        }
+        return coupon.getCouponId() != null ? "完课优惠券 #" + coupon.getCouponId() : "完课优惠券";
+    }
 }

+ 40 - 6
fs-live-app/src/main/java/com/fs/live/task/Task.java

@@ -370,12 +370,11 @@ public class Task {
             sendMsgVo.setLiveId(liveLottery.getLiveId());
             sendMsgVo.setCmd("LotteryDetail");
             sendMsgVo.setData(JSON.toJSONString(lotteryVos));
-            WebSocketServer.attachOpLog(sendMsgVo, liveConsoleOpLogService.saveLog(
+            WebSocketServer.attachOpLog(sendMsgVo, liveConsoleOpLogService.saveLotterySettleLog(
                     liveLottery.getLiveId(),
-                    LiveConsoleOpLog.OP_LOTTERY_SETTLE,
                     LiveConsoleOpLog.HANDLE_AUTO,
                     liveLottery.getLotteryId(),
-                    liveLottery.getDesc()
+                    resolveLotteryBizName(liveLottery.getLotteryId(), liveLottery.getDesc())
             ));
             webSocketServer.broadcastMessage(liveLottery.getLiveId(), JSONObject.toJSONString(R.ok().put("data", sendMsgVo)));
 
@@ -485,7 +484,7 @@ public class Task {
                             LiveConsoleOpLog.OP_WATCH_REWARD_POINTS,
                             LiveConsoleOpLog.HANDLE_AUTO,
                             openRewardLive.getLiveId(),
-                            "观看奖励积分" + config.getScoreAmount() + "分,发放" + userIds.size() + "人"
+                            resolveWatchRewardPointsBizName(config, userIds.size())
                     );
                     userIds.forEach(userId -> webSocketServer.sendIntegralMessage(
                             openRewardLive.getLiveId(), userId, config.getScoreAmount(), watchPointsOpLog));
@@ -502,13 +501,12 @@ public class Task {
                     LiveCoupon watchRewardCoupon = liveCouponService.selectLiveCouponById(actionCouponId);
                     List<LiveConsoleOpLogUser> couponRelations = bindCouponToUsers(openRewardLive, userIds, actionCouponId, false);
                     if (!couponRelations.isEmpty()) {
-                        String couponTitle = watchRewardCoupon != null ? watchRewardCoupon.getTitle() : "观看奖励优惠券";
                         LiveConsoleOpLog watchCouponOpLog = liveConsoleOpLogService.saveLog(
                                 openRewardLive.getLiveId(),
                                 LiveConsoleOpLog.OP_WATCH_REWARD_COUPON,
                                 LiveConsoleOpLog.HANDLE_AUTO,
                                 actionCouponId,
-                                couponTitle + ",发放" + couponRelations.size() + "人"
+                                resolveWatchRewardCouponBizName(watchRewardCoupon, actionCouponId, couponRelations.size())
                         );
                         liveConsoleOpLogService.bindOpLogUsers(
                                 watchCouponOpLog.getId(), openRewardLive.getLiveId(), couponRelations);
@@ -1371,4 +1369,40 @@ public class Task {
 //            log.error("批量同步观看时长任务异常", e);
 //        }
 //    }
+
+    private String resolveLotteryBizName(Long lotteryId, String desc) {
+        if (StringUtils.isNotEmpty(desc)) {
+            return desc;
+        }
+        if (lotteryId != null) {
+            LiveLotteryConf conf = liveLotteryConfService.selectLiveLotteryConfByLotteryId(lotteryId);
+            if (conf != null && StringUtils.isNotEmpty(conf.getDesc())) {
+                return conf.getDesc();
+            }
+            return "抽奖 #" + lotteryId;
+        }
+        return "抽奖";
+    }
+
+    private String resolveWatchRewardPointsBizName(LiveWatchConfig config, int userCount) {
+        Long amount = config != null ? config.getScoreAmount() : null;
+        String amountText = amount != null ? String.valueOf(amount) : "0";
+        return "观看奖励积分" + amountText + "分,发放" + userCount + "人";
+    }
+
+    private String resolveWatchRewardCouponBizName(LiveCoupon coupon, Long couponId, int userCount) {
+        String title = null;
+        if (coupon != null && StringUtils.isNotEmpty(coupon.getTitle())) {
+            title = coupon.getTitle();
+        } else if (couponId != null) {
+            LiveCoupon loaded = liveCouponService.selectLiveCouponById(couponId);
+            if (loaded != null && StringUtils.isNotEmpty(loaded.getTitle())) {
+                title = loaded.getTitle();
+            }
+        }
+        if (StringUtils.isEmpty(title)) {
+            title = couponId != null ? "观看奖励优惠券 #" + couponId : "观看奖励优惠券";
+        }
+        return title + ",发放" + userCount + "人";
+    }
 }

+ 83 - 48
fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java

@@ -720,57 +720,75 @@ public class WebSocketServer {
     }
 
     /**
-     * 中控台红包操作留存(发放 / 结算)
+     * 中控台红包:仅结算时挂载 REST/定时任务已写入的留存,不在 WebSocket 侧新建记录
      */
     private LiveConsoleOpLog saveConsoleRedOpLog(Long liveId, LiveRedConf liveRedConf, Integer status) {
         if (liveRedConf == null || status == null) {
             return null;
         }
-        if (status == 1) {
-            return liveConsoleOpLogService.saveLog(
-                    liveId,
-                    LiveConsoleOpLog.OP_RED_SEND,
-                    LiveConsoleOpLog.HANDLE_CONSOLE,
-                    liveRedConf.getRedId(),
-                    liveRedConf.getDesc()
-            );
-        }
         if (status == 2 || status == -1) {
-            return liveConsoleOpLogService.saveLog(
-                    liveId,
-                    LiveConsoleOpLog.OP_RED_SETTLE,
-                    LiveConsoleOpLog.HANDLE_CONSOLE,
-                    liveRedConf.getRedId(),
-                    liveRedConf.getDesc()
-            );
+            return findRecentRedSettleOpLog(liveId, liveRedConf.getRedId());
         }
         return null;
     }
 
     /**
-     * 中控台抽奖操作留存(发放 / 结算)
+     * 查询 REST 结算接口刚写入的红包结算留存,供 WebSocket 挂载 opLog
+     */
+    private LiveConsoleOpLog findRecentRedSettleOpLog(Long liveId, Long redId) {
+        LiveConsoleOpLog query = new LiveConsoleOpLog();
+        query.setLiveId(liveId);
+        query.setBizId(redId);
+        List<LiveConsoleOpLog> list = liveConsoleOpLogService.selectLiveConsoleOpLogList(query);
+        if (list == null || list.isEmpty()) {
+            return null;
+        }
+        long now = System.currentTimeMillis();
+        for (LiveConsoleOpLog item : list) {
+            if (item.getCreateTime() == null
+                    || !Objects.equals(item.getOpType(), LiveConsoleOpLog.OP_RED_SETTLE)) {
+                continue;
+            }
+            if (now - item.getCreateTime().getTime() <= 30000) {
+                return item;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 中控台抽奖:仅结算时挂载 REST 已写入的留存,不在 WebSocket 侧新建记录
      */
     private LiveConsoleOpLog saveConsoleLotteryOpLog(Long liveId, LiveLotteryConf liveLotteryConf, Integer status) {
         if (liveLotteryConf == null || status == null) {
             return null;
         }
-        if (status == 1) {
-            return liveConsoleOpLogService.saveLog(
-                    liveId,
-                    LiveConsoleOpLog.OP_LOTTERY_SEND,
-                    LiveConsoleOpLog.HANDLE_CONSOLE,
-                    liveLotteryConf.getLotteryId(),
-                    liveLotteryConf.getDesc()
-            );
-        }
         if (status == 2 || status == -1) {
-            return liveConsoleOpLogService.saveLog(
-                    liveId,
-                    LiveConsoleOpLog.OP_LOTTERY_SETTLE,
-                    LiveConsoleOpLog.HANDLE_CONSOLE,
-                    liveLotteryConf.getLotteryId(),
-                    liveLotteryConf.getDesc()
-            );
+            return findRecentLotterySettleOpLog(liveId, liveLotteryConf.getLotteryId());
+        }
+        return null;
+    }
+
+    /**
+     * 查询 REST 结算接口刚写入的抽奖结算留存,供 WebSocket 挂载 opLog
+     */
+    private LiveConsoleOpLog findRecentLotterySettleOpLog(Long liveId, Long lotteryId) {
+        LiveConsoleOpLog query = new LiveConsoleOpLog();
+        query.setLiveId(liveId);
+        query.setBizId(lotteryId);
+        List<LiveConsoleOpLog> list = liveConsoleOpLogService.selectLiveConsoleOpLogList(query);
+        if (list == null || list.isEmpty()) {
+            return null;
+        }
+        long now = System.currentTimeMillis();
+        for (LiveConsoleOpLog item : list) {
+            if (item.getCreateTime() == null
+                    || !Objects.equals(item.getOpType(), LiveConsoleOpLog.OP_LOTTERY_SETTLE)) {
+                continue;
+            }
+            if (now - item.getCreateTime().getTime() <= 30000) {
+                return item;
+            }
         }
         return null;
     }
@@ -782,6 +800,10 @@ public class WebSocketServer {
         if (status == null || status != 1 || couponIssueId == null) {
             return null;
         }
+        LiveConsoleOpLog recent = findRecentCouponShowOpLog(liveId, couponIssueId);
+        if (recent != null) {
+            return recent;
+        }
         LiveCouponIssue liveCouponIssue = liveCouponIssueService.selectLiveCouponIssueById(couponIssueId);
         if (liveCouponIssue == null || liveCouponIssue.getCouponId() == null) {
             return null;
@@ -795,6 +817,33 @@ public class WebSocketServer {
         );
     }
 
+    /**
+     * 中控台展示券时 REST 已写入留存,WebSocket 复用近期记录避免重复插入
+     */
+    private LiveConsoleOpLog findRecentCouponShowOpLog(Long liveId, Long couponIssueId) {
+        LiveConsoleOpLog query = new LiveConsoleOpLog();
+        query.setLiveId(liveId);
+        query.setBizId(couponIssueId);
+        List<LiveConsoleOpLog> list = liveConsoleOpLogService.selectLiveConsoleOpLogList(query);
+        if (list == null || list.isEmpty()) {
+            return null;
+        }
+        LiveConsoleOpLog latest = list.get(0);
+        if (latest.getCreateTime() == null) {
+            return null;
+        }
+        long ageMs = System.currentTimeMillis() - latest.getCreateTime().getTime();
+        if (ageMs > 5000) {
+            return null;
+        }
+        Integer opType = latest.getOpType();
+        if (opType != null
+                && (opType == LiveConsoleOpLog.OP_COUPON_SHOW || opType == LiveConsoleOpLog.OP_VERIFY_COUPON_SHOW)) {
+            return latest;
+        }
+        return null;
+    }
+
     //错误时调用
     @OnError
     public void onError(Session session, Throwable throwable) {
@@ -1374,13 +1423,6 @@ public class WebSocketServer {
                 liveRedConf.setUpdateTime( now);
                 msg.setData(JSON.toJSONString(liveRedConf));
                 liveRedConfService.updateLiveRedConf(liveRedConf);
-                attachOpLog(msg, liveConsoleOpLogService.saveLog(
-                        task.getLiveId(),
-                        LiveConsoleOpLog.OP_RED_SEND,
-                        LiveConsoleOpLog.HANDLE_AUTO,
-                        liveRedConf.getRedId(),
-                        liveRedConf.getDesc()
-                ));
                 liveService.asyncToCacheLiveConfig(task.getLiveId());
             }else if (task.getTaskType() == 4L) {
                 msg.setCmd("lottery");
@@ -1393,13 +1435,6 @@ public class WebSocketServer {
                 liveLotteryConf.setUpdateTime( now);
                 msg.setData(JSON.toJSONString(liveLotteryConf));
                 liveLotteryConfService.updateLiveLotteryConf(liveLotteryConf);
-                attachOpLog(msg, liveConsoleOpLogService.saveLog(
-                        task.getLiveId(),
-                        LiveConsoleOpLog.OP_LOTTERY_SEND,
-                        LiveConsoleOpLog.HANDLE_AUTO,
-                        liveLotteryConf.getLotteryId(),
-                        liveLotteryConf.getDesc()
-                ));
                 liveService.asyncToCacheLiveConfig(task.getLiveId());
             }else if (task.getTaskType() == 3L) {
                 msg.setCmd("sendMsg");

+ 12 - 2
fs-service/src/main/java/com/fs/live/service/ILiveConsoleOpLogService.java

@@ -8,7 +8,7 @@ import com.fs.live.vo.LiveConsoleOpLogRecordVo;
 import java.util.List;
 
 /**
- * 鐩存挱涓�帶鍙版搷浣滅暀瀛� Service
+ * 直播??控台操作留存 Service
  */
 public interface ILiveConsoleOpLogService {
 
@@ -16,6 +16,16 @@ public interface ILiveConsoleOpLogService {
 
     LiveConsoleOpLog saveLog(Long liveId, Integer opType, Integer handleType, Long bizId, String bizName);
 
+    /**
+     * ?齱???????棺???齱??д?????????????÷??????м??
+     */
+    LiveConsoleOpLog saveLotterySettleLog(Long liveId, Integer handleType, Long lotteryId, String bizName);
+
+    /**
+     * \u7ea2\u5305\u7ed3\u7b97\u7559\u5b58\uff1a\u540c\u4e00\u7ea2\u5305\u4ec5\u5199\u5165\u4e00\u6761\uff0c\u91cd\u590d\u8c03\u7528\u8fd4\u56de\u5df2\u6709\u8bb0\u5f55
+     */
+    LiveConsoleOpLog saveRedSettleLog(Long liveId, Integer handleType, Long redId, String bizName);
+
     LiveConsoleOpLog saveCouponShowLog(Long liveId, Long couponIssueId, LiveCoupon coupon, Integer handleType);
 
     void bindOpLogUsers(Long opLogId, Long liveId, List<LiveConsoleOpLogUser> relations);
@@ -27,7 +37,7 @@ public interface ILiveConsoleOpLogService {
     void bindOpLogUser(Long opLogId, Long liveId, Long userId, Long couponUserId);
 
     /**
-     * 鏌ヨ�鐢ㄦ埛鍦ㄦ寚瀹氱洿鎾�棿鐨勭暀瀛樿�褰曪紙鍚��鍙�/缁撴潫鐘舵€侊級
+     * 查???用户在指定直播间的留存记录(含领取/结束状态)
      */
     List<LiveConsoleOpLogRecordVo> listUserOpLogRecords(Long liveId, Long userId);
 }

+ 50 - 4
fs-service/src/main/java/com/fs/live/service/impl/LiveConsoleOpLogServiceImpl.java

@@ -9,10 +9,12 @@ import com.fs.live.domain.LiveConsoleOpLog;
 import com.fs.live.domain.LiveConsoleOpLogUser;
 import com.fs.live.domain.LiveCoupon;
 import com.fs.live.domain.LiveCouponIssue;
+import com.fs.live.domain.LiveCouponIssueRelation;
 import com.fs.live.domain.LiveLotteryConf;
 import com.fs.live.domain.LiveRedConf;
 import com.fs.live.mapper.LiveConsoleOpLogMapper;
 import com.fs.live.mapper.LiveConsoleOpLogUserMapper;
+import com.fs.live.mapper.LiveCouponMapper;
 import com.fs.live.service.ILiveConsoleOpLogService;
 import com.fs.live.service.ILiveCouponIssueService;
 import com.fs.live.service.ILiveLotteryConfService;
@@ -38,8 +40,10 @@ import java.util.stream.Collectors;
 @Service
 public class LiveConsoleOpLogServiceImpl implements ILiveConsoleOpLogService {
 
-    /** 运营自动化默认操作人名称 */
+    /** 运营自动化场景默认操作人 */
     private static final String AUTO_OPERATOR_NAME = "运营自动化";
+    /** 中控台 WebSocket 无登录上下文时的默认操作人 */
+    private static final String CONSOLE_OPERATOR_NAME = "中控台";
 
     @Autowired
     private LiveConsoleOpLogMapper liveConsoleOpLogMapper;
@@ -56,6 +60,9 @@ public class LiveConsoleOpLogServiceImpl implements ILiveConsoleOpLogService {
     @Autowired
     private ILiveCouponIssueService liveCouponIssueService;
 
+    @Autowired
+    private LiveCouponMapper liveCouponMapper;
+
     @Override
     public List<LiveConsoleOpLog> selectLiveConsoleOpLogList(LiveConsoleOpLog liveConsoleOpLog) {
         return liveConsoleOpLogMapper.selectLiveConsoleOpLogList(liveConsoleOpLog);
@@ -77,15 +84,50 @@ public class LiveConsoleOpLogServiceImpl implements ILiveConsoleOpLogService {
                 log.setOperatorName(loginUser.getUser().getNickName());
             }
         } catch (Exception ignored) {
-            // 定时任务等非 Web 上下文无登录用户
+            // 中控台 WebSocket 等场景可能无登录上下文
         }
         if (LiveConsoleOpLog.HANDLE_AUTO == handleType && StringUtils.isEmpty(log.getOperatorName())) {
             log.setOperatorName(AUTO_OPERATOR_NAME);
         }
+        if (LiveConsoleOpLog.HANDLE_CONSOLE == handleType && StringUtils.isEmpty(log.getOperatorName())) {
+            log.setOperatorName(CONSOLE_OPERATOR_NAME);
+        }
         liveConsoleOpLogMapper.insertLiveConsoleOpLog(log);
         return log;
     }
 
+    @Override
+    public LiveConsoleOpLog saveLotterySettleLog(Long liveId, Integer handleType, Long lotteryId, String bizName) {
+        if (liveId == null || lotteryId == null) {
+            return null;
+        }
+        LiveConsoleOpLog query = new LiveConsoleOpLog();
+        query.setLiveId(liveId);
+        query.setBizId(lotteryId);
+        query.setOpType(LiveConsoleOpLog.OP_LOTTERY_SETTLE);
+        List<LiveConsoleOpLog> existing = liveConsoleOpLogMapper.selectLiveConsoleOpLogList(query);
+        if (!CollectionUtils.isEmpty(existing)) {
+            return existing.get(0);
+        }
+        return saveLog(liveId, LiveConsoleOpLog.OP_LOTTERY_SETTLE, handleType, lotteryId, bizName);
+    }
+
+    @Override
+    public LiveConsoleOpLog saveRedSettleLog(Long liveId, Integer handleType, Long redId, String bizName) {
+        if (liveId == null || redId == null) {
+            return null;
+        }
+        LiveConsoleOpLog query = new LiveConsoleOpLog();
+        query.setLiveId(liveId);
+        query.setBizId(redId);
+        query.setOpType(LiveConsoleOpLog.OP_RED_SETTLE);
+        List<LiveConsoleOpLog> existing = liveConsoleOpLogMapper.selectLiveConsoleOpLogList(query);
+        if (!CollectionUtils.isEmpty(existing)) {
+            return existing.get(0);
+        }
+        return saveLog(liveId, LiveConsoleOpLog.OP_RED_SETTLE, handleType, redId, bizName);
+    }
+
     @Override
     public LiveConsoleOpLog saveCouponShowLog(Long liveId, Long couponIssueId, LiveCoupon coupon, Integer handleType) {
         int opType = isVerifyCouponType(coupon)
@@ -250,6 +292,10 @@ public class LiveConsoleOpLogServiceImpl implements ILiveConsoleOpLogService {
         switch (opType) {
             case LiveConsoleOpLog.OP_COUPON_SHOW:
             case LiveConsoleOpLog.OP_VERIFY_COUPON_SHOW:
+                LiveCouponIssueRelation showRelation = liveCouponMapper.selectRelation(opLog.getLiveId(), bizId);
+                if (showRelation == null || showRelation.getIsShow() == null || showRelation.getIsShow() != 1) {
+                    return true;
+                }
                 LiveCouponIssue issue = liveCouponIssueService.selectLiveCouponIssueById(bizId);
                 return issue == null
                         || issue.getStatus() == null
@@ -269,7 +315,7 @@ public class LiveConsoleOpLogServiceImpl implements ILiveConsoleOpLogService {
     }
 
     /**
-     * 判断是否为核销券 / 核销代金券类型
+     * 判断是否为核销券 / 核销优惠券类型
      */
     private boolean isVerifyCouponType(LiveCoupon coupon) {
         if (coupon == null || coupon.getType() == null) {
@@ -282,4 +328,4 @@ public class LiveConsoleOpLogServiceImpl implements ILiveConsoleOpLogService {
         return StringUtils.isNotEmpty(typeLabel)
                 && (typeLabel.contains("核销") || typeLabel.contains("核销券"));
     }
-}
+}

+ 15 - 9
fs-service/src/main/java/com/fs/live/service/impl/LiveCouponServiceImpl.java

@@ -225,24 +225,30 @@ public class LiveCouponServiceImpl implements ILiveCouponService
         Live live = liveMapper.selectLiveByLiveId(liveId);
         if(live == null) return R.error("直播间不存在");
         boolean isShow = Boolean.parseBoolean(payload.get("isShow").toString());
-        if (isShow) {
-            int i = liveCouponMapper.selectShowByLiveId(liveId);
-            if (i > 0) return R.error("直播间已存在优惠券");
+        Long couponIssueId = Long.valueOf(payload.get("couponId").toString());
+        LiveCouponIssueRelation liveCouponIssueRelation = liveCouponMapper.selectRelation(liveId, couponIssueId);
+        if (liveCouponIssueRelation == null) {
+            return R.error("优惠券未关联到直播间");
         }
-        Long couponId = Long.valueOf(payload.get("couponId").toString());
-        LiveCouponIssueRelation liveCouponIssueRelation = liveCouponMapper.selectRelation(liveId,couponId);
 
-        // 查询优惠券类型
-        LiveCoupon liveCoupon = liveCouponMapper.selectLiveCouponById(couponId);
+        LiveCouponIssue couponIssue = liveCouponIssueMapper.selectLiveCouponIssueById(couponIssueId);
+        if (couponIssue == null || couponIssue.getCouponId() == null) {
+            return R.error("优惠券不存在");
+        }
+        LiveCoupon liveCoupon = liveCouponMapper.selectLiveCouponById(couponIssue.getCouponId());
 
         // 如果不是核销券/无门槛券,需要检查是否绑定了商品
         if (!isVerifyCouponType(liveCoupon) && ObjectUtil.isEmpty(liveCouponIssueRelation.getGoodsId())) {
             return R.error("未绑定商品,无法发布!");
         }
 
-        liveCouponMapper.updateShow(liveId, couponId, isShow ? 1 : 0);
         if (isShow) {
-            liveConsoleOpLogService.saveCouponShowLog(liveId, couponId, liveCoupon, LiveConsoleOpLog.HANDLE_CONSOLE);
+            // updateChangeShow 会自动收起其它券,仅保留当前展示的一张
+            liveCouponMapper.updateChangeShow(liveId, couponIssueId);
+            liveConsoleOpLogService.saveCouponShowLog(
+                    liveId, couponIssueId, liveCoupon, LiveConsoleOpLog.HANDLE_CONSOLE);
+        } else {
+            liveCouponMapper.updateShow(liveId, couponIssueId, 0);
         }
         return R.ok("操作成功");
     }

+ 11 - 3
fs-service/src/main/java/com/fs/live/service/impl/LiveLotteryConfServiceImpl.java

@@ -4,6 +4,7 @@ package com.fs.live.service.impl;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.StringUtils;
 import com.fs.live.domain.LiveConsoleOpLog;
 import com.fs.live.domain.LiveLotteryConf;
 import com.fs.live.domain.LiveLotteryRegistration;
@@ -120,17 +121,24 @@ public class LiveLotteryConfServiceImpl implements ILiveLotteryConfService {
         }
         int rows = baseMapper.updateLiveLotteryConf(liveLotteryConf);
         if ("2".equals(liveLotteryConf.getLotteryStatus())) {
-            liveConsoleOpLogService.saveLog(
+            LiveLotteryConf persisted = baseMapper.selectLiveLotteryConfByLotteryId(liveLotteryConf.getLotteryId());
+            liveConsoleOpLogService.saveLotterySettleLog(
                     liveLotteryConf.getLiveId(),
-                    LiveConsoleOpLog.OP_LOTTERY_SETTLE,
                     LiveConsoleOpLog.HANDLE_CONSOLE,
                     liveLotteryConf.getLotteryId(),
-                    liveLotteryConf.getDesc()
+                    resolveLotteryBizName(persisted)
             );
         }
         return R.ok().put("data", rows);
     }
 
+    private String resolveLotteryBizName(LiveLotteryConf conf) {
+        if (conf != null && StringUtils.isNotEmpty(conf.getDesc())) {
+            return conf.getDesc();
+        }
+        return conf != null && conf.getLotteryId() != null ? "抽奖 #" + conf.getLotteryId() : "抽奖";
+    }
+
     /**
      * 批量删除直播抽奖配置
      *

+ 13 - 6
fs-service/src/main/java/com/fs/live/service/impl/LiveRedConfServiceImpl.java

@@ -8,6 +8,7 @@ import com.fs.common.constant.LiveKeysConstant;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.StringUtils;
 import com.fs.his.domain.FsUserIntegralLogs;
 import com.fs.his.enums.FsUserIntegralLogTypeEnum;
 import com.fs.his.mapper.FsUserIntegralLogsMapper;
@@ -149,17 +150,24 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
         }
         int rows = baseMapper.updateLiveRedConf(liveRedConf);
         if (liveRedConf.getRedStatus() != null && liveRedConf.getRedStatus() == 2L) {
-            liveConsoleOpLogService.saveLog(
+            LiveRedConf persisted = baseMapper.selectLiveRedConfByRedId(liveRedConf.getRedId());
+            liveConsoleOpLogService.saveRedSettleLog(
                     liveRedConf.getLiveId(),
-                    LiveConsoleOpLog.OP_RED_SETTLE,
                     LiveConsoleOpLog.HANDLE_CONSOLE,
                     liveRedConf.getRedId(),
-                    liveRedConf.getDesc()
+                    resolveRedBizName(persisted)
             );
         }
         return rows;
     }
 
+    private String resolveRedBizName(LiveRedConf conf) {
+        if (conf != null && StringUtils.isNotEmpty(conf.getDesc())) {
+            return conf.getDesc();
+        }
+        return conf != null && conf.getRedId() != null ? "红包 #" + conf.getRedId() : "红包";
+    }
+
     /**
      * 批量删除直播红包记录配置
      *
@@ -424,12 +432,11 @@ public class LiveRedConfServiceImpl implements ILiveRedConfService {
             for (String redIdStr : range) {
                 LiveRedConf conf = baseMapper.selectLiveRedConfByRedId(Long.valueOf(redIdStr));
                 if (conf != null) {
-                    opLogs.add(liveConsoleOpLogService.saveLog(
+                    opLogs.add(liveConsoleOpLogService.saveRedSettleLog(
                             conf.getLiveId(),
-                            LiveConsoleOpLog.OP_RED_SETTLE,
                             LiveConsoleOpLog.HANDLE_AUTO,
                             conf.getRedId(),
-                            conf.getDesc()
+                            resolveRedBizName(conf)
                     ));
                 }
             }