瀏覽代碼

1、不能跨销售公司核销,对核销卷进行限制

yys 1 周之前
父節點
當前提交
0ce524f7d0
共有 1 個文件被更改,包括 105 次插入22 次删除
  1. 105 22
      fs-service/src/main/java/com/fs/live/service/impl/LiveCouponServiceImpl.java

+ 105 - 22
fs-service/src/main/java/com/fs/live/service/impl/LiveCouponServiceImpl.java

@@ -13,6 +13,8 @@ import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.DictUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.his.domain.FsUser;
+import com.fs.his.service.IFsUserService;
 import com.fs.live.domain.*;
 import com.fs.live.mapper.LiveCouponIssueMapper;
 import com.fs.live.mapper.LiveCouponIssueUserMapper;
@@ -60,6 +62,8 @@ public class LiveCouponServiceImpl implements ILiveCouponService
     private LiveCouponIssueMapper liveCouponIssueMapper;
     @Autowired
     private ILiveConsoleOpLogService liveConsoleOpLogService;
+    @Autowired
+    private IFsUserService fsUserService;
 
     /**
      * 查询优惠券
@@ -470,9 +474,14 @@ public class LiveCouponServiceImpl implements ILiveCouponService
         return R.ok().put("data", detail);
     }
 
+    /**
+     * 销售扫码核销优惠券。
+     * <p>流程:参数校验 → 查券 → 绑定销售校验 → 状态/过期校验 → 落库核销 → 返回详情</p>
+     */
     @Override
     @Transactional
     public R verifyCoupon(LiveCouponVerifyParam param) {
+        // 1. 基础参数校验
         if (param.getVerifyUserId() == null) {
             return R.error("销售未登录");
         }
@@ -480,57 +489,122 @@ public class LiveCouponServiceImpl implements ILiveCouponService
             return R.error("核销码不能为空");
         }
 
-        LiveCouponUser couponUser;
-        if (StringUtils.isNotEmpty(param.getVerifyCode())) {
-            couponUser = liveCouponUserService.selectLiveCouponUserByVerifyCode(param.getVerifyCode());
-        } else {
-            couponUser = liveCouponUserService.selectLiveCouponUserById(param.getCouponUserId());
-        }
+        // 2. 按核销码或发放记录ID定位优惠券
+        LiveCouponUser couponUser = resolveCouponUser(param);
         if (couponUser == null || Objects.equals(couponUser.getIsDel(), 1)) {
             return R.error("优惠券不存在");
         }
 
