|
|
@@ -0,0 +1,251 @@
|
|
|
+package shop.alien.store.service.impl;
|
|
|
+
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import shop.alien.entity.store.LifeDiscountCoupon;
|
|
|
+import shop.alien.entity.store.StoreImg;
|
|
|
+import shop.alien.entity.store.StoreInfo;
|
|
|
+import shop.alien.entity.storePlatform.StoreOperationalActivity;
|
|
|
+import shop.alien.entity.storePlatform.StoreOperationalActivitySignup;
|
|
|
+import shop.alien.entity.storePlatform.vo.StoreOperationalActivityVO;
|
|
|
+import shop.alien.entity.storePlatform.vo.StoreOperationalActivitySignupCheckVo;
|
|
|
+import shop.alien.mapper.LifeDiscountCouponMapper;
|
|
|
+import shop.alien.mapper.StoreImgMapper;
|
|
|
+import shop.alien.mapper.StoreInfoMapper;
|
|
|
+import shop.alien.mapper.storePlantform.StoreOperationalActivityMapper;
|
|
|
+import shop.alien.mapper.storePlantform.StoreOperationalActivitySignupMapper;
|
|
|
+import shop.alien.store.config.BaseRedisService;
|
|
|
+import shop.alien.store.dto.StoreOperationalActivitySignupDto;
|
|
|
+import shop.alien.store.service.StoreOperationalActivityService;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import shop.alien.util.common.JwtUtil;
|
|
|
+
|
|
|
+import java.util.Date;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 用户端运营活动服务实现
|
|
|
+ *
|
|
|
+ * @author system
|
|
|
+ * @since 2025-01-XX
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class StoreOperationalActivityServiceImpl implements StoreOperationalActivityService {
|
|
|
+
|
|
|
+ private final StoreOperationalActivityMapper activityMapper;
|
|
|
+ private final StoreImgMapper imgMapper;
|
|
|
+ private final LifeDiscountCouponMapper lifeDiscountCouponMapper;
|
|
|
+ private final StoreInfoMapper storeInfoMapper;
|
|
|
+ private final StoreOperationalActivitySignupMapper signupMapper;
|
|
|
+ private final BaseRedisService baseRedisService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public StoreOperationalActivityVO getActivityDetail(Integer id) {
|
|
|
+ log.info("StoreOperationalActivityServiceImpl.getActivityDetail: id={}", id);
|
|
|
+ if (id == null) {
|
|
|
+ throw new IllegalArgumentException("活动ID不能为空");
|
|
|
+ }
|
|
|
+ StoreOperationalActivity activity = activityMapper.selectById(id);
|
|
|
+ if (activity == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ StoreOperationalActivityVO vo = new StoreOperationalActivityVO();
|
|
|
+ BeanUtils.copyProperties(activity, vo);
|
|
|
+ vo.setStatusName(resolveStatusName(activity.getStatus()));
|
|
|
+ fillSignupFlags(vo, activity);
|
|
|
+ fillSignupCounts(vo);
|
|
|
+
|
|
|
+ if (activity.getCouponId() != null) {
|
|
|
+ LifeDiscountCoupon coupon = lifeDiscountCouponMapper.selectById(activity.getCouponId());
|
|
|
+ if (coupon != null) {
|
|
|
+ vo.setCouponName(coupon.getName());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ attachStoreInfo(vo);
|
|
|
+ fillActivityImages(vo);
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public StoreOperationalActivitySignupCheckVo checkSignup(Integer activityId, Integer userId) {
|
|
|
+ log.info("StoreOperationalActivityServiceImpl.checkSignup: activityId={}, userId={}", activityId, userId);
|
|
|
+ if (activityId == null) {
|
|
|
+ throw new IllegalArgumentException("活动ID不能为空");
|
|
|
+ }
|
|
|
+ if (userId == null) {
|
|
|
+ throw new IllegalArgumentException("用户ID不能为空");
|
|
|
+ }
|
|
|
+ StoreOperationalActivity activity = activityMapper.selectById(activityId);
|
|
|
+ if (activity == null) {
|
|
|
+ throw new IllegalArgumentException("活动不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ Integer signupCount = signupMapper.countSignupByActivityId(activityId);
|
|
|
+ Integer limitPeople = activity.getActivityLimitPeople();
|
|
|
+ boolean full = limitPeople != null && limitPeople > 0 && signupCount != null && signupCount >= limitPeople;
|
|
|
+
|
|
|
+ Integer userSignupCount = signupMapper.countSignedUpByActivityAndUser(activityId, userId);
|
|
|
+ boolean signedUp = userSignupCount != null && userSignupCount > 0;
|
|
|
+
|
|
|
+ StoreOperationalActivitySignupCheckVo vo = new StoreOperationalActivitySignupCheckVo();
|
|
|
+ vo.setCurrentSignupCount(signupCount != null ? signupCount : 0);
|
|
|
+ vo.setActivityLimitPeople(limitPeople);
|
|
|
+ vo.setFull(full);
|
|
|
+ vo.setSignedUp(signedUp);
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean signup(StoreOperationalActivitySignupDto dto) {
|
|
|
+ if (dto == null) {
|
|
|
+ throw new IllegalArgumentException("报名参数不能为空");
|
|
|
+ }
|
|
|
+ if (dto.getActivityId() == null) {
|
|
|
+ throw new IllegalArgumentException("活动ID不能为空");
|
|
|
+ }
|
|
|
+ if (dto.getUserId() == null) {
|
|
|
+ throw new IllegalArgumentException("用户ID不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ StoreOperationalActivity activity = activityMapper.selectById(dto.getActivityId());
|
|
|
+ if (activity == null) {
|
|
|
+ throw new IllegalArgumentException("活动不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ String lockKey = "activity:signup:" + dto.getActivityId();
|
|
|
+ String lockVal = baseRedisService.lock(lockKey, 5000, 5000);
|
|
|
+ if (lockVal == null) {
|
|
|
+ throw new IllegalArgumentException("系统繁忙,请稍后再试");
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ Integer userSignupCount = signupMapper.countApprovedByActivityAndUser(dto.getActivityId(), dto.getUserId());
|
|
|
+ if (userSignupCount != null && userSignupCount > 0) {
|
|
|
+ throw new IllegalArgumentException("已成功报名,请勿重复报名");
|
|
|
+ }
|
|
|
+
|
|
|
+ Integer approvedCount = signupMapper.countSignupByActivityId(dto.getActivityId());
|
|
|
+ Integer limitPeople = activity.getActivityLimitPeople();
|
|
|
+ if (limitPeople != null && limitPeople > 0 && approvedCount != null && approvedCount >= limitPeople) {
|
|
|
+ throw new IllegalArgumentException("报名人数已满");
|
|
|
+ }
|
|
|
+
|
|
|
+ StoreOperationalActivitySignup signup = new StoreOperationalActivitySignup();
|
|
|
+ signup.setActivityId(dto.getActivityId());
|
|
|
+ signup.setStoreId(activity.getStoreId());
|
|
|
+ signup.setUserId(dto.getUserId());
|
|
|
+ signup.setUserName(dto.getUserName());
|
|
|
+ signup.setPhone(dto.getPhone());
|
|
|
+ signup.setStatus(0);
|
|
|
+ signup.setSignupTime(new Date());
|
|
|
+ signup.setDeleteFlag(0);
|
|
|
+ signup.setCreatedUserId(dto.getUserId());
|
|
|
+ return signupMapper.insert(signup) > 0;
|
|
|
+ } finally {
|
|
|
+ baseRedisService.unlock(lockKey, lockVal);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private String resolveStatusName(Integer status) {
|
|
|
+ if (status == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ switch (status) {
|
|
|
+ case 1:
|
|
|
+ return "待审核";
|
|
|
+ case 2:
|
|
|
+ return "未开始";
|
|
|
+ case 3:
|
|
|
+ return "审核拒绝";
|
|
|
+ case 4:
|
|
|
+ return "已售罄";
|
|
|
+ case 5:
|
|
|
+ return "进行中";
|
|
|
+ case 6:
|
|
|
+ return "已下架";
|
|
|
+ case 7:
|
|
|
+ return "已结束";
|
|
|
+ default:
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void attachStoreInfo(StoreOperationalActivityVO vo) {
|
|
|
+ if (vo == null || vo.getStoreId() == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ StoreInfo storeInfo = storeInfoMapper.selectById(vo.getStoreId());
|
|
|
+ if (storeInfo != null) {
|
|
|
+ vo.setStoreName(storeInfo.getStoreName());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void fillActivityImages(StoreOperationalActivityVO vo) {
|
|
|
+ if (vo == null || vo.getStoreId() == null || vo.getId() == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ StoreImg titleImg = imgMapper.selectOne(new LambdaQueryWrapper<StoreImg>()
|
|
|
+ .eq(StoreImg::getStoreId, vo.getStoreId())
|
|
|
+ .eq(StoreImg::getBusinessId, vo.getId())
|
|
|
+ .eq(StoreImg::getImgType, 26)
|
|
|
+ .eq(StoreImg::getDeleteFlag, 0));
|
|
|
+ if (titleImg != null) {
|
|
|
+ vo.setActivityTitleImg(titleImg);
|
|
|
+ vo.setActivityTitleImgUrl(titleImg.getImgUrl());
|
|
|
+ }
|
|
|
+
|
|
|
+ StoreImg detailImg = imgMapper.selectOne(new LambdaQueryWrapper<StoreImg>()
|
|
|
+ .eq(StoreImg::getStoreId, vo.getStoreId())
|
|
|
+ .eq(StoreImg::getBusinessId, vo.getId())
|
|
|
+ .eq(StoreImg::getImgType, 27)
|
|
|
+ .eq(StoreImg::getDeleteFlag, 0));
|
|
|
+ if (detailImg != null) {
|
|
|
+ vo.setActivityDetailImg(detailImg);
|
|
|
+ vo.setActivityDetailImgUrl(detailImg.getImgUrl());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void fillSignupCounts(StoreOperationalActivityVO vo) {
|
|
|
+ if (vo == null || vo.getId() == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Integer signupCount = signupMapper.countSignupByActivityId(vo.getId());
|
|
|
+ Integer approvedCount = signupMapper.countApprovedByActivityId(vo.getId());
|
|
|
+ vo.setCurrentSignupCount(signupCount != null ? signupCount : 0);
|
|
|
+ vo.setCurrentApprovedCount(approvedCount != null ? approvedCount : 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void fillSignupFlags(StoreOperationalActivityVO vo, StoreOperationalActivity activity) {
|
|
|
+ if (vo == null || activity == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ boolean expired = false;
|
|
|
+ if (activity.getSignupEndTime() != null) {
|
|
|
+ expired = new Date().after(activity.getSignupEndTime());
|
|
|
+ }
|
|
|
+ vo.setSignupExpired(expired);
|
|
|
+
|
|
|
+ Integer currentUserId = null;
|
|
|
+ try {
|
|
|
+ JSONObject userInfo = JwtUtil.getCurrentUserInfo();
|
|
|
+ if (userInfo != null) {
|
|
|
+ currentUserId = userInfo.getInteger("userId");
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.debug("获取当前用户失败,无法判断是否已报名", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (currentUserId == null) {
|
|
|
+ vo.setSignedUp(false);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Integer signupCount = signupMapper.countSignedUpByActivityAndUser(activity.getId(), currentUserId);
|
|
|
+ vo.setSignedUp(signupCount != null && signupCount > 0);
|
|
|
+ }
|
|
|
+}
|