From 4062cdea5708d8655f8199dfd0466e78363e51b7 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Tue, 14 Oct 2025 17:57:32 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9F=AD=E4=BF=A1=E6=8E=A8=E9=80=81=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/SmsPushEventController.java | 60 ++++++++++ .../admin/SmsShopTemplateController.java | 2 - .../com/czg/market/dto/SmsPushEventDTO.java | 109 ++++++++++++++++++ .../com/czg/market/entity/SmsPushEvent.java | 101 ++++++++++++++++ .../czg/market/entity/SmsPushEventUser.java | 81 +++++++++++++ .../market/service/SmsPushEventService.java | 29 +++++ .../market/mapper/SmsPushEventMapper.java | 14 +++ .../market/mapper/SmsPushEventUserMapper.java | 14 +++ .../service/impl/SmsPushEventServiceImpl.java | 98 ++++++++++++++++ .../resources/mapper/SmsPushEventMapper.xml | 7 ++ .../mapper/SmsPushEventUserMapper.xml | 7 ++ 11 files changed, 520 insertions(+), 2 deletions(-) create mode 100644 cash-api/market-server/src/main/java/com/czg/controller/admin/SmsPushEventController.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/dto/SmsPushEventDTO.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/entity/SmsPushEvent.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/entity/SmsPushEventUser.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/service/SmsPushEventService.java create mode 100644 cash-service/market-service/src/main/java/com/czg/service/market/mapper/SmsPushEventMapper.java create mode 100644 cash-service/market-service/src/main/java/com/czg/service/market/mapper/SmsPushEventUserMapper.java create mode 100644 cash-service/market-service/src/main/java/com/czg/service/market/service/impl/SmsPushEventServiceImpl.java create mode 100644 cash-service/market-service/src/main/resources/mapper/SmsPushEventMapper.xml create mode 100644 cash-service/market-service/src/main/resources/mapper/SmsPushEventUserMapper.xml diff --git a/cash-api/market-server/src/main/java/com/czg/controller/admin/SmsPushEventController.java b/cash-api/market-server/src/main/java/com/czg/controller/admin/SmsPushEventController.java new file mode 100644 index 00000000..96c0d291 --- /dev/null +++ b/cash-api/market-server/src/main/java/com/czg/controller/admin/SmsPushEventController.java @@ -0,0 +1,60 @@ +package com.czg.controller.admin; + +import com.czg.BaseQueryParam; +import com.czg.market.dto.SmsPushEventDTO; +import com.czg.market.dto.SmsShopTemplateDTO; +import com.czg.market.service.SmsPushEventService; +import com.czg.market.service.SmsShopTemplateService; +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.*; + +import java.util.List; + +/** + * 短信推送任务 + * + * @author ww + * @description + */ +@Slf4j +@RestController +@RequestMapping("/admin/pushEvent") +public class SmsPushEventController { + @Resource + private SmsPushEventService pushEventService; + + /** + * 列表 + */ + @GetMapping + public CzgResult> getPushEventPage(@RequestParam BaseQueryParam param, @RequestParam(required = false) Long id) { + Page data = pushEventService.getPushEventPage(param, StpKit.USER.getShopId(), id); + return CzgResult.success(data); + } + + /** + * 新增 + */ + @PostMapping + public CzgResult addPushEvent(@RequestBody @Validated(InsertGroup.class) SmsPushEventDTO param) { + param.setShopId(StpKit.USER.getShopId()); + pushEventService.addPushEvent(param); + return CzgResult.success(); + } + + /** + * 删除任务 + */ + @DeleteMapping("/{id}") + public CzgResult deletePushEvent(@PathVariable Long id) { + pushEventService.deletePushEvent(id); + return CzgResult.success(); + } +} diff --git a/cash-api/market-server/src/main/java/com/czg/controller/admin/SmsShopTemplateController.java b/cash-api/market-server/src/main/java/com/czg/controller/admin/SmsShopTemplateController.java index ab0d539a..ceb79f71 100644 --- a/cash-api/market-server/src/main/java/com/czg/controller/admin/SmsShopTemplateController.java +++ b/cash-api/market-server/src/main/java/com/czg/controller/admin/SmsShopTemplateController.java @@ -1,8 +1,6 @@ package com.czg.controller.admin; -import com.czg.config.RabbitPublisher; import com.czg.market.dto.SmsShopTemplateDTO; -import com.czg.market.service.ShopCouponService; import com.czg.market.service.SmsShopTemplateService; import com.czg.resp.CzgResult; import com.czg.sa.StpKit; diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/dto/SmsPushEventDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/market/dto/SmsPushEventDTO.java new file mode 100644 index 00000000..d75de158 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/dto/SmsPushEventDTO.java @@ -0,0 +1,109 @@ + +package com.czg.market.dto; + +import java.io.Serializable; +import java.time.LocalDateTime; + +import com.alibaba.fastjson2.annotation.JSONField; + +import java.io.Serial; + +import com.czg.market.entity.SmsPushEventUser; +import com.czg.validator.group.InsertGroup; +import com.czg.validator.group.UpdateGroup; +import com.mybatisflex.annotation.Column; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 营销推送发送记录 实体类。 + * + * @author ww + * @since 2025-10-14 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SmsPushEventDTO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private Long id; + + private Long shopId; + + /** + * 推送类型 1 模版推送 2短信推送 无用 暂留 + */ + private Integer pushType; + + /** + * 模板ID + */ + @NotNull(message = "模板ID不能为空", groups = InsertGroup.class) + private Long pushEventId; + + /** + * 1 全部用户 2范围用户 3 指定用户 指定暂定一个用户 + */ + @NotNull(message = "发送范围不能为空", groups = InsertGroup.class) + private Long userType; + + /** + * 指定用户时 使用 + */ + private String userId; + + /** + * 0待发送 1 发送中 2发送成功 -1失败 + */ + private Integer status; + + /** + * 发送内容 + */ + @NotBlank(message = "发送内容不能为空", groups = InsertGroup.class) + private String content; + + /** + * 赠送券信息[{"id":"268700","num":12,"title":"邀新10元优惠券"}] + */ + private String coupon; + + /** + * 发送类型 1 立即发送 2定时发送 + */ + @NotNull(message = "发送类型不能为空", groups = InsertGroup.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; + + /** + * 发送的用户信息选项 + * userType为2时 使用 + */ + @Column(ignore = true) + private SmsPushEventUser smsPushEventUser; +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/entity/SmsPushEvent.java b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/SmsPushEvent.java new file mode 100644 index 00000000..9d608320 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/SmsPushEvent.java @@ -0,0 +1,101 @@ +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-14 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("sms_push_event") +public class SmsPushEvent implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Id(keyType = KeyType.Auto) + private Long id; + + private Long shopId; + + /** + * 推送类型 1 模版推送 2短信推送 无用 暂留 + */ + private Integer pushType; + + /** + * 模板ID + */ + private Long pushEventId; + + /** + * 1 全部用户 2范围用户 3 指定用户 指定暂定一个用户 + */ + private Long userType; + + /** + * 指定用户时 使用 + */ + private String userId; + + /** + * 0待发送 1 发送中 2发送成功 -1失败 + */ + private Integer status; + + /** + * 发送内容 + */ + private String content; + + /** + * 赠送券信息[{"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; + /** + * 是否删除 0 未删除 1 删除 + */ + private Integer isDel; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/entity/SmsPushEventUser.java b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/SmsPushEventUser.java new file mode 100644 index 00000000..89296bad --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/SmsPushEventUser.java @@ -0,0 +1,81 @@ +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-14 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("sms_push_event_user") +public class SmsPushEventUser implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Id(keyType = KeyType.Auto) + private Long id; + + /** + * sms_user_push_event的id + */ + private Long eventId; + + private Long shopId; + + /** + * 性别 0未知 1男 2女 + */ + private String gender; + + /** + * 下单时间 0:今天 1:昨天 2:两周内 3:两周前 + */ + private String orderTimes; + + /** + * 下单时间 0:从未下单 其它数字表示下过几单 + */ + private String orderHistory; + + /** + * 充值过 0否 1是 + */ + private String isRecharge; + + /** + * 会员 0非会员 1会员 + */ + private String vip; + + /** + * 预留 短信推送用 会员等级 0 全部会员 1仅限等级 2以上等级 + */ + private String vipLevel; + + /** + * 预留 短信推送用 会员等级ID + */ + private Long vipLevelId; + + @Column(onInsertValue = "now()") + private LocalDateTime createTime; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/service/SmsPushEventService.java b/cash-common/cash-common-service/src/main/java/com/czg/market/service/SmsPushEventService.java new file mode 100644 index 00000000..a9281a67 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/service/SmsPushEventService.java @@ -0,0 +1,29 @@ +package com.czg.market.service; + +import com.czg.BaseQueryParam; +import com.czg.market.dto.ShopCouponDTO; +import com.czg.market.dto.SmsPushEventDTO; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.service.IService; +import com.czg.market.entity.SmsPushEvent; + +/** + * 营销推送发送记录 服务层。 + * + * @author ww + * @since 2025-10-14 + */ +public interface SmsPushEventService extends IService { + + /** + * 分页查询营销推送发送记录列表 + */ + Page getPushEventPage(BaseQueryParam param, Long shopId, Long id); + + /** + * 添加营销推送发送任务 + */ + void addPushEvent(SmsPushEventDTO param); + + void deletePushEvent(Long id); +} diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/mapper/SmsPushEventMapper.java b/cash-service/market-service/src/main/java/com/czg/service/market/mapper/SmsPushEventMapper.java new file mode 100644 index 00000000..e37ade9c --- /dev/null +++ b/cash-service/market-service/src/main/java/com/czg/service/market/mapper/SmsPushEventMapper.java @@ -0,0 +1,14 @@ +package com.czg.service.market.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.czg.market.entity.SmsPushEvent; + +/** + * 营销推送发送记录 映射层。 + * + * @author ww + * @since 2025-10-14 + */ +public interface SmsPushEventMapper extends BaseMapper { + +} diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/mapper/SmsPushEventUserMapper.java b/cash-service/market-service/src/main/java/com/czg/service/market/mapper/SmsPushEventUserMapper.java new file mode 100644 index 00000000..a2822c7d --- /dev/null +++ b/cash-service/market-service/src/main/java/com/czg/service/market/mapper/SmsPushEventUserMapper.java @@ -0,0 +1,14 @@ +package com.czg.service.market.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.czg.market.entity.SmsPushEventUser; + +/** + * 营销推送任务 映射层。 + * + * @author ww + * @since 2025-10-14 + */ +public interface SmsPushEventUserMapper extends BaseMapper { + +} diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/SmsPushEventServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/SmsPushEventServiceImpl.java new file mode 100644 index 00000000..798e8683 --- /dev/null +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/SmsPushEventServiceImpl.java @@ -0,0 +1,98 @@ +package com.czg.service.market.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.czg.BaseQueryParam; +import com.czg.config.RabbitPublisher; +import com.czg.exception.CzgException; +import com.czg.market.dto.ShopCouponDTO; +import com.czg.market.dto.SmsPushEventDTO; +import com.czg.market.entity.ShopCoupon; +import com.czg.market.entity.SmsPushEventUser; +import com.czg.service.market.mapper.SmsPushEventUserMapper; +import com.czg.utils.AssertUtil; +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 com.czg.market.entity.SmsPushEvent; +import com.czg.market.service.SmsPushEventService; +import com.czg.service.market.mapper.SmsPushEventMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; + +/** + * 营销推送发送记录 服务层实现。 + * + * @author ww + * @since 2025-10-14 + */ +@Service +public class SmsPushEventServiceImpl extends ServiceImpl implements SmsPushEventService { + + @Resource + private SmsPushEventUserMapper eventUserMapper; + @Resource + private RabbitPublisher rabbitPublisher; + + @Override + public Page getPushEventPage(BaseQueryParam param, Long shopId, Long id) { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq(SmsPushEvent::getShopId, shopId) + .eq(SmsPushEvent::getId, id) + .eq(SmsPushEvent::getIsDel, 0) + .orderBy(SmsPushEvent::getCreateTime).desc(); + Page page = pageAs(new Page<>(param.getPage(), param.getSize()), queryWrapper, SmsPushEventDTO.class); + for (SmsPushEventDTO record : page.getRecords()) { + if (record.getUserType() != 2) { + continue; + } + SmsPushEventUser eventUser = eventUserMapper.selectOneByQuery( + new QueryWrapper().eq(SmsPushEventUser::getEventId, record.getId()) + ); + record.setSmsPushEventUser(eventUser); + } + return page; + } + + @Override + @Transactional + public void addPushEvent(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); + save(pushEvent); + if (param.getUserType() == 2) { + SmsPushEventUser eventUser = param.getSmsPushEventUser(); + eventUser.setShopId(param.getShopId()); + eventUser.setEventId(pushEvent.getId()); + eventUserMapper.insert(eventUser); + } + // 推送消息 进行 阿里模板申请 + rabbitPublisher.sendWechatTemplateMsg(pushEvent.getShopId() + "," + pushEvent.getId()); + } + + /** + * 逻辑删除记录 + */ + @Override + public void deletePushEvent(Long id) { + SmsPushEvent pushEvent = getById(id); + AssertUtil.isNull(pushEvent, "记录不存在"); + pushEvent.setIsDel(1); + updateById(pushEvent); + } +} diff --git a/cash-service/market-service/src/main/resources/mapper/SmsPushEventMapper.xml b/cash-service/market-service/src/main/resources/mapper/SmsPushEventMapper.xml new file mode 100644 index 00000000..3b77c86a --- /dev/null +++ b/cash-service/market-service/src/main/resources/mapper/SmsPushEventMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/cash-service/market-service/src/main/resources/mapper/SmsPushEventUserMapper.xml b/cash-service/market-service/src/main/resources/mapper/SmsPushEventUserMapper.xml new file mode 100644 index 00000000..0f55153a --- /dev/null +++ b/cash-service/market-service/src/main/resources/mapper/SmsPushEventUserMapper.xml @@ -0,0 +1,7 @@ + + + + +