-        Date now = DateUtils.getNowDate();
-        if (couponUser.getStatus() != null && couponUser.getStatus() == 1) {
+        // 3. 校验持券用户是否绑定当前销售(防跨销售核销)
+        R checkResult = checkBindSales(couponUser, param.getVerifyUserId());
+        if (checkResult != null) {
+            return checkResult;
+        }
+        // 4. 校验优惠券状态是否可核销(含过期同步)
+        checkResult = checkCouponVerifiable(couponUser);
+        if (checkResult != null) {
+            return checkResult;
+        }
+
+        // 5. 落库标记已核销,并返回最新详情
+        markCouponVerified(couponUser, param.getVerifyUserId());
+        LiveCouponUserDetailVo detail = liveCouponUserService.selectLiveCouponUserDetailById(couponUser.getId());
+        fillCouponStatusName(detail);
+        return R.ok("核销成功").put("data", detail);
+    }
+
+    /**
+     * 解析待核销优惠券:优先按核销码查询,否则按发放记录ID查询。
+     *
+     * @param param 核销参数(verifyCode / couponUserId)
+     * @return 优惠券发放记录,未找到时由调用方处理
+     */
+    private LiveCouponUser resolveCouponUser(LiveCouponVerifyParam param) {
+        if (StringUtils.isNotEmpty(param.getVerifyCode())) {
+            return liveCouponUserService.selectLiveCouponUserByVerifyCode(param.getVerifyCode());
+        }
+        return liveCouponUserService.selectLiveCouponUserById(param.getCouponUserId());
+    }
+
+    /**
+     * 校验持券用户是否绑定当前登录销售。
+     * <p>通过优惠券上的 userId 查 fs_user.bind_company_user_id,与 verifyUserId 比对,防止跨销售核销。</p>
+     *
+     * @param couponUser   优惠券发放记录
+     * @param verifyUserId 当前登录销售ID
+     * @return 校验失败返回错误结果;通过返回 null
+     */
+    private R checkBindSales(LiveCouponUser couponUser, Long verifyUserId) {
+        if (couponUser.getUserId() == null) {
+            return R.error("优惠券所属用户不存在");
+        }
+        FsUser fsUser = fsUserService.selectFsUserByUserId(Long.valueOf(couponUser.getUserId()));
+        if (fsUser == null) {
+            return R.error("优惠券所属用户不存在");
+        }
+        // bind_company_user_id 为空或与当前销售不一致,均不允许核销
+        if (!Objects.equals(fsUser.getBindCompanyUserId(), verifyUserId)) {
+            return R.error("该用户未绑定当前销售,无法核销");
+        }
+        return null;
+    }
+
+    /**
+     * 校验优惠券是否处于可核销状态。
+     * <p>已核销、已过期不可核销;若未核销但已超过 limitTime,则同步落库为已过期后再拒绝。</p>
+     *
+     * @param couponUser 优惠券发放记录
+     * @return 校验失败返回错误结果;通过返回 null
+     */
+    private R checkCouponVerifiable(LiveCouponUser couponUser) {
+        Integer status = couponUser.getStatus();
+        // 0-未核销 1-已核销 2-已过期
+        if (status != null && status == 1) {
             return R.error("优惠券已核销");
         }
-        if (couponUser.getStatus() != null && couponUser.getStatus() == 2) {
+        if (status != null && status == 2) {
             return R.error("优惠券已过期");
         }
-        if (couponUser.getLimitTime() != null && couponUser.getLimitTime().before(now)) {
-            LiveCouponUser expired = new LiveCouponUser();
-            expired.setId(couponUser.getId());
-            expired.setStatus(2);
-            expired.setIsFail(0);
-            expired.setUpdateTime(now);
-            liveCouponUserService.updateLiveCouponUser(expired);
+        // 状态仍为未核销,但实际已过有效期时,先同步为已过期
+        expireCouponIfNeeded(couponUser, DateUtils.getNowDate());
+        if (Objects.equals(couponUser.getStatus(), 2)) {
             return R.error("优惠券已过期");
         }
+        return null;
+    }
 
+    /**
+     * 将优惠券标记为已核销并写入核销人、核销时间;若缺少核销码则补生成。
+     *
+     * @param couponUser   优惠券发放记录
+     * @param verifyUserId 核销销售ID
+     */
+    private void markCouponVerified(LiveCouponUser couponUser, Long verifyUserId) {
+        Date now = DateUtils.getNowDate();
         LiveCouponUser update = new LiveCouponUser();
         update.setId(couponUser.getId());
         update.setStatus(1);
         update.setUseTime(now);
         update.setVerifyTime(now);
-        update.setVerifyUserId(param.getVerifyUserId());
+        update.setVerifyUserId(verifyUserId);
         update.setUpdateTime(now);
         if (StringUtils.isEmpty(couponUser.getVerifyCode())) {
             update.setVerifyCode(generateVerifyCode());
         }
         liveCouponUserService.updateLiveCouponUser(update);
-
-        LiveCouponUserDetailVo detail = liveCouponUserService.selectLiveCouponUserDetailById(couponUser.getId());
-        fillCouponStatusName(detail);
-        return R.ok("核销成功").put("data", detail);
     }
 
     /**
-     * 未核销且已过期的优惠券同步为已过期(与 verifyCoupon 逻辑一致)
+     * 若优惠券未核销且已超过有效期,则同步更新为已过期状态。
+     *
+     * @param couponUser 优惠券发放记录(成功过期后会回写 status=2)
+     * @param now        当前时间
      */
     private void expireCouponIfNeeded(LiveCouponUser couponUser, Date now) {
         if (couponUser == null) {
             return;
         }
+        // 仅处理未核销状态
         if (couponUser.getStatus() != null && couponUser.getStatus() != 0) {
             return;
         }
@@ -546,6 +620,9 @@ public class LiveCouponServiceImpl implements ILiveCouponService
         couponUser.setStatus(2);
     }
 
+    /**
+     * 填充优惠券状态中文名称(未核销 / 已核销 / 已过期)。
+     */
     private void fillCouponStatusName(LiveCouponUserDetailVo detail) {
         if (detail == null || detail.getStatus() == null) {
             return;
@@ -563,6 +640,9 @@ public class LiveCouponServiceImpl implements ILiveCouponService
         }
     }
 
+    /**
+     * 详情中若无核销码,则补生成并落库,便于前端展示二维码。
+     */
     private void ensureVerifyCode(LiveCouponUserDetailVo detail) {
         if (detail == null || StringUtils.isNotEmpty(detail.getVerifyCode())) {
             return;
@@ -575,6 +655,9 @@ public class LiveCouponServiceImpl implements ILiveCouponService
         detail.setVerifyCode(update.getVerifyCode());
     }
 
+    /**
+     * 生成优惠券核销码(前缀 LC + 时间戳 + 随机数)。
+     */
     private String generateVerifyCode() {
         return "LC" + System.currentTimeMillis() + (int) (Math.random() * 1000);
     }