群聊优惠券

This commit is contained in:
2025-12-02 18:10:34 +08:00
parent 2c2b3765ad
commit d012201752
17 changed files with 628 additions and 22 deletions

View File

@@ -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<List<BkContactList>> getUserList(@RequestBody Set<String> 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<List<BkTableVO>> 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<BookingOrderStatisticsVO> 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<List<BkOrder>> 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<List<BkOrderTable>> bookingTables(Long id) {
List<BkOrderTable> 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<Void> 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<Void> 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<Void> storeArrival(@RequestBody BkOrderDTO bkOrder) {
AssertUtil.isNull(bkOrder.getId(), "已到店的预约单id不能为空");

View File

@@ -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<Void> 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<ChatCouponVO> 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<Void> 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<Void> 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<MkShopCouponRecord> 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);
}
}

View File

@@ -215,4 +215,17 @@ public class ACouponController {
public CzgResult<List<UserCouponVo>> 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<Page<ShopCouponDTO>> 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));
}
}

View File

@@ -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<List<KitchenTableVO>> getKitchenTable(@RequestParam(required = false) String tableName, @RequestParam(required = false) Long areaId) {
Long shopId = StpKit.USER.getShopId();
List<KitchenTableVO> 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<List<KitchenTableFoodVO>> 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<List<KitchenFoodVO>> getKitchenFood(@RequestParam(required = false) String productName, @RequestParam(required = false) Long categoryId) {
Long shopId = StpKit.USER.getShopId();
List<KitchenFoodVO> kitchenFood = kitchenDetailMapper.getKitchenFood(shopId, productName, categoryId);

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -125,7 +125,7 @@ public class ShopCoupon implements Serializable {
private String getType;
/**
* 用户领取方式
* 用户领取方式 首页home/用餐eat/订单order
*/
private String getMode;

View File

@@ -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<ChatCoupon> {
/**
* 创建聊天优惠券发放活动
*/
void createChatCoupon(Long shopId, ChatCouponDTO chatCoupon);
/**
* 分页查询聊天优惠券发放活动
*/
Page<ChatCouponVO> pageChatCoupon(Long shopId, Integer page, Integer size, Integer status);
/**
* 失效
*/
void expiredChatCoupon(Long shopId, Long id);
/**
* 发放优惠券
*/
void grantChatCoupon(Long id, Long shopUserId, Long userId);
/**
* 分页查询优惠券发放记录
*/
Page<MkShopCouponRecord> grantChatCouponRecord(Long id, Integer status, Integer page, Integer size);
}

View File

@@ -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<MkShopCouponRecord>
Boolean grant(Long shopId, MkRewardCouponDTO rewardCouponDTO, String source);
MkShopCouponRecord assembleRecord(Long chatCouponId, ShopCoupon coupon);
/**
* 优惠券发放
*/
void grantChatCoupon(MkShopCouponRecord record, Integer number);
}

View File

@@ -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<ShopCoupon> {
/**
* 群聊可发放优惠券列表
*
* @param shopId 店铺id
* @param search 优惠券名称模糊搜索
*/
Page<ShopCouponDTO> chatCoupon(Long shopId, String search);
Page<ShopCouponDTO> getCouponPage(ShopCouponDTO param);
List<ShopCouponPopUp> getPopUp(Long shopId, Long userId, String getMode);

View File

@@ -0,0 +1,11 @@
package com.czg.market.vo;
import com.czg.market.entity.ChatCoupon;
/**
* @author ww
* @description
*/
public class ChatCouponVO extends ChatCoupon {
}

View File

@@ -0,0 +1,14 @@
package com.czg.service.market.mapper;
import com.mybatisflex.core.BaseMapper;
import com.czg.market.entity.ChatCoupon;
/**
* 映射层。
*
* @author ww
* @since 2025-12-02
*/
public interface ChatCouponMapper extends BaseMapper<ChatCoupon> {
}

View File

@@ -0,0 +1,142 @@
package com.czg.service.market.service.impl;
import com.alibaba.fastjson2.JSONObject;
import com.czg.exception.CzgException;
import com.czg.market.dto.ChatCouponDTO;
import com.czg.market.entity.MkShopCouponRecord;
import com.czg.market.entity.ShopCoupon;
import com.czg.market.service.MkShopCouponRecordService;
import com.czg.market.service.ShopCouponService;
import com.czg.market.vo.ChatCouponVO;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.czg.market.entity.ChatCoupon;
import com.czg.market.service.ChatCouponService;
import com.czg.service.market.mapper.ChatCouponMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 服务层实现。
*
* @author ww
* @since 2025-12-02
*/
@Slf4j
@Service
public class ChatCouponServiceImpl extends ServiceImpl<ChatCouponMapper, ChatCoupon> implements ChatCouponService {
@Resource
private ShopCouponService couponService;
@Resource
private MkShopCouponRecordService recordService;
@Override
@Transactional
public void createChatCoupon(Long shopId, ChatCouponDTO chatCoupon) {
ShopCoupon coupon = couponService.getOne(QueryWrapper.create()
.eq(ShopCoupon::getId, chatCoupon.getCouponId())
);
if (coupon == null) {
throw new CzgException("优惠券不可使用,优惠券不存在");
}
if (!"all".equals(coupon.getGetUserType())) {
throw new CzgException("优惠券不可使用,优惠券存在领取用户限制");
}
ChatCoupon saveChatCoupon = ChatCoupon.builder()
.shopId(shopId)
.title(chatCoupon.getTitle())
.getLimit(chatCoupon.getGetLimit() == null ? 1 : chatCoupon.getGetLimit())
.giveNum(chatCoupon.getGiveNum() == null ? -10086 : chatCoupon.getGiveNum())
.leftNum(chatCoupon.getGiveNum() == null ? -10086 : chatCoupon.getGiveNum())
.useNum(0)
.couponId(chatCoupon.getCouponId())
.build();
save(saveChatCoupon);
if (saveChatCoupon.getId() == null) {
log.info("发放创建失败群聊发放任务回填Id失败{}", JSONObject.toJSONString(saveChatCoupon));
throw new CzgException("发放创建失败,请联系管理员");
}
MkShopCouponRecord record = recordService.assembleRecord(saveChatCoupon.getId(), coupon);
saveChatCoupon.setCouponJson(JSONObject.toJSONString(record));
updateById(saveChatCoupon);
}
@Override
public Page<ChatCouponVO> pageChatCoupon(Long shopId, Integer page, Integer size, Integer status) {
Page<ChatCouponVO> pages = pageAs(Page.of(page, size),
QueryWrapper.create()
.eq(ChatCoupon::getShopId, shopId)
.eq(ChatCoupon::getStatus, status)
.orderBy(ChatCoupon::getStatus).asc()
.orderBy(ChatCoupon::getId).desc(),
ChatCouponVO.class);
return pages;
}
/**
* 失效
*/
@Override
public void expiredChatCoupon(Long shopId, Long id) {
ChatCoupon coupon = new ChatCoupon();
coupon.setStatus(3);
update(coupon, QueryWrapper.create()
.eq(ChatCoupon::getId, id)
.eq(ChatCoupon::getShopId, shopId)
);
}
@Override
@Transactional
public void grantChatCoupon(Long id, Long shopUserId, Long userId) {
ChatCoupon coupon = getOne(QueryWrapper.create()
.eq(ChatCoupon::getId, id)
.eq(ChatCoupon::getShopId, shopUserId)
);
if (coupon == null) {
throw new CzgException("活动不存在");
}
if (coupon.getStatus() != 1) {
throw new CzgException("活动已失效");
}
boolean exists = recordService.exists(QueryWrapper.create()
.eq(MkShopCouponRecord::getSource, "群聊发放")
.eq(MkShopCouponRecord::getSourceId, coupon.getId())
.eq(MkShopCouponRecord::getShopUserId, shopUserId)
.eq(MkShopCouponRecord::getUserId, userId)
);
if (exists) {
throw new CzgException("不可重复领取");
}
if (coupon.getLeftNum() <= 0) {
throw new CzgException("发放失败,剩余数量不足");
}
if (coupon.getLeftNum() < coupon.getGetLimit()) {
throw new CzgException("发放失败,剩余数量不足");
}
coupon.setLeftNum(coupon.getLeftNum() - coupon.getGetLimit());
if (coupon.getLeftNum() == 0) {
coupon.setStatus(3);
}
updateById(coupon);
MkShopCouponRecord record = JSONObject.parseObject(coupon.getCouponJson(), MkShopCouponRecord.class);
record.setShopUserId(shopUserId);
record.setUserId(userId);
recordService.grantChatCoupon(record, coupon.getGetLimit());
}
@Override
public Page<MkShopCouponRecord> grantChatCouponRecord(Long id, Integer status, Integer page, Integer size) {
return recordService.pageAs(Page.of(page, size),
QueryWrapper.create()
.eq(MkShopCouponRecord::getSourceId, id)
.eq(MkShopCouponRecord::getStatus, status)
.orderBy(MkShopCouponRecord::getId).desc(),
MkShopCouponRecord.class);
}
}

View File

@@ -33,7 +33,6 @@ import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
@@ -511,4 +510,78 @@ public class MkShopCouponRecordServiceImpl extends ServiceImpl<MkShopCouponRecor
receiveCoupon(giftDTO, rewardCouponDTO.getNum(), false);
return true;
}
/**
* 组装信息
*/
public MkShopCouponRecord assembleRecord(Long chatCouponId, ShopCoupon coupon) {
LocalDateTime start = LocalDateTime.now().with(LocalTime.MIN);
LocalDateTime end = null;
if ("fixed".equals(coupon.getValidType())) {
//固定时间
if (coupon.getDaysToTakeEffect() != null && coupon.getDaysToTakeEffect() > 0) {
start = LocalDateTimeUtil.offset(start, coupon.getDaysToTakeEffect(), ChronoUnit.DAYS).with(LocalTime.MIN);
}
end = LocalDateTimeUtil.offset(start, coupon.getValidDays(), ChronoUnit.DAYS).with(LocalTime.MAX).truncatedTo(ChronoUnit.SECONDS);
} else if ("custom".equals(coupon.getValidType())) {
//自定义时间
start = coupon.getValidStartTime();
end = coupon.getValidEndTime();
}
MkShopCouponRecord record = new MkShopCouponRecord();
record.setShopId(coupon.getShopId());
record.setCouponId(coupon.getId());
record.setCouponSyncId(coupon.getSyncId());
record.setSourceId(chatCouponId);
record.setSource("群聊发放");
record.setStatus(0);
record.setType(coupon.getCouponType());
record.setFullAmount(coupon.getFullAmount());
record.setDiscountAmount(coupon.getDiscountAmount());
record.setDiscountRate(coupon.getDiscountRate());
record.setMaxDiscountAmount(coupon.getMaxDiscountAmount());
record.setCreateTime(LocalDateTime.now());
record.setIsDel(0);
record.setUseStartTime(start);
record.setUseEndTime(end);
return record;
}
@Override
public void grantChatCoupon(MkShopCouponRecord record, Integer number) {
ShopCoupon coupon = couponService.selectOneById(record.getCouponId());
AssertUtil.isNull(coupon, "优惠券不存在");
List<MkShopCouponRecord> recordList = new ArrayList<>();
// 检查优惠券状态
if (coupon.getIsDel() != 0) {
// 状态异常,直接返回
return;
}
// 检查优惠券是否失效
if (coupon.getStatus() != 1) {
return;
}
coupon.setGiftNum(coupon.getGiftNum() + number);
for (int i = 0; i < number; i++) {
recordList.add(record);
}
mapper.insertBatchSelective(recordList, 50);
QueryWrapper queryWrapper = new QueryWrapper();
ShopCoupon newCoupon = new ShopCoupon();
newCoupon.setGiftNum(coupon.getGiftNum());
if (coupon.getSyncId() != null) {
queryWrapper.and(q -> {
q.eq(ShopCoupon::getId, coupon.getSyncId()).or(q1 -> {
q1.eq(ShopCoupon::getSyncId, coupon.getSyncId());
});
});
couponService.updateByQuery(newCoupon, queryWrapper);
} else {
newCoupon.setId(coupon.getId());
couponService.update(newCoupon, true);
}
}
}

View File

@@ -16,15 +16,13 @@ import com.czg.account.vo.UserCouponVo;
import com.czg.exception.CzgException;
import com.czg.market.dto.MkShopCouponGiftDTO;
import com.czg.market.dto.ShopCouponDTO;
import com.czg.market.entity.ChatCoupon;
import com.czg.market.entity.MkShopCouponRecord;
import com.czg.market.entity.ShopCoupon;
import com.czg.market.service.MkCouponGiftService;
import com.czg.market.service.MkShopCouponRecordService;
import com.czg.market.service.ShopCouponService;
import com.czg.market.service.*;
import com.czg.market.vo.ShopCouponPopUp;
import com.czg.market.vo.UserCouponVO;
import com.czg.order.entity.OrderInfo;
import com.czg.market.service.OrderInfoService;
import com.czg.product.entity.Product;
import com.czg.product.service.ProductService;
import com.czg.sa.StpKit;
@@ -43,6 +41,7 @@ import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.scheduling.annotation.Async;
import java.time.LocalDate;
import java.time.LocalDateTime;
@@ -74,6 +73,27 @@ public class ShopCouponServiceImpl extends ServiceImpl<ShopCouponMapper, ShopCou
private ProductService productService;
@Resource
private OrderInfoService orderInfoService;
@Resource
private ChatCouponService chatCouponService;
@Override
public Page<ShopCouponDTO> chatCoupon(Long shopId, String search) {
QueryWrapper queryWrapper = new QueryWrapper();
// queryWrapper.select("id as id,title as name");
queryWrapper.eq(ShopCoupon::getShopId, shopId)
.eq(ShopCoupon::getGetUserType, "all")
.eq(ShopCoupon::getIsDel, 0)
.eq(ShopCoupon::getStatus, 1)
.like(ShopCoupon::getTitle, CzgStrUtils.getStrOrNull(search))
.orderBy(ShopCoupon::getCreateTime).desc();
queryWrapper.and(q -> {
q.eq(ShopCoupon::getValidType, "fixed").or(q1 -> {
q1.eq(ShopCoupon::getValidType, "custom").gt(ShopCoupon::getValidEndTime, LocalDateTime.now());
});
});
Page<ShopCouponDTO> list = pageAs(PageUtil.buildPage(), queryWrapper, ShopCouponDTO.class);
return list;
}
@Override
public Page<ShopCouponDTO> getCouponPage(ShopCouponDTO param) {
@@ -314,12 +334,30 @@ public class ShopCouponServiceImpl extends ServiceImpl<ShopCouponMapper, ShopCou
}
@Override
@Async
public Boolean use(List<Long> ids, Long shopUserId, Long orderId) {
List<MkShopCouponRecord> records = recordService.listByIds(ids);
if (records.isEmpty()) {
log.error("优惠券使用失败订单Id:{}", orderId);
return false;
}
Map<Long, Long> chatCouponIdCountMap = records.stream()
.filter(record -> "群聊发放".equals(record.getSource()))
.collect(Collectors.groupingBy(MkShopCouponRecord::getSourceId,
Collectors.counting()
));
chatCouponIdCountMap.forEach((chatCouponId, count) -> {
ChatCoupon chatCoupon = chatCouponService.getById(chatCouponId);
if (chatCoupon == null) {
return;
}
ChatCoupon upChatCoupon = new ChatCoupon();
upChatCoupon.setId(chatCoupon.getId());
upChatCoupon.setUseNum(chatCoupon.getUseNum() + count.intValue());
chatCouponService.updateById(upChatCoupon);
});
// 使用流来统计 couponId 出现的次数
Map<Long, Long> couponIdCountMap = records.stream()
.collect(Collectors.groupingBy(MkShopCouponRecord::getCouponId,

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.czg.service.market.mapper.ChatCouponMapper">
</mapper>