Просмотр исходного кода

1、结束时间问题处理
2、优惠卷过期时间处理

yys 4 дней назад
Родитель
Сommit
74d3abded4

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

@@ -75,7 +75,7 @@ public interface LiveCouponMapper
             "left join live_coupon lc on lc.coupon_id = lci.coupon_id " +
             "left join live_coupon lc on lc.coupon_id = lci.coupon_id " +
             "left join live_goods lg on lg.goods_id = lcir.goods_id " +
             "left join live_goods lg on lg.goods_id = lcir.goods_id " +
             "left join fs_store_product_scrm fsp on lg.product_id = fsp.product_id " +
             "left join fs_store_product_scrm fsp on lg.product_id = fsp.product_id " +
-            "where lcir.live_id = #{liveId}")
+            "where lcir.live_id = #{liveId} and lc.coupon_id is not null")
     List<LiveCoupon> selectLiveCouponByLiveId(@Param("liveId") Long liveId);
     List<LiveCoupon> selectLiveCouponByLiveId(@Param("liveId") Long liveId);
 
 
     @Select("<script>" +
     @Select("<script>" +
@@ -115,7 +115,7 @@ public interface LiveCouponMapper
             "left join live_coupon lc on lc.coupon_id = lci.coupon_id " +
             "left join live_coupon lc on lc.coupon_id = lci.coupon_id " +
             "left join live_goods lg on lg.goods_id = lcir.goods_id " +
             "left join live_goods lg on lg.goods_id = lcir.goods_id " +
             "left join fs_store_product_scrm fsp on lg.product_id = fsp.product_id " +
             "left join fs_store_product_scrm fsp on lg.product_id = fsp.product_id " +
-            "where lcir.live_id = #{liveId}")
+            "where lcir.live_id = #{liveId} and lc.coupon_id is not null")
     List<LiveCoupon> listOn(@Param("liveId") Long liveId);
     List<LiveCoupon> listOn(@Param("liveId") Long liveId);
 
 
     @Update("update live_coupon_issue_relation set is_show = case WHEN coupon_issue_id = #{couponId} THEN 1 else 0 end where live_id = #{liveId}")
     @Update("update live_coupon_issue_relation set is_show = case WHEN coupon_issue_id = #{couponId} THEN 1 else 0 end where live_id = #{liveId}")

+ 46 - 8
fs-service/src/main/java/com/fs/live/service/impl/LiveCouponServiceImpl.java

@@ -202,9 +202,8 @@ public class LiveCouponServiceImpl implements ILiveCouponService
 
 
     @Override
     @Override
     public List<LiveCoupon> selectLiveCouponByLiveId(Long liveId) {
     public List<LiveCoupon> selectLiveCouponByLiveId(Long liveId) {
-        return liveCouponMapper.selectLiveCouponByLiveId(liveId).stream()
-                .filter(c -> c.getCouponId() != null)
-                .collect(Collectors.toList());
+        // 直接返回 PageHelper 的 Page,勿 stream().collect(),否则会丢失分页 total
+        return liveCouponMapper.selectLiveCouponByLiveId(liveId);
     }
     }
 
 
     @Override
     @Override
@@ -387,7 +386,12 @@ public class LiveCouponServiceImpl implements ILiveCouponService
                 userRecord.setCreateTime(now);
                 userRecord.setCreateTime(now);
                 userRecord.setUpdateTime(now);
                 userRecord.setUpdateTime(now);
                 userRecord.setStatus(0);
                 userRecord.setStatus(0);
-                userRecord.setLimitTime(DateUtils.addDays(now, Math.toIntExact(liveCoupon.getCouponTime())));
+                // 与观看奖励发券一致:优先用发放配置结束时间,否则按模板有效天数(勿补 23:59:59.999,MySQL DATETIME 会进位到次日 00:00:00)
+                if (issue.getLimitTime() != null) {
+                    userRecord.setLimitTime(issue.getLimitTime());
+                } else if (liveCoupon.getCouponTime() != null) {
+                    userRecord.setLimitTime(DateUtils.addDays(now, Math.toIntExact(liveCoupon.getCouponTime())));
+                }
                 userRecord.setIsFail(1);
                 userRecord.setIsFail(1);
                 userRecord.setIsDel(0);
                 userRecord.setIsDel(0);
                 userRecord.setGoodsId(coupon.getGoodsId());
                 userRecord.setGoodsId(coupon.getGoodsId());
