公众号推送
This commit is contained in:
@@ -170,4 +170,15 @@ public class ShopUserController {
|
|||||||
return CzgResult.success(shopUserService.getPushEventUser(smsPushEventUser));
|
return CzgResult.success(shopUserService.getPushEventUser(smsPushEventUser));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取公众号推送任务用户列表
|
||||||
|
* @param pushEventUser 公众号推送任务用户
|
||||||
|
* @return 用户列表
|
||||||
|
*/
|
||||||
|
@PostMapping("/getAcPushEventUser")
|
||||||
|
public CzgResult<Page<ShopUser>> getAcPushEventUser(@RequestBody @Validated SmsPushEventUser pushEventUser) {
|
||||||
|
AssertUtil.isNull(pushEventUser.getShopId(), "店铺id不能为空");
|
||||||
|
return CzgResult.success(shopUserService.getAcPushEventUser(pushEventUser));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.czg.controller.admin;
|
||||||
|
|
||||||
|
import com.czg.market.dto.AcPushEventDTO;
|
||||||
|
import com.czg.market.service.AcPushEventService;
|
||||||
|
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;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号推送
|
||||||
|
*
|
||||||
|
* @author ww
|
||||||
|
* @description
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/admin/acPushEvent")
|
||||||
|
public class AcPushEventController {
|
||||||
|
@Resource
|
||||||
|
private AcPushEventService pushEventService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号推送:列表
|
||||||
|
*/
|
||||||
|
@GetMapping
|
||||||
|
public CzgResult<Page<AcPushEventDTO>> getPushEventPage(@RequestParam(required = false, defaultValue = "1") Integer page,
|
||||||
|
@RequestParam(required = false, defaultValue = "10") Integer size,
|
||||||
|
@RequestParam(required = false) Integer status,
|
||||||
|
@RequestParam(required = false) Long id) {
|
||||||
|
Page<AcPushEventDTO> data = pushEventService.getPushEventPage(page, size, StpKit.USER.getShopId(), status, id);
|
||||||
|
return CzgResult.success(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号推送:新增
|
||||||
|
*/
|
||||||
|
@PostMapping
|
||||||
|
public CzgResult<Void> addPushEvent(@RequestBody @Validated(InsertGroup.class) AcPushEventDTO param) {
|
||||||
|
param.setShopId(StpKit.USER.getShopId());
|
||||||
|
pushEventService.addPushEvent(param);
|
||||||
|
return CzgResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号推送:更新
|
||||||
|
*/
|
||||||
|
@PutMapping
|
||||||
|
public CzgResult<Void> upPushEvent(@RequestBody @Validated(UpdateGroup.class) AcPushEventDTO param) {
|
||||||
|
param.setShopId(StpKit.USER.getShopId());
|
||||||
|
pushEventService.upPushEvent(param);
|
||||||
|
return CzgResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号推送:删除任务
|
||||||
|
*/
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public CzgResult<Void> deletePushEvent(@PathVariable Long id) {
|
||||||
|
pushEventService.deletePushEvent(id);
|
||||||
|
return CzgResult.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package com.czg.config;
|
|||||||
|
|
||||||
import com.czg.account.service.ShopTableService;
|
import com.czg.account.service.ShopTableService;
|
||||||
import com.czg.market.entity.MkShopCouponRecord;
|
import com.czg.market.entity.MkShopCouponRecord;
|
||||||
|
import com.czg.market.service.AcPushEventService;
|
||||||
import com.czg.market.service.MkShopCouponRecordService;
|
import com.czg.market.service.MkShopCouponRecordService;
|
||||||
import com.czg.market.service.SmsPushEventService;
|
import com.czg.market.service.SmsPushEventService;
|
||||||
import com.czg.order.service.OrderInfoService;
|
import com.czg.order.service.OrderInfoService;
|
||||||
@@ -37,6 +38,8 @@ public class RedisKeyExpirationListener implements MessageListener {
|
|||||||
private MkShopCouponRecordService mkShopCouponRecordService;
|
private MkShopCouponRecordService mkShopCouponRecordService;
|
||||||
@Resource
|
@Resource
|
||||||
private SmsPushEventService smsPushEventService;
|
private SmsPushEventService smsPushEventService;
|
||||||
|
@Resource
|
||||||
|
private AcPushEventService acPushEventService;
|
||||||
|
|
||||||
|
|
||||||
//redis key失效监听
|
//redis key失效监听
|
||||||
@@ -73,6 +76,10 @@ public class RedisKeyExpirationListener implements MessageListener {
|
|||||||
log.info("监听到短信定时发放优惠券,sms_push_event任务Id: {}", expiredKey);
|
log.info("监听到短信定时发放优惠券,sms_push_event任务Id: {}", expiredKey);
|
||||||
String eventId = expiredKey.substring(RedisCst.classKeyExpired.EXPIRED_SMS.length());
|
String eventId = expiredKey.substring(RedisCst.classKeyExpired.EXPIRED_SMS.length());
|
||||||
smsPushEventService.sendPushEventCoupon(eventId);
|
smsPushEventService.sendPushEventCoupon(eventId);
|
||||||
|
} else if (expiredKey.startsWith(RedisCst.classKeyExpired.EXPIRED_WECHAT)) {
|
||||||
|
log.info("监听到公众号推送优惠券,ac_push_event任务Id: {}", expiredKey);
|
||||||
|
String eventId = expiredKey.substring(RedisCst.classKeyExpired.EXPIRED_WECHAT.length());
|
||||||
|
acPushEventService.sendPushEventCoupon(eventId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ public interface RedisCst {
|
|||||||
public static final String EXPIRED_COUPON = "expired:coupon:";
|
public static final String EXPIRED_COUPON = "expired:coupon:";
|
||||||
//短信定时发放 倒计时KEY
|
//短信定时发放 倒计时KEY
|
||||||
public static final String EXPIRED_SMS = "expired:sms:";
|
public static final String EXPIRED_SMS = "expired:sms:";
|
||||||
|
//公众号推送 倒计时KEY
|
||||||
|
public static final String EXPIRED_WECHAT = "expired:wechat:";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public interface AShopUserService {
|
|||||||
|
|
||||||
Page<ShopUserDTO> getPage(String key, Integer isVip, BigDecimal amount);
|
Page<ShopUserDTO> getPage(String key, Integer isVip, BigDecimal amount);
|
||||||
Page<ShopUser> getPushEventUser(SmsPushEventUser smsPushEventUser);
|
Page<ShopUser> getPushEventUser(SmsPushEventUser smsPushEventUser);
|
||||||
|
Page<ShopUser> getAcPushEventUser(SmsPushEventUser smsPushEventUser);
|
||||||
|
|
||||||
List<ShopUser> getPushEventUserList(SmsPushEventUser smsPushEventUser);
|
List<ShopUser> getPushEventUserList(SmsPushEventUser smsPushEventUser);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,132 @@
|
|||||||
|
|
||||||
|
package com.czg.market.dto;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
|
import com.czg.market.entity.SmsPushEventUser;
|
||||||
|
import com.czg.validator.group.InsertGroup;
|
||||||
|
import com.czg.validator.group.UpdateGroup;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import java.io.Serial;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号推送任务 实体类。
|
||||||
|
*
|
||||||
|
* @author ww
|
||||||
|
* @since 2025-10-20
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class AcPushEventDTO implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private Long shopId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1 全部用户 2范围用户 3 指定用户
|
||||||
|
*/
|
||||||
|
private Long userType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预计人数
|
||||||
|
*/
|
||||||
|
private Long estimateNum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实际人数
|
||||||
|
*/
|
||||||
|
private Long actualNum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 成功人数
|
||||||
|
*/
|
||||||
|
private Long successNum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定用户时 使用
|
||||||
|
*/
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 0待发送 1 发送中 2发送成功 -1失败
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家名称(客户)
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "商家名称不能为空", groups = {InsertGroup.class, UpdateGroup.class})
|
||||||
|
private String shopName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 活动描述(商品名称)
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "活动描述不能为空", groups = {InsertGroup.class, UpdateGroup.class})
|
||||||
|
private String activityDetail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 活动时间(发货时间)
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "活动时间不能为空", groups = {InsertGroup.class, UpdateGroup.class})
|
||||||
|
private String activityTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家地址(收货地址)
|
||||||
|
*/
|
||||||
|
private String address;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 赠送券信息[{"id":"268700","num":12,"title":"邀新10元优惠券"}]
|
||||||
|
*/
|
||||||
|
private String coupon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送类型 1 立即发送 2定时发送
|
||||||
|
*/
|
||||||
|
@NotNull(message = "发送类型不能为空", groups = {InsertGroup.class, UpdateGroup.class})
|
||||||
|
private Integer sendType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送时间
|
||||||
|
*/
|
||||||
|
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime sendTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 失败原因
|
||||||
|
*/
|
||||||
|
private String error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 逻辑删除
|
||||||
|
*/
|
||||||
|
private Integer isDel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送的用户信息选项
|
||||||
|
* userType为2时 使用
|
||||||
|
*/
|
||||||
|
private SmsPushEventUser pushEventUser;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
package com.czg.market.entity;
|
||||||
|
|
||||||
|
import com.mybatisflex.annotation.Column;
|
||||||
|
import com.mybatisflex.annotation.Id;
|
||||||
|
import com.mybatisflex.annotation.KeyType;
|
||||||
|
import com.mybatisflex.annotation.Table;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号推送任务 实体类。
|
||||||
|
*
|
||||||
|
* @author ww
|
||||||
|
* @since 2025-10-20
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Table("ac_push_event")
|
||||||
|
public class AcPushEvent implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Id(keyType = KeyType.Auto)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private Long shopId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1 全部用户 2范围用户 3 指定用户
|
||||||
|
*/
|
||||||
|
private Long userType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预计人数
|
||||||
|
*/
|
||||||
|
private Long estimateNum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实际人数
|
||||||
|
*/
|
||||||
|
private Long actualNum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 成功人数
|
||||||
|
*/
|
||||||
|
private Long successNum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定用户时 使用
|
||||||
|
*/
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 0待发送 1 发送中 2发送成功 -1失败
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家名称(客户)
|
||||||
|
*/
|
||||||
|
private String shopName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 活动描述(商品名称)
|
||||||
|
*/
|
||||||
|
private String activityDetail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 活动时间(发货时间)
|
||||||
|
*/
|
||||||
|
private String activityTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家地址(收货地址)
|
||||||
|
*/
|
||||||
|
private String address;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 赠送券信息[{"id":"268700","num":12,"title":"邀新10元优惠券"}]
|
||||||
|
*/
|
||||||
|
private String coupon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送类型 1 立即发送 2定时发送
|
||||||
|
*/
|
||||||
|
private Integer sendType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime sendTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@Column(onInsertValue = "now()")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
@Column(onInsertValue = "now()", onUpdateValue = "now()")
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 失败原因
|
||||||
|
*/
|
||||||
|
private String error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 逻辑删除
|
||||||
|
*/
|
||||||
|
@Column(isLogicDelete = true)
|
||||||
|
private Integer isDel;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.czg.market.service;
|
||||||
|
|
||||||
|
import com.czg.market.dto.AcPushEventDTO;
|
||||||
|
import com.mybatisflex.core.paginate.Page;
|
||||||
|
import com.mybatisflex.core.service.IService;
|
||||||
|
import com.czg.market.entity.AcPushEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号推送任务 服务层。
|
||||||
|
*
|
||||||
|
* @author ww
|
||||||
|
* @since 2025-10-20
|
||||||
|
*/
|
||||||
|
public interface AcPushEventService extends IService<AcPushEvent> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询公众号推送任务列表
|
||||||
|
*/
|
||||||
|
Page<AcPushEventDTO> getPushEventPage(Integer page, Integer size, Long shopId, Integer status, Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加公众号推送任务
|
||||||
|
*/
|
||||||
|
void addPushEvent(AcPushEventDTO param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送公众号推送任务中的优惠券
|
||||||
|
*/
|
||||||
|
void sendPushEventCoupon(String eventId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新公众号推送任务
|
||||||
|
*/
|
||||||
|
void upPushEvent(AcPushEventDTO param);
|
||||||
|
|
||||||
|
void deletePushEvent(Long id);
|
||||||
|
}
|
||||||
@@ -1,16 +1,13 @@
|
|||||||
package com.czg.market.service;
|
package com.czg.market.service;
|
||||||
|
|
||||||
import com.czg.account.dto.QueryReceiveDto;
|
import com.czg.account.dto.QueryReceiveDto;
|
||||||
import com.czg.account.entity.ShopUser;
|
|
||||||
import com.czg.account.vo.CouponReceiveVo;
|
import com.czg.account.vo.CouponReceiveVo;
|
||||||
import com.czg.account.vo.UserCouponVo;
|
import com.czg.account.vo.UserCouponVo;
|
||||||
import com.czg.market.dto.MkRewardCouponDTO;
|
import com.czg.market.dto.*;
|
||||||
import com.czg.market.dto.MkShopCouponGiftDTO;
|
import com.czg.market.entity.MkShopCouponRecord;
|
||||||
import com.czg.market.dto.MkShopCouponRecordDTO;
|
|
||||||
import com.czg.market.vo.UserCouponVO;
|
import com.czg.market.vo.UserCouponVO;
|
||||||
import com.mybatisflex.core.paginate.Page;
|
import com.mybatisflex.core.paginate.Page;
|
||||||
import com.mybatisflex.core.service.IService;
|
import com.mybatisflex.core.service.IService;
|
||||||
import com.czg.market.entity.MkShopCouponRecord;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -48,13 +45,13 @@ public interface MkShopCouponRecordService extends IService<MkShopCouponRecord>
|
|||||||
*/
|
*/
|
||||||
void receiveCoupon(MkShopCouponGiftDTO giftDTO, Integer number, boolean isLimit);
|
void receiveCoupon(MkShopCouponGiftDTO giftDTO, Integer number, boolean isLimit);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发放券 批量发放 不计限领
|
* 短信/公众号 事件发送优惠券
|
||||||
* 检查优惠券状态 检查店铺ID是否存在且与发放店铺一致 检查优惠券是否失效
|
* 通过事件发放优惠券
|
||||||
* @param giftDTO 除 sourceFlowId shopUserId外 全必填 如果有 也填
|
|
||||||
* @param number 发放数量
|
|
||||||
*/
|
*/
|
||||||
void batchReceiveCoupon(MkShopCouponGiftDTO giftDTO, Integer number, List<ShopUser> userList);
|
void smsGrantCoupon(SmsPushEventDTO param);
|
||||||
|
void acGrantCoupon(AcPushEventDTO param);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户优惠券 失效/删除
|
* 用户优惠券 失效/删除
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public interface ShopUserMapper extends BaseMapper<ShopUser> {
|
|||||||
UserInfoAssetsSummaryDTO selectAssetsSummary(@Param("userId") Long userInfoId);
|
UserInfoAssetsSummaryDTO selectAssetsSummary(@Param("userId") Long userInfoId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询符合推送条件的用户
|
* 查询符合推送条件的用户 手机号不为空
|
||||||
*
|
*
|
||||||
* @param mainShopId 主店铺ID
|
* @param mainShopId 主店铺ID
|
||||||
* @param shopId 店铺ID
|
* @param shopId 店铺ID
|
||||||
@@ -49,4 +49,17 @@ public interface ShopUserMapper extends BaseMapper<ShopUser> {
|
|||||||
@Param("param") SmsPushEventUser smsPushEventUser
|
@Param("param") SmsPushEventUser smsPushEventUser
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询符合推送条件的用户 公众号Id不为空
|
||||||
|
*
|
||||||
|
* @param mainShopId 主店铺ID
|
||||||
|
* @param shopId 店铺ID
|
||||||
|
* @return 分页结果
|
||||||
|
*/
|
||||||
|
List<ShopUser> selectAcPushEventUser(
|
||||||
|
@Param("mainShopId") Long mainShopId,
|
||||||
|
@Param("shopId") Long shopId,
|
||||||
|
@Param("param") SmsPushEventUser smsPushEventUser
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ import org.apache.dubbo.config.annotation.DubboService;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
@@ -109,6 +108,22 @@ public class AShopUserServiceImpl implements AShopUserService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<ShopUser> getAcPushEventUser(SmsPushEventUser smsPushEventUser) {
|
||||||
|
try {
|
||||||
|
Long mainShopId = shopInfoService.getMainIdByShopId(smsPushEventUser.getShopId());
|
||||||
|
PageHelper.startPage(smsPushEventUser.getPage(), smsPushEventUser.getSize());
|
||||||
|
smsPushEventUser.checkIsAll();
|
||||||
|
// 调用Mapper层查询
|
||||||
|
List<ShopUser> shopUsers = shopUserMapper.selectAcPushEventUser(mainShopId,
|
||||||
|
smsPushEventUser.getShopId(), smsPushEventUser);
|
||||||
|
return PageUtil.convert(new PageInfo<>(shopUsers));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("获取公众号推送任务用户列表失败{},{}", smsPushEventUser, e.getMessage());
|
||||||
|
return PageUtil.convert(new PageInfo<>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ShopUser> getPushEventUserList(SmsPushEventUser smsPushEventUser) {
|
public List<ShopUser> getPushEventUserList(SmsPushEventUser smsPushEventUser) {
|
||||||
Long mainShopId = shopInfoService.getMainIdByShopId(smsPushEventUser.getShopId());
|
Long mainShopId = shopInfoService.getMainIdByShopId(smsPushEventUser.getShopId());
|
||||||
|
|||||||
@@ -190,4 +190,77 @@
|
|||||||
order by u.create_time desc
|
order by u.create_time desc
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectAcPushEventUser" resultType="com.czg.account.entity.ShopUser">
|
||||||
|
SELECT DISTINCT
|
||||||
|
u.id,u.user_id, u.head_img, u.nick_name, u.amount, u.account_points, u.phone,
|
||||||
|
<choose>
|
||||||
|
<!-- 当有筛选条件时才计算订单相关字段 -->
|
||||||
|
<when test="param.orderTimeToday == 1 or param.orderTimeYesterday == 1 or
|
||||||
|
param.orderTimeTwoWeeks == 1 or param.orderTimeMoreThanTwoWeeks == 1 or
|
||||||
|
param.noOrder == 1 or param.oneOrder == 1 or param.fiveOrder == 1">
|
||||||
|
COUNT(o.id) AS order_count,
|
||||||
|
SUM(CASE WHEN o.trade_day = CURDATE() THEN 1 ELSE 0 END) AS today_orders,
|
||||||
|
SUM(CASE WHEN o.trade_day = CURDATE() - INTERVAL 1 DAY THEN 1 ELSE 0 END) AS yesterday_orders,
|
||||||
|
SUM(CASE WHEN o.trade_day >= CURDATE() - INTERVAL 2 WEEK AND o.trade_day < CURDATE() - INTERVAL 1
|
||||||
|
DAY
|
||||||
|
THEN 1 ELSE 0 END) AS two_weeks_orders,
|
||||||
|
SUM(CASE WHEN o.trade_day < CURDATE() - INTERVAL 2 WEEK THEN 1 ELSE 0 END) AS earlier_orders
|
||||||
|
</when>
|
||||||
|
<!-- 无筛选条件时不计算订单相关字段 -->
|
||||||
|
<otherwise>
|
||||||
|
0 AS order_count,
|
||||||
|
0 AS today_orders,
|
||||||
|
0 AS yesterday_orders,
|
||||||
|
0 AS two_weeks_orders,
|
||||||
|
0 AS earlier_orders
|
||||||
|
</otherwise>
|
||||||
|
</choose>
|
||||||
|
FROM tb_shop_user u
|
||||||
|
inner join tb_user_info user on u.user_id = user.id and user.wechat_ac_open_id is not null
|
||||||
|
<!-- 只有当有筛选条件时才关联order表 -->
|
||||||
|
<if test="param.orderTimeToday == 1 or param.orderTimeYesterday == 1 or
|
||||||
|
param.orderTimeTwoWeeks == 1 or param.orderTimeMoreThanTwoWeeks == 1 or
|
||||||
|
param.noOrder == 1 or param.oneOrder == 1 or param.fiveOrder == 1">
|
||||||
|
LEFT JOIN `tb_order_info` o ON u.user_id = o.user_id and o.user_id is not null AND o.shop_id = #{shopId}
|
||||||
|
AND o.status = 'done'
|
||||||
|
</if>
|
||||||
|
WHERE u.main_shop_id = #{mainShopId} and u.user_id is not null
|
||||||
|
<!-- 性别筛选条件 -->
|
||||||
|
<if test="!(param.sexMan == 1 and param.sexWoman == 1 and param.sexUnknown == 1)
|
||||||
|
and (param.sexMan == 1 or param.sexWoman == 1 or param.sexUnknown == 1)">
|
||||||
|
AND
|
||||||
|
<trim prefix="(" suffix=")" prefixOverrides="OR">
|
||||||
|
<if test="param.sexMan == 1">OR u.sex = 1</if>
|
||||||
|
<if test="param.sexWoman == 1">OR u.sex = 0</if>
|
||||||
|
<if test="param.sexUnknown == 1">OR u.sex IS NULL</if>
|
||||||
|
</trim>
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<!-- 会员状态筛选 -->
|
||||||
|
<if test="param.isVip != null">
|
||||||
|
AND u.is_vip = #{param.isVip}
|
||||||
|
</if>
|
||||||
|
|
||||||
|
<if test="param.isRecharge != null">
|
||||||
|
AND u.recharge_count <![CDATA[ ${param.isRecharge == 0 ? '=' : '>'} ]]> 0
|
||||||
|
</if>
|
||||||
|
<!-- 只有当有筛选条件时才需要HAVING子句 -->
|
||||||
|
<if test="param.orderTimeToday == 1 or param.orderTimeYesterday == 1 or
|
||||||
|
param.orderTimeTwoWeeks == 1 or param.orderTimeMoreThanTwoWeeks == 1 or
|
||||||
|
param.noOrder == 1 or param.oneOrder == 1 or param.fiveOrder == 1">
|
||||||
|
GROUP BY u.id
|
||||||
|
HAVING
|
||||||
|
<trim prefix="(" suffix=")" prefixOverrides="OR">
|
||||||
|
<if test="param.orderTimeToday == 1">OR today_orders > 0</if>
|
||||||
|
<if test="param.orderTimeYesterday == 1">OR yesterday_orders > 0</if>
|
||||||
|
<if test="param.orderTimeTwoWeeks == 1">OR two_weeks_orders > 0</if>
|
||||||
|
<if test="param.orderTimeMoreThanTwoWeeks == 1">OR earlier_orders > 0</if>
|
||||||
|
|
||||||
|
<if test="param.noOrder == 1">OR order_count = 0</if>
|
||||||
|
<if test="param.oneOrder == 1">OR order_count = 1</if>
|
||||||
|
<if test="param.fiveOrder == 1">OR order_count >= 5</if>
|
||||||
|
</trim>
|
||||||
|
</if>
|
||||||
|
order by u.create_time desc
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.czg.service.market.mapper;
|
||||||
|
|
||||||
|
import com.mybatisflex.core.BaseMapper;
|
||||||
|
import com.czg.market.entity.AcPushEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号推送任务 映射层。
|
||||||
|
*
|
||||||
|
* @author ww
|
||||||
|
* @since 2025-10-20
|
||||||
|
*/
|
||||||
|
public interface AcPushEventMapper extends BaseMapper<AcPushEvent> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
package com.czg.service.market.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.czg.account.service.ShopInfoService;
|
||||||
|
import com.czg.config.RabbitPublisher;
|
||||||
|
import com.czg.config.RedisCst;
|
||||||
|
import com.czg.exception.CzgException;
|
||||||
|
import com.czg.market.dto.AcPushEventDTO;
|
||||||
|
import com.czg.market.entity.AcPushEvent;
|
||||||
|
import com.czg.market.entity.SmsPushEvent;
|
||||||
|
import com.czg.market.entity.SmsPushEventUser;
|
||||||
|
import com.czg.market.service.AcPushEventService;
|
||||||
|
import com.czg.market.service.MkShopCouponRecordService;
|
||||||
|
import com.czg.service.RedisService;
|
||||||
|
import com.czg.service.market.mapper.AcPushEventMapper;
|
||||||
|
import com.czg.service.market.mapper.SmsPushEventUserMapper;
|
||||||
|
import com.czg.utils.AssertUtil;
|
||||||
|
import com.mybatisflex.core.paginate.Page;
|
||||||
|
import com.mybatisflex.core.query.QueryWrapper;
|
||||||
|
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.dubbo.config.annotation.DubboReference;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号推送任务 服务层实现。
|
||||||
|
*
|
||||||
|
* @author ww
|
||||||
|
* @since 2025-10-20
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class AcPushEventServiceImpl extends ServiceImpl<AcPushEventMapper, AcPushEvent> implements AcPushEventService {
|
||||||
|
@Resource
|
||||||
|
private SmsPushEventUserMapper eventUserMapper;
|
||||||
|
@DubboReference
|
||||||
|
private ShopInfoService shopInfoService;
|
||||||
|
@Resource
|
||||||
|
private MkShopCouponRecordService couponRecordService;
|
||||||
|
@Resource
|
||||||
|
private RabbitPublisher rabbitPublisher;
|
||||||
|
@Resource
|
||||||
|
private RedisService redisService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<AcPushEventDTO> getPushEventPage(Integer page, Integer size, Long shopId, Integer status, Long id) {
|
||||||
|
QueryWrapper queryWrapper = new QueryWrapper();
|
||||||
|
queryWrapper.eq(SmsPushEvent::getShopId, shopId)
|
||||||
|
.eq(SmsPushEvent::getId, id)
|
||||||
|
.eq(SmsPushEvent::getStatus, status)
|
||||||
|
.eq(SmsPushEvent::getIsDel, 0)
|
||||||
|
.orderBy(SmsPushEvent::getCreateTime).desc();
|
||||||
|
Page<AcPushEventDTO> page1 = pageAs(new Page<>(page, size), queryWrapper, AcPushEventDTO.class);
|
||||||
|
for (AcPushEventDTO record : page1.getRecords()) {
|
||||||
|
if (record.getUserType() != 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
SmsPushEventUser eventUser = eventUserMapper.selectOneByQuery(
|
||||||
|
new QueryWrapper()
|
||||||
|
.eq(SmsPushEventUser::getType, "ac")
|
||||||
|
.eq(SmsPushEventUser::getEventId, record.getId())
|
||||||
|
);
|
||||||
|
record.setPushEventUser(eventUser);
|
||||||
|
}
|
||||||
|
return page1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addPushEvent(AcPushEventDTO param) {
|
||||||
|
AssertUtil.isNull(param.getUserType(), "请选择用户范围后进行推送");
|
||||||
|
if (param.getUserType() == 2 && param.getPushEventUser() == null) {
|
||||||
|
throw new CzgException("范围推送时,必须指定用户范围");
|
||||||
|
} else if (param.getUserType() == 3 && param.getUserId() == null) {
|
||||||
|
throw new CzgException("指定推送时,必须指定用户");
|
||||||
|
}
|
||||||
|
if (param.getSendType() == 2) {
|
||||||
|
AssertUtil.isNull(param.getSendTime(), "定时发送时,必须指定发送时间");
|
||||||
|
} else {
|
||||||
|
param.setSendTime(LocalDateTime.now());
|
||||||
|
}
|
||||||
|
AcPushEvent pushEvent = BeanUtil.toBean(param, AcPushEvent.class);
|
||||||
|
save(pushEvent);
|
||||||
|
if (param.getUserType() == 2) {
|
||||||
|
SmsPushEventUser eventUser = param.getPushEventUser();
|
||||||
|
eventUser.setType("ac");
|
||||||
|
eventUser.setShopId(param.getShopId());
|
||||||
|
eventUser.setEventId(pushEvent.getId());
|
||||||
|
eventUserMapper.insert(eventUser);
|
||||||
|
}
|
||||||
|
param.setId(pushEvent.getId());
|
||||||
|
Long mainShopId = shopInfoService.getMainIdByShopId(param.getShopId());
|
||||||
|
// 推送消息 进行 消息发送
|
||||||
|
rabbitPublisher.sendApplySmsMsg(mainShopId + "," + pushEvent.getId(), "sendWechatTemp");
|
||||||
|
if (param.getSendType() == 1 && StrUtil.isNotBlank(param.getCoupon())) {
|
||||||
|
couponRecordService.acGrantCoupon(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendPushEventCoupon(String eventId) {
|
||||||
|
AcPushEvent acPushEvent = getOne(new QueryWrapper().eq(AcPushEvent::getId, eventId));
|
||||||
|
AssertUtil.isNull(acPushEvent, "券发放失败,推送事件不存在");
|
||||||
|
if (StrUtil.isNotBlank(acPushEvent.getCoupon())) {
|
||||||
|
AcPushEventDTO pushEvent = BeanUtil.toBean(acPushEvent, AcPushEventDTO.class);
|
||||||
|
SmsPushEventUser eventUser = eventUserMapper.selectOneByQuery(
|
||||||
|
new QueryWrapper()
|
||||||
|
.eq(SmsPushEventUser::getType, "ac")
|
||||||
|
.eq(SmsPushEventUser::getEventId, eventId)
|
||||||
|
);
|
||||||
|
pushEvent.setPushEventUser(eventUser);
|
||||||
|
couponRecordService.acGrantCoupon(pushEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void upPushEvent(AcPushEventDTO param) {
|
||||||
|
AssertUtil.isNull(param.getUserType(), "请选择用户范围后进行推送");
|
||||||
|
if (param.getUserType() == 2 && param.getPushEventUser() == null) {
|
||||||
|
throw new CzgException("范围推送时,必须指定用户范围");
|
||||||
|
} else if (param.getUserType() == 3 && param.getUserId() == null) {
|
||||||
|
throw new CzgException("指定推送时,必须指定用户");
|
||||||
|
}
|
||||||
|
if (param.getSendType() == 2) {
|
||||||
|
AssertUtil.isNull(param.getSendTime(), "定时发送时,必须指定发送时间");
|
||||||
|
} else {
|
||||||
|
param.setSendTime(LocalDateTime.now());
|
||||||
|
}
|
||||||
|
AcPushEvent pushEvent = BeanUtil.toBean(param, AcPushEvent.class);
|
||||||
|
updateById(pushEvent);
|
||||||
|
eventUserMapper.deleteByQuery(new QueryWrapper()
|
||||||
|
.eq(SmsPushEventUser::getType, "ac")
|
||||||
|
.eq(SmsPushEventUser::getEventId, pushEvent.getId()));
|
||||||
|
if (param.getUserType() == 2) {
|
||||||
|
SmsPushEventUser eventUser = param.getPushEventUser();
|
||||||
|
eventUser.setType("ac");
|
||||||
|
eventUser.setShopId(param.getShopId());
|
||||||
|
eventUser.setEventId(pushEvent.getId());
|
||||||
|
eventUserMapper.insert(eventUser);
|
||||||
|
}
|
||||||
|
Long mainShopId = shopInfoService.getMainIdByShopId(param.getShopId());
|
||||||
|
// 推送消息 进行 消息发送
|
||||||
|
rabbitPublisher.sendApplySmsMsg(mainShopId + "," + pushEvent.getId(), "sendWechatTemp");
|
||||||
|
if (param.getSendType() == 1 && StrUtil.isNotBlank(param.getCoupon())) {
|
||||||
|
couponRecordService.acGrantCoupon(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deletePushEvent(Long id) {
|
||||||
|
AcPushEvent pushEvent = getById(id);
|
||||||
|
AssertUtil.isNull(pushEvent, "记录不存在");
|
||||||
|
if (pushEvent.getStatus() == 2) {
|
||||||
|
throw new CzgException("已发送的记录不能删除");
|
||||||
|
}
|
||||||
|
redisService.del(RedisCst.classKeyExpired.EXPIRED_WECHAT + id);
|
||||||
|
pushEvent.setIsDel(1);
|
||||||
|
updateById(pushEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,22 +2,24 @@ package com.czg.service.market.service.impl;
|
|||||||
|
|
||||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.czg.account.dto.QueryReceiveDto;
|
import com.czg.account.dto.QueryReceiveDto;
|
||||||
import com.czg.account.entity.ShopInfo;
|
import com.czg.account.entity.ShopInfo;
|
||||||
import com.czg.account.entity.ShopUser;
|
import com.czg.account.entity.ShopUser;
|
||||||
import com.czg.account.entity.UserInfo;
|
import com.czg.account.entity.UserInfo;
|
||||||
|
import com.czg.account.service.AShopUserService;
|
||||||
import com.czg.account.service.ShopInfoService;
|
import com.czg.account.service.ShopInfoService;
|
||||||
import com.czg.account.service.ShopUserService;
|
import com.czg.account.service.ShopUserService;
|
||||||
import com.czg.account.service.UserInfoService;
|
import com.czg.account.service.UserInfoService;
|
||||||
import com.czg.account.vo.CouponReceiveVo;
|
import com.czg.account.vo.CouponReceiveVo;
|
||||||
import com.czg.account.vo.UserCouponVo;
|
import com.czg.account.vo.UserCouponVo;
|
||||||
import com.czg.exception.CzgException;
|
import com.czg.exception.CzgException;
|
||||||
import com.czg.market.dto.MkRewardCouponDTO;
|
import com.czg.market.dto.*;
|
||||||
import com.czg.market.dto.MkShopCouponGiftDTO;
|
|
||||||
import com.czg.market.dto.MkShopCouponRecordDTO;
|
|
||||||
import com.czg.market.entity.MkShopCouponRecord;
|
import com.czg.market.entity.MkShopCouponRecord;
|
||||||
import com.czg.market.entity.ShopCoupon;
|
import com.czg.market.entity.ShopCoupon;
|
||||||
|
import com.czg.market.entity.SmsPushEventUser;
|
||||||
import com.czg.market.service.MkShopCouponRecordService;
|
import com.czg.market.service.MkShopCouponRecordService;
|
||||||
import com.czg.market.vo.UserCouponVO;
|
import com.czg.market.vo.UserCouponVO;
|
||||||
import com.czg.service.market.mapper.MkShopCouponRecordMapper;
|
import com.czg.service.market.mapper.MkShopCouponRecordMapper;
|
||||||
@@ -29,6 +31,7 @@ import com.mybatisflex.core.paginate.Page;
|
|||||||
import com.mybatisflex.core.query.QueryWrapper;
|
import com.mybatisflex.core.query.QueryWrapper;
|
||||||
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.dubbo.config.annotation.DubboReference;
|
import org.apache.dubbo.config.annotation.DubboReference;
|
||||||
import org.apache.dubbo.config.annotation.DubboService;
|
import org.apache.dubbo.config.annotation.DubboService;
|
||||||
|
|
||||||
@@ -37,6 +40,7 @@ import java.time.LocalTime;
|
|||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 优惠券发放记录表 服务层实现。
|
* 优惠券发放记录表 服务层实现。
|
||||||
@@ -44,6 +48,7 @@ import java.util.List;
|
|||||||
* @author ww
|
* @author ww
|
||||||
* @since 2025-09-13
|
* @since 2025-09-13
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@DubboService
|
@DubboService
|
||||||
public class MkShopCouponRecordServiceImpl extends ServiceImpl<MkShopCouponRecordMapper, MkShopCouponRecord> implements MkShopCouponRecordService {
|
public class MkShopCouponRecordServiceImpl extends ServiceImpl<MkShopCouponRecordMapper, MkShopCouponRecord> implements MkShopCouponRecordService {
|
||||||
|
|
||||||
@@ -54,6 +59,8 @@ public class MkShopCouponRecordServiceImpl extends ServiceImpl<MkShopCouponRecor
|
|||||||
private ShopInfoService shopInfoService;
|
private ShopInfoService shopInfoService;
|
||||||
@DubboReference
|
@DubboReference
|
||||||
private ShopUserService shopUserService;
|
private ShopUserService shopUserService;
|
||||||
|
@DubboReference
|
||||||
|
private AShopUserService aShopUserService;
|
||||||
@Resource
|
@Resource
|
||||||
private ShopCouponMapper couponService;
|
private ShopCouponMapper couponService;
|
||||||
|
|
||||||
@@ -177,6 +184,77 @@ public class MkShopCouponRecordServiceImpl extends ServiceImpl<MkShopCouponRecor
|
|||||||
return recordPage;
|
return recordPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void acGrantCoupon(AcPushEventDTO param) {
|
||||||
|
//发放优惠券
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
try {
|
||||||
|
SmsPushEventUser smsPushEventUser = param.getPushEventUser();
|
||||||
|
List<ShopUser> userList = new ArrayList<>();
|
||||||
|
if (param.getUserType() == 1) {
|
||||||
|
smsPushEventUser = new SmsPushEventUser();
|
||||||
|
smsPushEventUser.setShopId(param.getShopId());
|
||||||
|
smsPushEventUser.setIsAll(1);
|
||||||
|
}
|
||||||
|
userList = aShopUserService.getPushEventUserList(smsPushEventUser);
|
||||||
|
// 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("营销短信发放");
|
||||||
|
batchReceiveCoupon(giftDTO, num, userList);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("异步发放优惠券失败", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void smsGrantCoupon(SmsPushEventDTO param) {
|
||||||
|
//发放优惠券
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
try {
|
||||||
|
SmsPushEventUser smsPushEventUser = param.getSmsPushEventUser();
|
||||||
|
List<ShopUser> userList = new ArrayList<>();
|
||||||
|
if (param.getUserType() == 1) {
|
||||||
|
smsPushEventUser = new SmsPushEventUser();
|
||||||
|
smsPushEventUser.setShopId(param.getShopId());
|
||||||
|
smsPushEventUser.setIsAll(1);
|
||||||
|
}
|
||||||
|
userList = aShopUserService.getPushEventUserList(smsPushEventUser);
|
||||||
|
// 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("营销短信发放");
|
||||||
|
batchReceiveCoupon(giftDTO, num, userList);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("异步发放优惠券失败", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void receiveCoupon(MkShopCouponGiftDTO giftDTO, Integer number, boolean isLimit) {
|
public void receiveCoupon(MkShopCouponGiftDTO giftDTO, Integer number, boolean isLimit) {
|
||||||
@@ -271,8 +349,13 @@ public class MkShopCouponRecordServiceImpl extends ServiceImpl<MkShopCouponRecor
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public void batchReceiveCoupon(MkShopCouponGiftDTO giftDTO, Integer number, List<ShopUser> userList) {
|
* 发放券 批量发放 不计限领
|
||||||
|
* 检查优惠券状态 检查店铺ID是否存在且与发放店铺一致 检查优惠券是否失效
|
||||||
|
* @param giftDTO 除 sourceFlowId shopUserId外 全必填 如果有 也填
|
||||||
|
* @param number 发放数量
|
||||||
|
*/
|
||||||
|
private void batchReceiveCoupon(MkShopCouponGiftDTO giftDTO, Integer number, List<ShopUser> userList) {
|
||||||
if (number == null || number <= 0) {
|
if (number == null || number <= 0) {
|
||||||
throw new CzgException("发放数量不能小于0");
|
throw new CzgException("发放数量不能小于0");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,10 @@ package com.czg.service.market.service.impl;
|
|||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.czg.account.service.ShopInfoService;
|
||||||
import com.alibaba.fastjson2.JSONArray;
|
|
||||||
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.RabbitPublisher;
|
||||||
import com.czg.config.RedisCst;
|
import com.czg.config.RedisCst;
|
||||||
import com.czg.exception.CzgException;
|
import com.czg.exception.CzgException;
|
||||||
import com.czg.market.dto.MkShopCouponGiftDTO;
|
|
||||||
import com.czg.market.dto.SmsPushEventDTO;
|
import com.czg.market.dto.SmsPushEventDTO;
|
||||||
import com.czg.market.entity.SmsPushEvent;
|
import com.czg.market.entity.SmsPushEvent;
|
||||||
import com.czg.market.entity.SmsPushEventUser;
|
import com.czg.market.entity.SmsPushEventUser;
|
||||||
@@ -30,9 +25,6 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 营销推送发送记录 服务层实现。
|
* 营销推送发送记录 服务层实现。
|
||||||
@@ -46,10 +38,10 @@ public class SmsPushEventServiceImpl extends ServiceImpl<SmsPushEventMapper, Sms
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private SmsPushEventUserMapper eventUserMapper;
|
private SmsPushEventUserMapper eventUserMapper;
|
||||||
|
@DubboReference
|
||||||
|
private ShopInfoService shopInfoService;
|
||||||
@Resource
|
@Resource
|
||||||
private MkShopCouponRecordService couponRecordService;
|
private MkShopCouponRecordService couponRecordService;
|
||||||
@DubboReference
|
|
||||||
private AShopUserService shopUserService;
|
|
||||||
@Resource
|
@Resource
|
||||||
private RabbitPublisher rabbitPublisher;
|
private RabbitPublisher rabbitPublisher;
|
||||||
@Resource
|
@Resource
|
||||||
@@ -104,10 +96,11 @@ public class SmsPushEventServiceImpl extends ServiceImpl<SmsPushEventMapper, Sms
|
|||||||
eventUserMapper.insert(eventUser);
|
eventUserMapper.insert(eventUser);
|
||||||
}
|
}
|
||||||
param.setId(pushEvent.getId());
|
param.setId(pushEvent.getId());
|
||||||
|
Long mainShopId = shopInfoService.getMainIdByShopId(param.getShopId());
|
||||||
// 推送消息 进行 消息发送
|
// 推送消息 进行 消息发送
|
||||||
rabbitPublisher.sendApplySmsMsg(pushEvent.getShopId() + "," + pushEvent.getId(), "sendMarkSms");
|
rabbitPublisher.sendApplySmsMsg(mainShopId + "," + pushEvent.getId(), "sendMarkSms");
|
||||||
if (param.getSendType() == 1 && StrUtil.isNotBlank(param.getCoupon())) {
|
if (param.getSendType() == 1 && StrUtil.isNotBlank(param.getCoupon())) {
|
||||||
grantCoupon(param);
|
couponRecordService.smsGrantCoupon(param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,66 +130,30 @@ public class SmsPushEventServiceImpl extends ServiceImpl<SmsPushEventMapper, Sms
|
|||||||
eventUser.setEventId(pushEvent.getId());
|
eventUser.setEventId(pushEvent.getId());
|
||||||
eventUserMapper.insert(eventUser);
|
eventUserMapper.insert(eventUser);
|
||||||
}
|
}
|
||||||
|
Long mainShopId = shopInfoService.getMainIdByShopId(param.getShopId());
|
||||||
// 推送消息 进行 消息发送
|
// 推送消息 进行 消息发送
|
||||||
rabbitPublisher.sendApplySmsMsg(pushEvent.getShopId() + "," + pushEvent.getId(), "sendMarkSms");
|
rabbitPublisher.sendApplySmsMsg(mainShopId + "," + pushEvent.getId(), "sendMarkSms");
|
||||||
//发放优惠券
|
if (param.getSendType() == 1 && StrUtil.isNotBlank(param.getCoupon())) {
|
||||||
grantCoupon(param);
|
couponRecordService.smsGrantCoupon(param);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendPushEventCoupon(String eventId) {
|
public void sendPushEventCoupon(String eventId) {
|
||||||
SmsPushEvent smsPushEvent = getOne(new QueryWrapper().eq(SmsPushEvent::getId, eventId));
|
SmsPushEvent smsPushEvent = getOne(new QueryWrapper().eq(SmsPushEvent::getId, eventId));
|
||||||
AssertUtil.isNull(smsPushEvent, "券发放失败,推送事件不存在");
|
AssertUtil.isNull(smsPushEvent, "券发放失败,推送事件不存在");
|
||||||
SmsPushEventDTO pushEvent = BeanUtil.toBean(smsPushEvent, SmsPushEventDTO.class);
|
if (StrUtil.isNotBlank(smsPushEvent.getCoupon())) {
|
||||||
SmsPushEventUser eventUser = eventUserMapper.selectOneByQuery(
|
SmsPushEventDTO pushEvent = BeanUtil.toBean(smsPushEvent, SmsPushEventDTO.class);
|
||||||
new QueryWrapper()
|
SmsPushEventUser eventUser = eventUserMapper.selectOneByQuery(
|
||||||
.eq(SmsPushEventUser::getType, "sms")
|
new QueryWrapper()
|
||||||
.eq(SmsPushEventUser::getEventId, eventId)
|
.eq(SmsPushEventUser::getType, "sms")
|
||||||
);
|
.eq(SmsPushEventUser::getEventId, eventId)
|
||||||
pushEvent.setSmsPushEventUser(eventUser);
|
);
|
||||||
if (StrUtil.isNotBlank(pushEvent.getCoupon())) {
|
pushEvent.setSmsPushEventUser(eventUser);
|
||||||
grantCoupon(pushEvent);
|
couponRecordService.smsGrantCoupon(pushEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 发放优惠券
|
|
||||||
private void grantCoupon(SmsPushEventDTO param) {
|
|
||||||
//发放优惠券
|
|
||||||
CompletableFuture.runAsync(() -> {
|
|
||||||
try {
|
|
||||||
SmsPushEventUser smsPushEventUser = param.getSmsPushEventUser();
|
|
||||||
List<ShopUser> userList = new ArrayList<>();
|
|
||||||
if (param.getUserType() == 1) {
|
|
||||||
smsPushEventUser = new SmsPushEventUser();
|
|
||||||
smsPushEventUser.setShopId(param.getShopId());
|
|
||||||
smsPushEventUser.setIsAll(1);
|
|
||||||
}
|
|
||||||
userList = shopUserService.getPushEventUserList(smsPushEventUser);
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("异步发放优惠券失败", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 逻辑删除记录
|
* 逻辑删除记录
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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.AcPushEventMapper">
|
||||||
|
|
||||||
|
</mapper>
|
||||||
Reference in New Issue
Block a user