From d012201752d15d200fd700e5b804304821a2f483 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Tue, 2 Dec 2025 18:10:34 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BE=A4=E8=81=8A=E4=BC=98=E6=83=A0=E5=88=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/BkContactListController.java | 17 +-- .../admin/AChatCouponController.java | 86 +++++++++++ .../controller/admin/ACouponController.java | 13 ++ .../controller/kitchen/TableController.java | 8 +- .../com/czg/market/dto/ChatCouponDTO.java | 50 ++++++ .../czg/market/dto/ChatCouponGrantDTO.java | 26 ++++ .../com/czg/market/entity/ChatCoupon.java | 92 ++++++++++++ .../com/czg/market/entity/ShopCoupon.java | 2 +- .../czg/market/service/ChatCouponService.java | 42 ++++++ .../service/MkShopCouponRecordService.java | 8 + .../czg/market/service/ShopCouponService.java | 11 +- .../java/com/czg/market/vo/ChatCouponVO.java | 11 ++ .../market/mapper/ChatCouponMapper.java | 14 ++ .../service/impl/ChatCouponServiceImpl.java | 142 ++++++++++++++++++ .../impl/MkShopCouponRecordServiceImpl.java | 75 ++++++++- .../service/impl/ShopCouponServiceImpl.java | 46 +++++- .../resources/mapper/ChatCouponMapper.xml | 7 + 17 files changed, 628 insertions(+), 22 deletions(-) create mode 100644 cash-api/market-server/src/main/java/com/czg/controller/admin/AChatCouponController.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/dto/ChatCouponDTO.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/dto/ChatCouponGrantDTO.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/entity/ChatCoupon.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/service/ChatCouponService.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/market/vo/ChatCouponVO.java create mode 100644 cash-service/market-service/src/main/java/com/czg/service/market/mapper/ChatCouponMapper.java create mode 100644 cash-service/market-service/src/main/java/com/czg/service/market/service/impl/ChatCouponServiceImpl.java create mode 100644 cash-service/market-service/src/main/resources/mapper/ChatCouponMapper.xml diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/BkContactListController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/BkContactListController.java index fbcb4a18b..d9f251dde 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/admin/BkContactListController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/BkContactListController.java @@ -1,7 +1,6 @@ package com.czg.controller.admin; import com.czg.account.dto.BkOrderDTO; -import com.czg.account.dto.calltable.CallTablePage; import com.czg.account.entity.BkContactList; import com.czg.account.entity.BkOrder; import com.czg.account.entity.BkOrderTable; @@ -41,7 +40,7 @@ public class BkContactListController { /** * 通讯录 获取联系人订单数等 */ -// @SaAdminCheckPermission(value = "bk:bkContactList:list", name = "预约端-联系人列表") + @SaAdminCheckPermission(value = "bk:bkContactList:list", name = "预约端-联系人列表") @PostMapping("/contactList") public CzgResult> getUserList(@RequestBody Set phones) { return CzgResult.success(contactListService.getUserList(StpKit.USER.getShopId(), phones)); @@ -50,7 +49,7 @@ public class BkContactListController { /** * 预约端-台桌:查询台桌列表 */ -// @SaAdminCheckPermission(value = "bk:bkOrder:table", name = "预约端-台桌:查询台桌列表") + @SaAdminCheckPermission(value = "bk:bkOrder:table", name = "预约端-台桌:查询台桌列表") @GetMapping("/bkOrder/table") public CzgResult> table(@RequestParam(value = "areaId", required = false) Long areaId, @RequestParam LocalDate day, @@ -62,7 +61,7 @@ public class BkContactListController { /** * 预约端-预定单:预约单统计 */ -// @SaAdminCheckPermission(value = "bk:bkOrder:bookings:statistics", name = "预约端-预约单:预约单统计") + @SaAdminCheckPermission(value = "bk:bookings:statistics", name = "预约端-预约单:预约单统计") @GetMapping("/bkOrder/booking/statistics") public CzgResult bookingOrderStatistics(@RequestParam(required = false) String search, @RequestParam(required = false) LocalDate start, @@ -75,7 +74,7 @@ public class BkContactListController { /** * 预约端-预定单:查询预约单列表 */ -// @SaAdminCheckPermission(value = "bk:bkOrder:bookings", name = "预约端-预约单:列表") + @SaAdminCheckPermission(value = "bk:bkOrder:bookings", name = "预约端-预约单:列表") @GetMapping("/bkOrder/bookings") public CzgResult> bookings(@RequestParam(required = false) String search, @RequestParam(required = false) LocalDate start, @@ -88,7 +87,7 @@ public class BkContactListController { /** * 预约端-预定单:查询预约单选中台桌 */ -// @SaAdminCheckPermission(value = "bk:bkOrder:bookings/tables", name = "预约端-预约单:查询预约单选中的台桌") + @SaAdminCheckPermission(value = "bk:bkOrder:tables", name = "预约端-预约单:查询预约单选中的台桌") @GetMapping("/bkOrder/bookings/tables") public CzgResult> bookingTables(Long id) { List tables = bkOrderService.bookingTables(StpKit.USER.getShopId(), id); @@ -99,7 +98,7 @@ public class BkContactListController { /** * 预约端-预约单:预约/修改预约 */ -// @SaAdminCheckPermission(value = "bk:bkOrder:booking", name = "预约端-预约单:预约") + @SaAdminCheckPermission(value = "bk:bkOrder:booking", name = "预约端-预约单:预约/修改") @PostMapping("/bkOrder/booking") public CzgResult booking(@RequestBody BkOrderDTO bkOrder) { Long shopId = StpKit.USER.getShopId(); @@ -113,7 +112,7 @@ public class BkContactListController { /** * 预约端-预约单:取消预约 */ -// @SaAdminCheckPermission(value = "bk:bkOrder:booking", name = "预约端-预约单:取消预约") + @SaAdminCheckPermission(value = "bk:bkOrder:cancel", name = "预约端-预约单:取消预约") @PostMapping("/bkOrder/cancel") public CzgResult cancel(@RequestBody BkOrderDTO bkOrder) { AssertUtil.isNull(bkOrder.getId(), "需要撤销的预约单id不能为空"); @@ -125,7 +124,7 @@ public class BkContactListController { /** * 预约端-预约单:已到店 */ -// @SaAdminCheckPermission(value = "bk:bkOrder:storeArrival", name = "预约端-预约单:已到店") + @SaAdminCheckPermission(value = "bk:bkOrder:storeArrival", name = "预约端-预约单:已到店") @PostMapping("/bkOrder/storeArrival") public CzgResult storeArrival(@RequestBody BkOrderDTO bkOrder) { AssertUtil.isNull(bkOrder.getId(), "已到店的预约单id不能为空"); diff --git a/cash-api/market-server/src/main/java/com/czg/controller/admin/AChatCouponController.java b/cash-api/market-server/src/main/java/com/czg/controller/admin/AChatCouponController.java new file mode 100644 index 000000000..913d6368b --- /dev/null +++ b/cash-api/market-server/src/main/java/com/czg/controller/admin/AChatCouponController.java @@ -0,0 +1,86 @@ +package com.czg.controller.admin; + +import com.czg.annotation.SaAdminCheckPermission; +import com.czg.market.dto.ChatCouponDTO; +import com.czg.market.dto.ChatCouponGrantDTO; +import com.czg.market.entity.MkShopCouponRecord; +import com.czg.market.service.ChatCouponService; +import com.czg.market.vo.ChatCouponVO; +import com.czg.resp.CzgResult; +import com.czg.sa.StpKit; +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/chat/coupon") +public class AChatCouponController { + @Resource + private ChatCouponService chatCouponService; + + /** + * 群聊优惠券活动-创建 + */ + @PostMapping("/create") + @SaAdminCheckPermission(value = "chat:coupon:create", name = "群聊优惠券活动-创建") + public CzgResult createChatCoupon(@RequestBody @Validated ChatCouponDTO chatCoupon) { + Long shopId = StpKit.USER.getShopId(); + chatCouponService.createChatCoupon(shopId, chatCoupon); + return CzgResult.success(); + } + + /** + * 群聊优惠券活动-分页查询 + */ + @GetMapping("/page") + @SaAdminCheckPermission(value = "chat:coupon:page", name = "群聊优惠券活动-分页查询") + public Page pageChatCoupon(@RequestParam(required = false, defaultValue = "1") Integer page, + @RequestParam(required = false, defaultValue = "10") Integer size, + @RequestParam(required = false) Integer status) { + Long shopId = StpKit.USER.getShopId(); + return chatCouponService.pageChatCoupon(shopId, page, size, status); + } + + /** + * 群聊优惠券活动-失效 + */ + @DeleteMapping("/expired/{id}") + @SaAdminCheckPermission(value = "chat:coupon:expired", name = "群聊优惠券活动-失效") + public CzgResult expiredChatCoupon(@PathVariable Long id) { + Long shopId = StpKit.USER.getShopId(); + chatCouponService.expiredChatCoupon(shopId, id); + return CzgResult.success(); + } + /** + * 群聊优惠券活动-发放优惠券 + */ + @PostMapping("/grant") + @SaAdminCheckPermission(value = "chat:coupon:grant", name = "群聊优惠券活动-发放优惠券") + public CzgResult grantChatCoupon(@RequestBody ChatCouponGrantDTO chatCouponGrant) { + chatCouponService.grantChatCoupon(chatCouponGrant.getId(), chatCouponGrant.getShopUserId(), chatCouponGrant.getUserId()); + return CzgResult.success(); + } + + /** + * 群聊优惠券活动-发放记录 + */ + @GetMapping("/record") + @SaAdminCheckPermission(value = "chat:coupon:record", name = "群聊优惠券活动-发放记录") + public Page grantChatCouponRecord(@RequestParam Long id, + @RequestParam(required = false) Integer status, + @RequestParam(required = false, defaultValue = "1") Integer page, + @RequestParam(required = false, defaultValue = "10") Integer size) { + return chatCouponService.grantChatCouponRecord(id, status, page, size); + } + + +} diff --git a/cash-api/market-server/src/main/java/com/czg/controller/admin/ACouponController.java b/cash-api/market-server/src/main/java/com/czg/controller/admin/ACouponController.java index 8af960ee3..8347bccb6 100644 --- a/cash-api/market-server/src/main/java/com/czg/controller/admin/ACouponController.java +++ b/cash-api/market-server/src/main/java/com/czg/controller/admin/ACouponController.java @@ -215,4 +215,17 @@ public class ACouponController { public CzgResult> findCoupon(@RequestParam Long shopUserId, @RequestParam(required = false) Integer type, @RequestParam(required = false) Integer isFood) { return CzgResult.success(shopCouponService.findCoupon(StpKit.USER.getShopId(), shopUserId, type, isFood)); } + + /** + * 群聊可发放优惠券列表 + * + * @param search 优惠券名称模糊搜索 + */ + @GetMapping("/chatCoupon") + public CzgResult> chatCoupon(@RequestParam(required = false, defaultValue = "1") Integer page, + @RequestParam(required = false, defaultValue = "10") Integer size, + @RequestParam(required = false) String search) { + Long shopId = StpKit.USER.getShopId(); + return CzgResult.success(shopCouponService.chatCoupon(shopId, search)); + } } diff --git a/cash-api/order-server/src/main/java/com/czg/controller/kitchen/TableController.java b/cash-api/order-server/src/main/java/com/czg/controller/kitchen/TableController.java index f84450f35..89a967e08 100644 --- a/cash-api/order-server/src/main/java/com/czg/controller/kitchen/TableController.java +++ b/cash-api/order-server/src/main/java/com/czg/controller/kitchen/TableController.java @@ -8,8 +8,6 @@ import com.czg.resp.CzgResult; import com.czg.sa.StpKit; import com.czg.service.order.mapper.KitchenDetailMapper; import jakarta.annotation.Resource; -import lombok.AllArgsConstructor; -import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -35,7 +33,7 @@ public class TableController { * 按台桌查看 */ @GetMapping("getKitchenTable") -// @SaAdminCheckPermission(value = "kitchen:table", name = "后厨-按台桌查看") + @SaAdminCheckPermission(value = "kitchen:table", name = "后厨-按台桌查看") public CzgResult> getKitchenTable(@RequestParam(required = false) String tableName, @RequestParam(required = false) Long areaId) { Long shopId = StpKit.USER.getShopId(); List kitchenTables = kitchenDetailMapper.getKitchenTable(shopId, tableName, areaId); @@ -46,7 +44,7 @@ public class TableController { * 按台桌查看 商品内容 */ @GetMapping("getKitchenTableFoods") -// @SaAdminCheckPermission(value = "kitchen:tableFood", name = "后厨-按台桌查看商品内容") + @SaAdminCheckPermission(value = "kitchen:tableFood", name = "后厨-按台桌查看商品内容") public CzgResult> getKitchenTableFoods(@RequestParam(required = false) Long orderId, @RequestParam(required = false) String tableCode, @RequestParam(required = false) Long isNoTable) { @@ -63,7 +61,7 @@ public class TableController { * 按商品查看 */ @GetMapping("getKitchenFood") -// @SaAdminCheckPermission(value = "kitchen:table", name = "后厨-按台桌查看") + @SaAdminCheckPermission(value = "kitchen:table", name = "后厨-按台桌查看") public CzgResult> getKitchenFood(@RequestParam(required = false) String productName, @RequestParam(required = false) Long categoryId) { Long shopId = StpKit.USER.getShopId(); List kitchenFood = kitchenDetailMapper.getKitchenFood(shopId, productName, categoryId); diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/dto/ChatCouponDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/market/dto/ChatCouponDTO.java new file mode 100644 index 000000000..0778b8b0f --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/dto/ChatCouponDTO.java @@ -0,0 +1,50 @@ + +package com.czg.market.dto; + +import java.io.Serializable; + +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-12-02 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class ChatCouponDTO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 自定义文案 + */ + @NotBlank(message = "自定义文案不能为空") + private String title; + + /** + * 每人领取限量 默认1 + */ + private Integer getLimit; + + /** + * 发放数量,-10086为不限量 + */ + private Integer giveNum; + /** + * 券id + */ + @NotNull(message = "券id不能为空") + private Long couponId; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/dto/ChatCouponGrantDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/market/dto/ChatCouponGrantDTO.java new file mode 100644 index 000000000..e64a8d758 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/dto/ChatCouponGrantDTO.java @@ -0,0 +1,26 @@ +package com.czg.market.dto; + +import lombok.Data; + +/** + * @author ww + * @description 群聊优惠券发放DTO + */ +@Data +public class ChatCouponGrantDTO { + + /** + * 活动ID + */ + private Long id; + /** + * 店铺用户ID + */ + private Long shopUserId; + /** + * 用户ID + */ + private Long userId; + + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/entity/ChatCoupon.java b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/ChatCoupon.java new file mode 100644 index 000000000..5788cca70 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/ChatCoupon.java @@ -0,0 +1,92 @@ +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.io.Serial; +import java.time.LocalDateTime; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 实体类。 + * + * @author ww + * @since 2025-12-02 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table("chat_coupon") +public class ChatCoupon implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @Id(keyType = KeyType.Auto) + private Long id; + + /** + * 店铺Id + */ + private Long shopId; + + /** + * 自定义文案 + */ + private String title; + + /** + * 每人领取限量 默认1长 + */ + private Integer getLimit; + + /** + * 发放数量,-10086为不限量 + */ + private Integer giveNum; + + /** + * 剩余数量 + */ + private Integer leftNum; + + /** + * 已使用数量 + */ + private Integer useNum; + + /** + * 券id + */ + private Long couponId; + /** + * 优惠券json mk_shop_coupon_record 表的json字段 + */ + private String couponJson; + /** + * 状态 1-发放中 3-已失效 + */ + private Integer status; + /** + * 创建时间 + */ + @Column(onInsertValue = "now()") + private LocalDateTime createTime; + /** + * 删除状态 0-正常 1-已删除 + */ + private Integer isDel; + +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/entity/ShopCoupon.java b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/ShopCoupon.java index cc497aad8..04102c042 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/market/entity/ShopCoupon.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/entity/ShopCoupon.java @@ -125,7 +125,7 @@ public class ShopCoupon implements Serializable { private String getType; /** - * 用户领取方式 + * 用户领取方式 首页home/用餐eat/订单order */ private String getMode; diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/service/ChatCouponService.java b/cash-common/cash-common-service/src/main/java/com/czg/market/service/ChatCouponService.java new file mode 100644 index 000000000..327fa0c34 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/service/ChatCouponService.java @@ -0,0 +1,42 @@ +package com.czg.market.service; + +import com.czg.market.dto.ChatCouponDTO; +import com.czg.market.entity.MkShopCouponRecord; +import com.czg.market.vo.ChatCouponVO; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.service.IService; +import com.czg.market.entity.ChatCoupon; + +/** + * 服务层。 + * + * @author ww + * @since 2025-12-02 + */ +public interface ChatCouponService extends IService { + + /** + * 创建聊天优惠券发放活动 + */ + void createChatCoupon(Long shopId, ChatCouponDTO chatCoupon); + + /** + * 分页查询聊天优惠券发放活动 + */ + Page pageChatCoupon(Long shopId, Integer page, Integer size, Integer status); + + /** + * 失效 + */ + void expiredChatCoupon(Long shopId, Long id); + + /** + * 发放优惠券 + */ + void grantChatCoupon(Long id, Long shopUserId, Long userId); + + /** + * 分页查询优惠券发放记录 + */ + Page grantChatCouponRecord(Long id, Integer status, Integer page, Integer size); +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkShopCouponRecordService.java b/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkShopCouponRecordService.java index da3ec2bbb..7aabfa0d7 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkShopCouponRecordService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/service/MkShopCouponRecordService.java @@ -5,6 +5,7 @@ import com.czg.account.vo.CouponReceiveVo; import com.czg.account.vo.UserCouponVo; import com.czg.market.dto.*; import com.czg.market.entity.MkShopCouponRecord; +import com.czg.market.entity.ShopCoupon; import com.czg.market.vo.UserCouponVO; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.service.IService; @@ -65,4 +66,11 @@ public interface MkShopCouponRecordService extends IService Boolean grant(Long shopId, MkRewardCouponDTO rewardCouponDTO, String source); + MkShopCouponRecord assembleRecord(Long chatCouponId, ShopCoupon coupon); + + /** + * 优惠券发放 + */ + void grantChatCoupon(MkShopCouponRecord record, Integer number); + } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/service/ShopCouponService.java b/cash-common/cash-common-service/src/main/java/com/czg/market/service/ShopCouponService.java index cc8ac74b8..a328857af 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/market/service/ShopCouponService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/service/ShopCouponService.java @@ -3,12 +3,11 @@ package com.czg.market.service; import com.czg.account.vo.ShopInfoCouponVO; import com.czg.account.vo.UserCouponVo; import com.czg.market.dto.ShopCouponDTO; -import com.czg.market.entity.MkShopCouponRecord; +import com.czg.market.entity.ShopCoupon; import com.czg.market.vo.ShopCouponPopUp; import com.czg.market.vo.UserCouponVO; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.service.IService; -import com.czg.market.entity.ShopCoupon; import java.util.List; @@ -19,6 +18,14 @@ import java.util.List; * @since 2025-09-11 */ public interface ShopCouponService extends IService { + /** + * 群聊可发放优惠券列表 + * + * @param shopId 店铺id + * @param search 优惠券名称模糊搜索 + */ + Page chatCoupon(Long shopId, String search); + Page getCouponPage(ShopCouponDTO param); List getPopUp(Long shopId, Long userId, String getMode); diff --git a/cash-common/cash-common-service/src/main/java/com/czg/market/vo/ChatCouponVO.java b/cash-common/cash-common-service/src/main/java/com/czg/market/vo/ChatCouponVO.java new file mode 100644 index 000000000..eee605a3a --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/market/vo/ChatCouponVO.java @@ -0,0 +1,11 @@ +package com.czg.market.vo; + +import com.czg.market.entity.ChatCoupon; + +/** + * @author ww + * @description + */ +public class ChatCouponVO extends ChatCoupon { + +} diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/mapper/ChatCouponMapper.java b/cash-service/market-service/src/main/java/com/czg/service/market/mapper/ChatCouponMapper.java new file mode 100644 index 000000000..088c72cc4 --- /dev/null +++ b/cash-service/market-service/src/main/java/com/czg/service/market/mapper/ChatCouponMapper.java @@ -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 { + +} diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/ChatCouponServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/ChatCouponServiceImpl.java new file mode 100644 index 000000000..2566c18bc --- /dev/null +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/ChatCouponServiceImpl.java @@ -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 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 pageChatCoupon(Long shopId, Integer page, Integer size, Integer status) { + Page 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 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); + } +} diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShopCouponRecordServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShopCouponRecordServiceImpl.java index aef8b7bd0..3c11271cc 100644 --- a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShopCouponRecordServiceImpl.java +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/MkShopCouponRecordServiceImpl.java @@ -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 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 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); + } + } } diff --git a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/ShopCouponServiceImpl.java b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/ShopCouponServiceImpl.java index f93c46340..13d5993bb 100644 --- a/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/ShopCouponServiceImpl.java +++ b/cash-service/market-service/src/main/java/com/czg/service/market/service/impl/ShopCouponServiceImpl.java @@ -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 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 list = pageAs(PageUtil.buildPage(), queryWrapper, ShopCouponDTO.class); + return list; + } @Override public Page getCouponPage(ShopCouponDTO param) { @@ -314,12 +334,30 @@ public class ShopCouponServiceImpl extends ServiceImpl ids, Long shopUserId, Long orderId) { List records = recordService.listByIds(ids); if (records.isEmpty()) { log.error("优惠券使用失败,订单Id:{}", orderId); return false; } + Map 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 couponIdCountMap = records.stream() .collect(Collectors.groupingBy(MkShopCouponRecord::getCouponId, diff --git a/cash-service/market-service/src/main/resources/mapper/ChatCouponMapper.xml b/cash-service/market-service/src/main/resources/mapper/ChatCouponMapper.xml new file mode 100644 index 000000000..6c2439da8 --- /dev/null +++ b/cash-service/market-service/src/main/resources/mapper/ChatCouponMapper.xml @@ -0,0 +1,7 @@ + + + + +