@@ -804,6 +808,39 @@ public class LiveCouponServiceImpl implements ILiveCouponService
         liveCouponUserService.updateLiveCouponUser(update);
         liveCouponUserService.updateLiveCouponUser(update);
     }
     }
 
 
+    /**
+     * 计算用户优惠券到期时间。
+     * <p>优先取发放配置结束时间(发布时的优惠券结束日期,日期型补齐到当天 23:59:59);
+     * 未配置时按模板有效天数从领取时刻起算。与完课/观看奖励发券逻辑保持一致。</p>
+     */
+    private Date resolveCouponUserLimitTime(LiveCouponIssue issue, LiveCoupon liveCoupon, Date now) {
+        if (issue != null && issue.getLimitTime() != null) {
+            return toEndOfDayIfMidnight(issue.getLimitTime());
+        }
+        if (liveCoupon != null && liveCoupon.getCouponTime() != null) {
+            return DateUtils.addDays(now, Math.toIntExact(liveCoupon.getCouponTime()));
+        }
+        return null;
+    }
+
+    /**
+     * 发布结束日期多为 yyyy-MM-dd(落库为 00:00:00),补齐到当天末,保证结束日当天仍可用。
+     */
+    private Date toEndOfDayIfMidnight(Date date) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        if (cal.get(Calendar.HOUR_OF_DAY) == 0
+                && cal.get(Calendar.MINUTE) == 0
+                && cal.get(Calendar.SECOND) == 0
+                && cal.get(Calendar.MILLISECOND) == 0) {
+            cal.set(Calendar.HOUR_OF_DAY, 23);
+            cal.set(Calendar.MINUTE, 59);
+            cal.set(Calendar.SECOND, 59);
+            cal.set(Calendar.MILLISECOND, 999);
+        }
+        return cal.getTime();
+    }
+
     /**
     /**
      * 若优惠券未核销且已超过有效期,则同步更新为已过期状态。
      * 若优惠券未核销且已超过有效期,则同步更新为已过期状态。
      *
      *
@@ -874,10 +911,11 @@ public class LiveCouponServiceImpl implements ILiveCouponService
 
 
     @Override
     @Override
     public List<LiveCoupon> listOn(Long liveId) {
     public List<LiveCoupon> listOn(Long liveId) {
-        return liveCouponMapper.listOn(liveId).stream()
-                .filter(c -> c.getCouponId() != null)
-                .filter(c -> c.getGoodsId() != null || isVerifyCouponType(c))
-                .collect(Collectors.toList());
+        // 过滤规则与原先一致:couponId 非空,且已绑定商品或核销/代金券类型
+        // 使用 removeIf 保留 PageHelper 的 Page,避免 collect 后 total 丢失
+        List<LiveCoupon> list = liveCouponMapper.listOn(liveId);
+        list.removeIf(c -> c.getCouponId() == null || (c.getGoodsId() == null && !isVerifyCouponType(c)));
+        return list;
     }
     }
 
 
     /**
     /**

+ 55 - 1
fs-service/src/main/java/com/fs/live/service/impl/LiveServiceImpl.java

@@ -577,6 +577,8 @@ public class LiveServiceImpl implements ILiveService
         live.setIsDel(0);
         live.setIsDel(0);
         live.setIsAudit(0);
         live.setIsAudit(0);
         live.setStartTime(live.getStartTime().withSecond(1));
         live.setStartTime(live.getStartTime().withSecond(1));
+        // 录播:结束时间按开始时间 + 视频时长补齐,避免前端漏算导致 finish_time 为空
+        fillFinishTimeByDuration(live);
         live.setStatus(1);
         live.setStatus(1);
         int save = baseMapper.insertLive(live);
         int save = baseMapper.insertLive(live);
         // 录播 才有视频
         // 录播 才有视频
@@ -778,6 +780,10 @@ public class LiveServiceImpl implements ILiveService
             return -1;
             return -1;
         }
         }
         live.setUpdateTime(DateUtils.getNowDate());
         live.setUpdateTime(DateUtils.getNowDate());
+        if (live.getStartTime() != null) {
+            live.setStartTime(live.getStartTime().withSecond(1));
+        }
+        fillFinishTimeByDuration(live);
         List<LiveVideo> videos = liveVideoService.listByLiveId(live.getLiveId(), 1);
         List<LiveVideo> videos = liveVideoService.listByLiveId(live.getLiveId(), 1);
         if(!videos.isEmpty()){
         if(!videos.isEmpty()){
             LiveVideo liveVideo = videos.get(0);
             LiveVideo liveVideo = videos.get(0);
@@ -1284,7 +1290,9 @@ public class LiveServiceImpl implements ILiveService
         liveEntity.setCompanyUserId(live.getCompanyUserId());
         liveEntity.setCompanyUserId(live.getCompanyUserId());
         liveEntity.setRtmpUrl(null);
         liveEntity.setRtmpUrl(null);
         liveEntity.setFlvHlsUrl(null);
         liveEntity.setFlvHlsUrl(null);
-        liveEntity.setFinishTime(null);
+        // 复制后状态重置为未开播,不能沿用原结束时间(可能是实际关播时间)
+        // 按视频时长重算计划结束时间,避免列表结束时间为空
+        liveEntity.setFinishTime(resolvePlannedFinishTime(exist));
         liveEntity.setIsAudit(0);
         liveEntity.setIsAudit(0);
         liveEntity.setStatus(1);
         liveEntity.setStatus(1);
         liveEntity.setCreateTime(now);
         liveEntity.setCreateTime(now);
@@ -1295,6 +1303,52 @@ public class LiveServiceImpl implements ILiveService
         return liveEntity.getLiveId();
         return liveEntity.getLiveId();
     }
     }
 
 
+    /**
+     * 录播:根据开始时间 + 视频时长补齐结束时间
+     */
+    private void fillFinishTimeByDuration(Live live) {
+        if (live == null || live.getStartTime() == null) {
+            return;
+        }
+        if (live.getLiveType() != null && live.getLiveType() == 2
+                && live.getDuration() != null && live.getDuration() > 0) {
+            live.setFinishTime(live.getStartTime().plusSeconds(live.getDuration()));
+        }
+    }
+
+    /**
+     * 复制时计算计划结束时间:优先 startTime + 视频时长
+     */
+    private LocalDateTime resolvePlannedFinishTime(Live exist) {
+        if (exist == null || exist.getStartTime() == null) {
+            return null;
+        }
+        Long durationSeconds = resolveVideoDurationSeconds(exist.getLiveId());
+        if (durationSeconds != null && durationSeconds > 0) {
+            return exist.getStartTime().plusSeconds(durationSeconds);
+        }
+        // 无视频时长时,若原结束时间仍晚于开始时间,保留相对计划结束时间
+        if (exist.getFinishTime() != null && exist.getFinishTime().isAfter(exist.getStartTime())) {
+            return exist.getFinishTime();
+        }
+        return null;
+    }
+
+    private Long resolveVideoDurationSeconds(Long liveId) {
+        if (liveId == null) {
+            return null;
+        }
+        List<LiveVideo> videos = liveVideoService.selectLiveVideosByLiveId(liveId);
+        if (videos == null || videos.isEmpty()) {
+            return null;
+        }
+        long total = videos.stream()
+                .filter(v -> v.getDuration() != null && v.getDuration() > 0)
+                .mapToLong(LiveVideo::getDuration)
+                .sum();
+        return total > 0 ? total : null;
+    }
+
     /**
     /**
      * 创建直播数据
      * 创建直播数据
      */
      */