parent
fc6aaf8b35
commit
8d41b4c2a9
|
|
@ -5,6 +5,7 @@ import com.czg.market.service.SmsPushEventService;
|
|||
import com.czg.resp.CzgResult;
|
||||
import com.czg.sa.StpKit;
|
||||
import com.czg.validator.group.InsertGroup;
|
||||
import com.czg.validator.group.UpdateGroup;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -45,6 +46,16 @@ public class SmsPushEventController {
|
|||
return CzgResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*/
|
||||
@PutMapping
|
||||
public CzgResult<Void> upPushEvent(@RequestBody @Validated(UpdateGroup.class) SmsPushEventDTO param) {
|
||||
param.setShopId(StpKit.USER.getShopId());
|
||||
pushEventService.upPushEvent(param);
|
||||
return CzgResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除任务
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.czg.config;
|
|||
import com.czg.account.service.ShopTableService;
|
||||
import com.czg.market.entity.MkShopCouponRecord;
|
||||
import com.czg.market.service.MkShopCouponRecordService;
|
||||
import com.czg.market.service.SmsPushEventService;
|
||||
import com.czg.order.service.OrderInfoService;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import jakarta.annotation.Resource;
|
||||
|
|
@ -34,6 +35,8 @@ public class RedisKeyExpirationListener implements MessageListener {
|
|||
private ShopTableService tableService;
|
||||
@Resource
|
||||
private MkShopCouponRecordService mkShopCouponRecordService;
|
||||
@Resource
|
||||
private SmsPushEventService smsPushEventService;
|
||||
|
||||
|
||||
//redis key失效监听
|
||||
|
|
@ -66,6 +69,10 @@ public class RedisKeyExpirationListener implements MessageListener {
|
|||
.eq(MkShopCouponRecord::getStatus, 0)
|
||||
.eq(MkShopCouponRecord::getId, Long.parseLong(couponId))
|
||||
);
|
||||
} else if (expiredKey.startsWith(RedisCst.classKeyExpired.EXPIRED_SMS)) {
|
||||
log.info("监听到短信定时发放优惠券,sms_push_event任务Id: {}", expiredKey);
|
||||
String eventId = expiredKey.substring(RedisCst.classKeyExpired.EXPIRED_SMS.length());
|
||||
smsPushEventService.sendPushEventCoupon(eventId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ public interface RedisCst {
|
|||
public static final String EXPIRED_TABLE = "expired:table:";
|
||||
//优惠券过期
|
||||
public static final String EXPIRED_COUPON = "expired:coupon:";
|
||||
//短信定时发放 倒计时KEY
|
||||
public static final String EXPIRED_SMS = "expired:sms:";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public class SmsPushEventDTO implements Serializable {
|
|||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@NotNull(message = "id不能为空", groups = {InsertGroup.class, UpdateGroup.class})
|
||||
private Long id;
|
||||
|
||||
private Long shopId;
|
||||
|
|
@ -44,18 +44,18 @@ public class SmsPushEventDTO implements Serializable {
|
|||
/**
|
||||
* 模板ID
|
||||
*/
|
||||
@NotNull(message = "模板ID不能为空", groups = InsertGroup.class)
|
||||
@NotNull(message = "模板ID不能为空", groups = {InsertGroup.class, UpdateGroup.class})
|
||||
private Long pushEventId;
|
||||
|
||||
/**
|
||||
* 1 全部用户 2范围用户 3 指定用户 指定暂定一个用户
|
||||
*/
|
||||
@NotNull(message = "发送范围不能为空", groups = InsertGroup.class)
|
||||
@NotNull(message = "发送范围不能为空", groups = {InsertGroup.class, UpdateGroup.class})
|
||||
private Long userType;
|
||||
/**
|
||||
* 预计人数
|
||||
*/
|
||||
@NotNull(message = "预计人数不能为空", groups = InsertGroup.class)
|
||||
@NotNull(message = "预计人数不能为空", groups = {InsertGroup.class, UpdateGroup.class})
|
||||
private Long estimateNum;
|
||||
/**
|
||||
* 实际人数
|
||||
|
|
@ -79,13 +79,13 @@ public class SmsPushEventDTO implements Serializable {
|
|||
/**
|
||||
* 发送内容
|
||||
*/
|
||||
@NotBlank(message = "发送内容不能为空", groups = InsertGroup.class)
|
||||
@NotBlank(message = "发送内容不能为空", groups = {InsertGroup.class, UpdateGroup.class})
|
||||
private String content;
|
||||
/**
|
||||
* 发送参数json
|
||||
* {"店铺名称":"火锅店","时间":"2025-02-17"}
|
||||
*/
|
||||
@NotBlank(message = "发送参数json不能为空", groups = InsertGroup.class)
|
||||
@NotBlank(message = "发送参数json不能为空", groups = {InsertGroup.class, UpdateGroup.class})
|
||||
private String json;
|
||||
|
||||
/**
|
||||
|
|
@ -96,7 +96,7 @@ public class SmsPushEventDTO implements Serializable {
|
|||
/**
|
||||
* 发送类型 1 立即发送 2定时发送
|
||||
*/
|
||||
@NotNull(message = "发送类型不能为空", groups = InsertGroup.class)
|
||||
@NotNull(message = "发送类型不能为空", groups = {InsertGroup.class, UpdateGroup.class})
|
||||
private Integer sendType;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.czg.market.service;
|
||||
|
||||
import com.czg.BaseQueryParam;
|
||||
import com.czg.market.dto.SmsPushEventDTO;
|
||||
import com.czg.market.entity.SmsPushEvent;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
|
|
@ -24,5 +23,15 @@ public interface SmsPushEventService extends IService<SmsPushEvent> {
|
|||
*/
|
||||
void addPushEvent(SmsPushEventDTO param);
|
||||
|
||||
/**
|
||||
* 发送营销推送发送任务中的优惠券
|
||||
*/
|
||||
void sendPushEventCoupon(String eventId);
|
||||
|
||||
/**
|
||||
* 更新营销推送发送任务
|
||||
*/
|
||||
void upPushEvent(SmsPushEventDTO param);
|
||||
|
||||
void deletePushEvent(Long id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import java.util.Map;
|
|||
* @since 2025-10-13
|
||||
*/
|
||||
@Service
|
||||
public class MkConsumeCashbackRecordServiceImpl extends ServiceImpl<MkConsumeCashbackRecordMapper, MkConsumeCashbackRecord> implements MkConsumeCashbackRecordService{
|
||||
public class MkConsumeCashbackRecordServiceImpl extends ServiceImpl<MkConsumeCashbackRecordMapper, MkConsumeCashbackRecord> implements MkConsumeCashbackRecordService {
|
||||
@Override
|
||||
public Map<String, Object> getRecord(Long mainShopId, Long shopId, String key, LocalDateTime startTime, LocalDateTime endTime) {
|
||||
QueryWrapper queryWrapper = new MyQueryWrapper().eq(MkConsumeCashbackRecord::getMainShopId, mainShopId)
|
||||
|
|
@ -76,7 +76,7 @@ public class MkConsumeCashbackRecordServiceImpl extends ServiceImpl<MkConsumeCas
|
|||
|
||||
BigDecimal amount = getOneAs(totalQuery.select("SUM(cashback_amount)"), BigDecimal.class);
|
||||
Map<String, Object> map = BeanUtil.beanToMap(pageAs(PageUtil.buildPage(), queryWrapper, MkConsumeCashbackRecordVO.class));
|
||||
map.put("totalAmount", amount);
|
||||
map.put("totalAmount", amount == null ? BigDecimal.ZERO : amount);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||
import com.czg.account.entity.ShopUser;
|
||||
import com.czg.account.service.AShopUserService;
|
||||
import com.czg.config.RabbitPublisher;
|
||||
import com.czg.config.RedisCst;
|
||||
import com.czg.exception.CzgException;
|
||||
import com.czg.market.dto.MkShopCouponGiftDTO;
|
||||
import com.czg.market.dto.SmsPushEventDTO;
|
||||
|
|
@ -15,6 +16,7 @@ import com.czg.market.entity.SmsPushEvent;
|
|||
import com.czg.market.entity.SmsPushEventUser;
|
||||
import com.czg.market.service.MkShopCouponRecordService;
|
||||
import com.czg.market.service.SmsPushEventService;
|
||||
import com.czg.service.RedisService;
|
||||
import com.czg.service.market.mapper.SmsPushEventMapper;
|
||||
import com.czg.service.market.mapper.SmsPushEventUserMapper;
|
||||
import com.czg.utils.AssertUtil;
|
||||
|
|
@ -49,6 +51,8 @@ public class SmsPushEventServiceImpl extends ServiceImpl<SmsPushEventMapper, Sms
|
|||
private AShopUserService shopUserService;
|
||||
@Resource
|
||||
private RabbitPublisher rabbitPublisher;
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
|
||||
@Override
|
||||
public Page<SmsPushEventDTO> getPushEventPage(Integer page, Integer size, Long shopId, Long id) {
|
||||
|
|
@ -96,6 +100,38 @@ public class SmsPushEventServiceImpl extends ServiceImpl<SmsPushEventMapper, Sms
|
|||
}
|
||||
// 推送消息 进行 消息发送
|
||||
rabbitPublisher.sendApplySmsMsg(pushEvent.getShopId() + "," + pushEvent.getId(), "sendMarkSms");
|
||||
if (param.getSendType() == 1 && StrUtil.isNotBlank(param.getCoupon())) {
|
||||
grantCoupon(param);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void upPushEvent(SmsPushEventDTO param) {
|
||||
AssertUtil.isNull(param.getUserType(), "请选择用户范围后进行推送");
|
||||
if (param.getUserType() == 2 && param.getSmsPushEventUser() == null) {
|
||||
throw new CzgException("范围推送时,必须指定用户范围");
|
||||
} else if (param.getUserType() == 3 && param.getUserId() == null) {
|
||||
throw new CzgException("指定推送时,必须指定用户");
|
||||
}
|
||||
AssertUtil.isNull(param.getPushEventId(), "请选择模板后进行推送");
|
||||
AssertUtil.isNull(param.getContent(), "消息内容不能为空");
|
||||
if (param.getSendType() == 2) {
|
||||
AssertUtil.isNull(param.getSendTime(), "定时发送时,必须指定发送时间");
|
||||
} else {
|
||||
param.setSendTime(LocalDateTime.now());
|
||||
}
|
||||
SmsPushEvent pushEvent = BeanUtil.toBean(param, SmsPushEvent.class);
|
||||
updateById(pushEvent);
|
||||
eventUserMapper.deleteByQuery(new QueryWrapper().eq(SmsPushEventUser::getEventId, pushEvent.getId()));
|
||||
if (param.getUserType() == 2) {
|
||||
SmsPushEventUser eventUser = param.getSmsPushEventUser();
|
||||
eventUser.setShopId(param.getShopId());
|
||||
eventUser.setEventId(pushEvent.getId());
|
||||
eventUserMapper.insert(eventUser);
|
||||
}
|
||||
// 推送消息 进行 消息发送
|
||||
rabbitPublisher.sendApplySmsMsg(pushEvent.getShopId() + "," + pushEvent.getId(), "sendMarkSms");
|
||||
//发放优惠券
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
|
|
@ -106,29 +142,48 @@ public class SmsPushEventServiceImpl extends ServiceImpl<SmsPushEventMapper, Sms
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPushEventCoupon(String eventId) {
|
||||
SmsPushEventDTO pushEvent = getObjAs(new QueryWrapper().eq(SmsPushEvent::getId, eventId), SmsPushEventDTO.class);
|
||||
AssertUtil.isNull(pushEvent, "券发放失败,推送事件不存在");
|
||||
SmsPushEventUser eventUser = eventUserMapper.selectOneByQuery(
|
||||
new QueryWrapper().eq(SmsPushEventUser::getEventId, eventId)
|
||||
);
|
||||
AssertUtil.isNull(eventUser, "券发放失败,推送事件用户群体不存在");
|
||||
pushEvent.setSmsPushEventUser(eventUser);
|
||||
if (pushEvent.getSendType() == 1 && StrUtil.isNotBlank(pushEvent.getCoupon())) {
|
||||
grantCoupon(pushEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 发放优惠券
|
||||
private void grantCoupon(SmsPushEventDTO param) {
|
||||
if (StrUtil.isBlank(param.getCoupon())) {
|
||||
return;
|
||||
}
|
||||
List<ShopUser> userList = shopUserService.getPushEventUserList(param.getSmsPushEventUser());
|
||||
// 2. 将JSON字符串解析为JSONArray
|
||||
JSONArray couponArray = JSON.parseArray(param.getCoupon());
|
||||
//发放优惠券
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
List<ShopUser> userList = shopUserService.getPushEventUserList(param.getSmsPushEventUser());
|
||||
// 2. 将JSON字符串解析为JSONArray
|
||||
JSONArray couponArray = JSON.parseArray(param.getCoupon());
|
||||
|
||||
// 3. 遍历JSONArray,逐个获取JSONObject的字段值
|
||||
for (int i = 0; i < couponArray.size(); i++) {
|
||||
// 获取单个优惠券的JSONObject对象
|
||||
JSONObject couponObj = couponArray.getJSONObject(i);
|
||||
// 通过键名获取对应值(需注意字段类型,按需转换)
|
||||
Long id = couponObj.getLong("id");
|
||||
Integer num = couponObj.getInteger("num");
|
||||
MkShopCouponGiftDTO giftDTO = new MkShopCouponGiftDTO();
|
||||
giftDTO.setShopId(param.getShopId());
|
||||
giftDTO.setSourceId(param.getId());
|
||||
giftDTO.setCouponId(id);
|
||||
giftDTO.setSource("营销短信发放");
|
||||
couponRecordService.batchReceiveCoupon(giftDTO, num, userList);
|
||||
}
|
||||
// 3. 遍历JSONArray,逐个获取JSONObject的字段值
|
||||
for (int i = 0; i < couponArray.size(); i++) {
|
||||
// 获取单个优惠券的JSONObject对象
|
||||
JSONObject couponObj = couponArray.getJSONObject(i);
|
||||
// 通过键名获取对应值(需注意字段类型,按需转换)
|
||||
Long id = couponObj.getLong("id");
|
||||
Integer num = couponObj.getInteger("num");
|
||||
MkShopCouponGiftDTO giftDTO = new MkShopCouponGiftDTO();
|
||||
giftDTO.setShopId(param.getShopId());
|
||||
giftDTO.setSourceId(param.getId());
|
||||
giftDTO.setCouponId(id);
|
||||
giftDTO.setSource("营销短信发放");
|
||||
couponRecordService.batchReceiveCoupon(giftDTO, num, userList);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("异步发放优惠券失败", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -138,6 +193,10 @@ public class SmsPushEventServiceImpl extends ServiceImpl<SmsPushEventMapper, Sms
|
|||
public void deletePushEvent(Long id) {
|
||||
SmsPushEvent pushEvent = getById(id);
|
||||
AssertUtil.isNull(pushEvent, "记录不存在");
|
||||
if (pushEvent.getStatus() == 2) {
|
||||
throw new CzgException("已发送的记录不能删除");
|
||||
}
|
||||
redisService.del(RedisCst.classKeyExpired.EXPIRED_SMS + id);
|
||||
pushEvent.setIsDel(1);
|
||||
updateById(pushEvent);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue