群聊优惠券
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
package com.czg.service.market.mapper;
|
||||
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
import com.czg.market.entity.ChatCoupon;
|
||||
|
||||
/**
|
||||
* 映射层。
|
||||
*
|
||||
* @author ww
|
||||
* @since 2025-12-02
|
||||
*/
|
||||
public interface ChatCouponMapper extends BaseMapper<ChatCoupon> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package com.czg.service.market.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.czg.exception.CzgException;
|
||||
import com.czg.market.dto.ChatCouponDTO;
|
||||
import com.czg.market.entity.MkShopCouponRecord;
|
||||
import com.czg.market.entity.ShopCoupon;
|
||||
import com.czg.market.service.MkShopCouponRecordService;
|
||||
import com.czg.market.service.ShopCouponService;
|
||||
import com.czg.market.vo.ChatCouponVO;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||
import com.czg.market.entity.ChatCoupon;
|
||||
import com.czg.market.service.ChatCouponService;
|
||||
import com.czg.service.market.mapper.ChatCouponMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 服务层实现。
|
||||
*
|
||||
* @author ww
|
||||
* @since 2025-12-02
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ChatCouponServiceImpl extends ServiceImpl<ChatCouponMapper, ChatCoupon> implements ChatCouponService {
|
||||
@Resource
|
||||
private ShopCouponService couponService;
|
||||
@Resource
|
||||
private MkShopCouponRecordService recordService;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void createChatCoupon(Long shopId, ChatCouponDTO chatCoupon) {
|
||||
ShopCoupon coupon = couponService.getOne(QueryWrapper.create()
|
||||
.eq(ShopCoupon::getId, chatCoupon.getCouponId())
|
||||
);
|
||||
if (coupon == null) {
|
||||
throw new CzgException("优惠券不可使用,优惠券不存在");
|
||||
}
|
||||
if (!"all".equals(coupon.getGetUserType())) {
|
||||
throw new CzgException("优惠券不可使用,优惠券存在领取用户限制");
|
||||
}
|
||||
ChatCoupon saveChatCoupon = ChatCoupon.builder()
|
||||
.shopId(shopId)
|
||||
.title(chatCoupon.getTitle())
|
||||
.getLimit(chatCoupon.getGetLimit() == null ? 1 : chatCoupon.getGetLimit())
|
||||
.giveNum(chatCoupon.getGiveNum() == null ? -10086 : chatCoupon.getGiveNum())
|
||||
.leftNum(chatCoupon.getGiveNum() == null ? -10086 : chatCoupon.getGiveNum())
|
||||
.useNum(0)
|
||||
.couponId(chatCoupon.getCouponId())
|
||||
.build();
|
||||
save(saveChatCoupon);
|
||||
if (saveChatCoupon.getId() == null) {
|
||||
log.info("发放创建失败,群聊发放任务回填Id失败:{}", JSONObject.toJSONString(saveChatCoupon));
|
||||
throw new CzgException("发放创建失败,请联系管理员");
|
||||
}
|
||||
MkShopCouponRecord record = recordService.assembleRecord(saveChatCoupon.getId(), coupon);
|
||||
saveChatCoupon.setCouponJson(JSONObject.toJSONString(record));
|
||||
updateById(saveChatCoupon);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Page<ChatCouponVO> pageChatCoupon(Long shopId, Integer page, Integer size, Integer status) {
|
||||
Page<ChatCouponVO> pages = pageAs(Page.of(page, size),
|
||||
QueryWrapper.create()
|
||||
.eq(ChatCoupon::getShopId, shopId)
|
||||
.eq(ChatCoupon::getStatus, status)
|
||||
.orderBy(ChatCoupon::getStatus).asc()
|
||||
.orderBy(ChatCoupon::getId).desc(),
|
||||
ChatCouponVO.class);
|
||||
return pages;
|
||||
}
|
||||
|
||||
/**
|
||||
* 失效
|
||||
*/
|
||||
@Override
|
||||
public void expiredChatCoupon(Long shopId, Long id) {
|
||||
ChatCoupon coupon = new ChatCoupon();
|
||||
coupon.setStatus(3);
|
||||
update(coupon, QueryWrapper.create()
|
||||
.eq(ChatCoupon::getId, id)
|
||||
.eq(ChatCoupon::getShopId, shopId)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void grantChatCoupon(Long id, Long shopUserId, Long userId) {
|
||||
ChatCoupon coupon = getOne(QueryWrapper.create()
|
||||
.eq(ChatCoupon::getId, id)
|
||||
.eq(ChatCoupon::getShopId, shopUserId)
|
||||
);
|
||||
if (coupon == null) {
|
||||
throw new CzgException("活动不存在");
|
||||
}
|
||||
if (coupon.getStatus() != 1) {
|
||||
throw new CzgException("活动已失效");
|
||||
}
|
||||
boolean exists = recordService.exists(QueryWrapper.create()
|
||||
.eq(MkShopCouponRecord::getSource, "群聊发放")
|
||||
.eq(MkShopCouponRecord::getSourceId, coupon.getId())
|
||||
.eq(MkShopCouponRecord::getShopUserId, shopUserId)
|
||||
.eq(MkShopCouponRecord::getUserId, userId)
|
||||
);
|
||||
if (exists) {
|
||||
throw new CzgException("不可重复领取");
|
||||
}
|
||||
if (coupon.getLeftNum() <= 0) {
|
||||
throw new CzgException("发放失败,剩余数量不足");
|
||||
}
|
||||
if (coupon.getLeftNum() < coupon.getGetLimit()) {
|
||||
throw new CzgException("发放失败,剩余数量不足");
|
||||
}
|
||||
coupon.setLeftNum(coupon.getLeftNum() - coupon.getGetLimit());
|
||||
if (coupon.getLeftNum() == 0) {
|
||||
coupon.setStatus(3);
|
||||
}
|
||||
updateById(coupon);
|
||||
|
||||
MkShopCouponRecord record = JSONObject.parseObject(coupon.getCouponJson(), MkShopCouponRecord.class);
|
||||
record.setShopUserId(shopUserId);
|
||||
record.setUserId(userId);
|
||||
recordService.grantChatCoupon(record, coupon.getGetLimit());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<MkShopCouponRecord> grantChatCouponRecord(Long id, Integer status, Integer page, Integer size) {
|
||||
return recordService.pageAs(Page.of(page, size),
|
||||
QueryWrapper.create()
|
||||
.eq(MkShopCouponRecord::getSourceId, id)
|
||||
.eq(MkShopCouponRecord::getStatus, status)
|
||||
.orderBy(MkShopCouponRecord::getId).desc(),
|
||||
MkShopCouponRecord.class);
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,6 @@ import com.czg.utils.PageUtil;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
@@ -511,4 +510,78 @@ public class MkShopCouponRecordServiceImpl extends ServiceImpl<MkShopCouponRecor
|
||||
receiveCoupon(giftDTO, rewardCouponDTO.getNum(), false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装信息
|
||||
*/
|
||||
public MkShopCouponRecord assembleRecord(Long chatCouponId, ShopCoupon coupon) {
|
||||
LocalDateTime start = LocalDateTime.now().with(LocalTime.MIN);
|
||||
LocalDateTime end = null;
|
||||
if ("fixed".equals(coupon.getValidType())) {
|
||||
//固定时间
|
||||
if (coupon.getDaysToTakeEffect() != null && coupon.getDaysToTakeEffect() > 0) {
|
||||
start = LocalDateTimeUtil.offset(start, coupon.getDaysToTakeEffect(), ChronoUnit.DAYS).with(LocalTime.MIN);
|
||||
}
|
||||
end = LocalDateTimeUtil.offset(start, coupon.getValidDays(), ChronoUnit.DAYS).with(LocalTime.MAX).truncatedTo(ChronoUnit.SECONDS);
|
||||
} else if ("custom".equals(coupon.getValidType())) {
|
||||
//自定义时间
|
||||
start = coupon.getValidStartTime();
|
||||
end = coupon.getValidEndTime();
|
||||
}
|
||||
MkShopCouponRecord record = new MkShopCouponRecord();
|
||||
record.setShopId(coupon.getShopId());
|
||||
|
||||
record.setCouponId(coupon.getId());
|
||||
record.setCouponSyncId(coupon.getSyncId());
|
||||
record.setSourceId(chatCouponId);
|
||||
|
||||
record.setSource("群聊发放");
|
||||
record.setStatus(0);
|
||||
record.setType(coupon.getCouponType());
|
||||
record.setFullAmount(coupon.getFullAmount());
|
||||
record.setDiscountAmount(coupon.getDiscountAmount());
|
||||
record.setDiscountRate(coupon.getDiscountRate());
|
||||
record.setMaxDiscountAmount(coupon.getMaxDiscountAmount());
|
||||
record.setCreateTime(LocalDateTime.now());
|
||||
record.setIsDel(0);
|
||||
record.setUseStartTime(start);
|
||||
record.setUseEndTime(end);
|
||||
return record;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grantChatCoupon(MkShopCouponRecord record, Integer number) {
|
||||
ShopCoupon coupon = couponService.selectOneById(record.getCouponId());
|
||||
AssertUtil.isNull(coupon, "优惠券不存在");
|
||||
List<MkShopCouponRecord> recordList = new ArrayList<>();
|
||||
// 检查优惠券状态
|
||||
if (coupon.getIsDel() != 0) {
|
||||
// 状态异常,直接返回
|
||||
return;
|
||||
}
|
||||
// 检查优惠券是否失效
|
||||
if (coupon.getStatus() != 1) {
|
||||
return;
|
||||
}
|
||||
coupon.setGiftNum(coupon.getGiftNum() + number);
|
||||
for (int i = 0; i < number; i++) {
|
||||
recordList.add(record);
|
||||
}
|
||||
mapper.insertBatchSelective(recordList, 50);
|
||||
|
||||
QueryWrapper queryWrapper = new QueryWrapper();
|
||||
ShopCoupon newCoupon = new ShopCoupon();
|
||||
newCoupon.setGiftNum(coupon.getGiftNum());
|
||||
if (coupon.getSyncId() != null) {
|
||||
queryWrapper.and(q -> {
|
||||
q.eq(ShopCoupon::getId, coupon.getSyncId()).or(q1 -> {
|
||||
q1.eq(ShopCoupon::getSyncId, coupon.getSyncId());
|
||||
});
|
||||
});
|
||||
couponService.updateByQuery(newCoupon, queryWrapper);
|
||||
} else {
|
||||
newCoupon.setId(coupon.getId());
|
||||
couponService.update(newCoupon, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,15 +16,13 @@ import com.czg.account.vo.UserCouponVo;
|
||||
import com.czg.exception.CzgException;
|
||||
import com.czg.market.dto.MkShopCouponGiftDTO;
|
||||
import com.czg.market.dto.ShopCouponDTO;
|
||||
import com.czg.market.entity.ChatCoupon;
|
||||
import com.czg.market.entity.MkShopCouponRecord;
|
||||
import com.czg.market.entity.ShopCoupon;
|
||||
import com.czg.market.service.MkCouponGiftService;
|
||||
import com.czg.market.service.MkShopCouponRecordService;
|
||||
import com.czg.market.service.ShopCouponService;
|
||||
import com.czg.market.service.*;
|
||||
import com.czg.market.vo.ShopCouponPopUp;
|
||||
import com.czg.market.vo.UserCouponVO;
|
||||
import com.czg.order.entity.OrderInfo;
|
||||
import com.czg.market.service.OrderInfoService;
|
||||
import com.czg.product.entity.Product;
|
||||
import com.czg.product.service.ProductService;
|
||||
import com.czg.sa.StpKit;
|
||||
@@ -43,6 +41,7 @@ import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
@@ -74,6 +73,27 @@ public class ShopCouponServiceImpl extends ServiceImpl<ShopCouponMapper, ShopCou
|
||||
private ProductService productService;
|
||||
@Resource
|
||||
private OrderInfoService orderInfoService;
|
||||
@Resource
|
||||
private ChatCouponService chatCouponService;
|
||||
|
||||
@Override
|
||||
public Page<ShopCouponDTO> chatCoupon(Long shopId, String search) {
|
||||
QueryWrapper queryWrapper = new QueryWrapper();
|
||||
// queryWrapper.select("id as id,title as name");
|
||||
queryWrapper.eq(ShopCoupon::getShopId, shopId)
|
||||
.eq(ShopCoupon::getGetUserType, "all")
|
||||
.eq(ShopCoupon::getIsDel, 0)
|
||||
.eq(ShopCoupon::getStatus, 1)
|
||||
.like(ShopCoupon::getTitle, CzgStrUtils.getStrOrNull(search))
|
||||
.orderBy(ShopCoupon::getCreateTime).desc();
|
||||
queryWrapper.and(q -> {
|
||||
q.eq(ShopCoupon::getValidType, "fixed").or(q1 -> {
|
||||
q1.eq(ShopCoupon::getValidType, "custom").gt(ShopCoupon::getValidEndTime, LocalDateTime.now());
|
||||
});
|
||||
});
|
||||
Page<ShopCouponDTO> list = pageAs(PageUtil.buildPage(), queryWrapper, ShopCouponDTO.class);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<ShopCouponDTO> getCouponPage(ShopCouponDTO param) {
|
||||
@@ -314,12 +334,30 @@ public class ShopCouponServiceImpl extends ServiceImpl<ShopCouponMapper, ShopCou
|
||||
}
|
||||
|
||||
@Override
|
||||
@Async
|
||||
public Boolean use(List<Long> ids, Long shopUserId, Long orderId) {
|
||||
List<MkShopCouponRecord> records = recordService.listByIds(ids);
|
||||
if (records.isEmpty()) {
|
||||
log.error("优惠券使用失败,订单Id:{}", orderId);
|
||||
return false;
|
||||
}
|
||||
Map<Long, Long> chatCouponIdCountMap = records.stream()
|
||||
.filter(record -> "群聊发放".equals(record.getSource()))
|
||||
.collect(Collectors.groupingBy(MkShopCouponRecord::getSourceId,
|
||||
Collectors.counting()
|
||||
));
|
||||
chatCouponIdCountMap.forEach((chatCouponId, count) -> {
|
||||
ChatCoupon chatCoupon = chatCouponService.getById(chatCouponId);
|
||||
if (chatCoupon == null) {
|
||||
return;
|
||||
}
|
||||
ChatCoupon upChatCoupon = new ChatCoupon();
|
||||
upChatCoupon.setId(chatCoupon.getId());
|
||||
upChatCoupon.setUseNum(chatCoupon.getUseNum() + count.intValue());
|
||||
chatCouponService.updateById(upChatCoupon);
|
||||
});
|
||||
|
||||
|
||||
// 使用流来统计 couponId 出现的次数
|
||||
Map<Long, Long> couponIdCountMap = records.stream()
|
||||
.collect(Collectors.groupingBy(MkShopCouponRecord::getCouponId,
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.czg.service.market.mapper.ChatCouponMapper">
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user