diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/act/ActCouponRecordStatusEnum.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/act/ActCouponRecordStatusEnum.java new file mode 100644 index 000000000..103fbf359 --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/act/ActCouponRecordStatusEnum.java @@ -0,0 +1,34 @@ +package com.bsd.pjcloud.wallet.api.constant.act; + +import cn.hutool.core.util.ObjectUtil; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 优惠券使用状态 + */ +@Getter +@AllArgsConstructor +public enum ActCouponRecordStatusEnum { + UNUSED("1", "未使用"), + USED("2", "已使用"), + EXPIRED("3", "已过期"), + INVALID("4", "已作废"), + ; + private final String code; + private final String desc; + + public static ActCouponRecordStatusEnum valueOfByType(String code) { + return Arrays.stream(ActCouponRecordStatusEnum.values()) + .filter(v -> ObjectUtil.equal(v.getCode(), code)) + .findFirst().orElse(null); + } + + public static ActCouponRecordStatusEnum descOf(String description) { + return Arrays.stream(ActCouponRecordStatusEnum.values()) + .filter(v -> ObjectUtil.equal(v.getDesc(), description)) + .findFirst().orElse(null); + } +} diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/act/ActTypeEnum.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/act/ActTypeEnum.java new file mode 100644 index 000000000..475b5a03d --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/act/ActTypeEnum.java @@ -0,0 +1,41 @@ +package com.bsd.pjcloud.wallet.api.constant.act; + +import cn.hutool.core.util.ObjectUtil; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; +import java.util.List; + +/** + * 核销活动状体啊 + */ +@Getter +@AllArgsConstructor +public enum ActTypeEnum { + + CANCEL_ACT("1", "核销活动", 1), + COUPON_ACT("2", "优惠券活动", 2), + ; + + private final String code; + private final String desc; + private final int priority; + + public static ActTypeEnum valueOfByType(String code) { + return Arrays.stream(ActTypeEnum.values()) + .filter(v -> ObjectUtil.equal(v.getCode(), code)) + .findFirst().get(); + } + + public static ActTypeEnum descOf(String description) { + return Arrays.stream(ActTypeEnum.values()) + .filter(v -> ObjectUtil.equal(v.getDesc(), description)) + .findFirst().get(); + } + + public static List sortList(){ + return Arrays.asList(ActTypeEnum.values()).stream().sorted((o1, o2) -> o2.priority - o1.priority).toList(); + } + +} diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/act/ActUserReceiveEnum.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/act/ActUserReceiveEnum.java new file mode 100644 index 000000000..68429e89d --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/act/ActUserReceiveEnum.java @@ -0,0 +1,40 @@ +package com.bsd.pjcloud.wallet.api.constant.act; + +import cn.hutool.core.util.ObjectUtil; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 用户活动状态 + */ +@Getter +@AllArgsConstructor +public enum ActUserReceiveEnum { + + ACT_EXPIRED("1", "活动不在进行中"), + ACT_NOT_EXIST("2", "活动不存在"), + ACT_NOT_STARTED("3", "活动未开启"), + USER_LIMIT_REACHED("4", "用户参加活动已达上限"), + USER_CANNOT_PARTICIPATE("5", "用户不能参加此活动"), + OTHER_ERROR("6", "其他错误"), + USER_CAN_JOIN_ACT("99", "用户可以参加活动"), + ; + + private final String code; + private final String desc; + + public static ActUserReceiveEnum valueOfByType(String code) { + return Arrays.stream(ActUserReceiveEnum.values()) + .filter(v -> ObjectUtil.equal(v.getCode(), code)) + .findFirst().orElse(null); + } + + public static ActUserReceiveEnum descOf(String description) { + return Arrays.stream(ActUserReceiveEnum.values()) + .filter(v -> ObjectUtil.equal(v.getDesc(), description)) + .findFirst().orElse(null); + } + +} diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/act/ActCouponReceiveDto.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/act/ActCouponReceiveDto.java new file mode 100644 index 000000000..be0bcea7e --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/act/ActCouponReceiveDto.java @@ -0,0 +1,20 @@ +package com.bsd.pjcloud.wallet.api.dto.act; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +public class ActCouponReceiveDto { + + /** + * 领取优惠券的用户id + */ + private Long receiveUserId; + + /** + * 优惠券id + */ + @NotNull(message = "优惠券id不能为空") + private Long couponId; + +} diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/act/ActCouponEntity.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/act/ActCouponEntity.java index 46b8e7bb5..14761bc2e 100755 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/act/ActCouponEntity.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/act/ActCouponEntity.java @@ -27,6 +27,18 @@ public class ActCouponEntity extends Model { @Schema(description = "优惠券ID") private Long id; + /** + * 优惠券活动唯一code + */ + @Schema(description = "优惠券活动唯一code") + private String uniqueCode; + + /** + * 绑定的通知id + */ + @Schema(description = "绑定的通知id") + private Long bindNotifyId; + /** * 优惠券名称 */ diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/act/ActCouponRecordEntity.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/act/ActCouponRecordEntity.java index 3d7702871..7c1b22c68 100755 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/act/ActCouponRecordEntity.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/act/ActCouponRecordEntity.java @@ -51,9 +51,9 @@ public class ActCouponRecordEntity extends Model { private String couponCode; /** - * 使用状态 (0:未使用 1:已使用 2:已过期 3:已作废) + * 使用状态(1:未使用2:已使用3:已过期4:已作废) */ - @Schema(description = "使用状态 (0:未使用 1:已使用 2:已过期 3:已作废)") + @Schema(description = "使用状态(1:未使用2:已使用3:已过期4:已作废)") private String status; /** diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/vo/act/ActSimpleNotfiyVo.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/vo/act/ActSimpleNotfiyVo.java new file mode 100644 index 000000000..44c4fc6da --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/vo/act/ActSimpleNotfiyVo.java @@ -0,0 +1,14 @@ +package com.bsd.pjcloud.wallet.api.vo.act; + +import com.bsd.pjcloud.wallet.api.constant.act.ActTypeEnum; +import lombok.Data; + +@Data +public class ActSimpleNotfiyVo { + + private ActTypeEnum actType; + + private Long actId; + + private T detail; +} diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/act/ActComController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/act/ActComController.java new file mode 100644 index 000000000..9f9fed629 --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/act/ActComController.java @@ -0,0 +1,53 @@ +package com.bsd.pjcloud.wallet.controller.act; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.bsd.pjcloud.common.core.util.R; +import com.bsd.pjcloud.common.security.service.PjcloudUser; +import com.bsd.pjcloud.common.security.util.SecurityUtils; +import com.bsd.pjcloud.wallet.api.constant.act.ActTypeEnum; +import com.bsd.pjcloud.wallet.api.constant.act.ActUserReceiveEnum; +import com.bsd.pjcloud.wallet.api.vo.act.ActCouponVo; +import com.bsd.pjcloud.wallet.api.vo.act.ActSimpleNotfiyVo; +import com.bsd.pjcloud.wallet.service.ActComService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * 活动公用方法 + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/act/com") +@Tag(description = "act-com", name = "活动公用方法") +@SecurityRequirement(name = HttpHeaders.AUTHORIZATION) +public class ActComController { + + private final ActComService actComService; + + @Operation(summary = "根据公告id查询对应的活动", description = "根据公告id查询对应的活动") + @GetMapping("/app/get-act-by-notify-id") + public R getActByNotifyId(@RequestParam Long notifyId) { + return R.ok(actComService.getActByNotifyId(notifyId)); + } + + @Operation(summary = "获取活动详情", description = "获取活动详情") + @GetMapping("/app/get-act-detail") + public R getActDetail(@RequestParam ActTypeEnum actType, @RequestParam Long actId) { + return R.ok(actComService.getActDetail(actType, actId)); + } + + @Operation(summary = "判断用户是否可以参加活动", description = "判断用户是否可以参加活动") + @GetMapping("/app/is-eligible-for-act") + public R isEligibleForAct(@RequestParam ActTypeEnum actType, @RequestParam Long actId) { + PjcloudUser user = SecurityUtils.getUser(); + return R.ok(actComService.isEligibleForAct(actType, actId, user.getId())); + } + +} diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/act/ActCouponController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/act/ActCouponController.java index fa04a321d..6f0ee90a5 100755 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/act/ActCouponController.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/act/ActCouponController.java @@ -6,9 +6,11 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.bsd.pjcloud.common.core.util.R; +import com.bsd.pjcloud.common.data.datascope.DataScope; import com.bsd.pjcloud.common.log.annotation.SysLog; import com.bsd.pjcloud.wallet.api.dto.act.ActCouponDto; import com.bsd.pjcloud.wallet.api.entity.act.ActCouponEntity; +import com.bsd.pjcloud.wallet.api.vo.act.ActCouponVo; import com.bsd.pjcloud.wallet.service.ActCouponService; import org.springframework.security.access.prepost.PreAuthorize; import com.bsd.pjcloud.common.excel.annotation.ResponseExcel; @@ -41,9 +43,8 @@ public class ActCouponController { @Operation(summary = "分页查询", description = "分页查询") @GetMapping("/page") @PreAuthorize("@pms.hasPermission('wallet_actCoupon_view')") - public R getActCouponPage(@ParameterObject Page page, @ParameterObject ActCouponDto dto) { - LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); - return R.ok(actCouponService.page(page, wrapper)); + public R> getActCouponPage(@ParameterObject Page page, @ParameterObject ActCouponDto dto) { + return R.ok(actCouponService.pageJoin(page, dto)); } /** @@ -63,8 +64,8 @@ public class ActCouponController { @SysLog("新增优惠券活动") @PostMapping @PreAuthorize("@pms.hasPermission('wallet_actCoupon_add')") - public R save(@RequestBody ActCouponEntity actCoupon) { - return R.ok(actCouponService.save(actCoupon)); + public R save(@RequestBody ActCouponEntity actCoupon) { + return R.ok(actCouponService.create(actCoupon)); } /** @@ -75,7 +76,8 @@ public class ActCouponController { @PutMapping @PreAuthorize("@pms.hasPermission('wallet_actCoupon_edit')") public R updateById(@RequestBody ActCouponEntity actCoupon) { - return R.ok(actCouponService.updateById(actCoupon)); + actCouponService.modify(actCoupon); + return R.ok(); } /** @@ -86,7 +88,8 @@ public class ActCouponController { @DeleteMapping @PreAuthorize("@pms.hasPermission('wallet_actCoupon_del')") public R removeById(@RequestBody Long[] ids) { - return R.ok(actCouponService.removeBatchByIds(CollUtil.toList(ids))); + actCouponService.delByIds(CollUtil.toList(ids)); + return R.ok(); } /** diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/act/ActCouponRecordController.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/act/ActCouponRecordController.java index 97ec5998a..34cf84e0e 100755 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/act/ActCouponRecordController.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/controller/act/ActCouponRecordController.java @@ -6,10 +6,15 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.bsd.pjcloud.common.core.util.R; +import com.bsd.pjcloud.common.idempotent.annotation.Idempotent; import com.bsd.pjcloud.common.log.annotation.SysLog; +import com.bsd.pjcloud.common.security.service.PjcloudUser; +import com.bsd.pjcloud.common.security.util.SecurityUtils; +import com.bsd.pjcloud.wallet.api.dto.act.ActCouponReceiveDto; import com.bsd.pjcloud.wallet.api.dto.act.ActCouponRecordDto; import com.bsd.pjcloud.wallet.api.entity.act.ActCouponRecordEntity; import com.bsd.pjcloud.wallet.service.ActCouponRecordService; +import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; import com.bsd.pjcloud.common.excel.annotation.ResponseExcel; import io.swagger.v3.oas.annotations.security.SecurityRequirement; @@ -27,19 +32,33 @@ import java.util.List; */ @RestController @RequiredArgsConstructor -@RequestMapping("/actCouponRecord" ) -@Tag(description = "actCouponRecord" , name = "优惠券领取记录表管理" ) +@RequestMapping("/act-coupon-record") +@Tag(description = "act-coupon-record", name = "优惠券领取记录表管理") @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) public class ActCouponRecordController { - private final ActCouponRecordService actCouponRecordService; + private final ActCouponRecordService actCouponRecordService; + + /* ************************************* start app start ************************************* */ + + @Operation(summary = "领取优惠券", description = "领取优惠券") + @PostMapping("/app/receive") + @Idempotent(expireTime = 2, key = "'/act/receive/app/receive/' + #dto.getReceiveUserId()", info = "正在领取中,请勿重复操作") + public R appReceive(@Valid @RequestBody ActCouponReceiveDto dto) { + PjcloudUser user = SecurityUtils.getUser(); + dto.setReceiveUserId(user.getId()); + return R.ok(actCouponRecordService.appReceive(dto)); + } + + + /* ************************************* end app end ************************************* */ /** * 分页查询 */ - @Operation(summary = "分页查询" , description = "分页查询" ) - @GetMapping("/page" ) - @PreAuthorize("@pms.hasPermission('wallet_actCouponRecord_view')" ) + @Operation(summary = "分页查询", description = "分页查询") + @GetMapping("/page") + @PreAuthorize("@pms.hasPermission('wallet_actCouponRecord_view')") public R getActCouponRecordPage(@ParameterObject Page page, @ParameterObject ActCouponRecordDto dto) { LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); return R.ok(actCouponRecordService.page(page, wrapper)); @@ -49,20 +68,20 @@ public class ActCouponRecordController { /** * 通过id查询优惠券领取记录表 */ - @Operation(summary = "通过id查询" , description = "通过id查询" ) - @GetMapping("/{id}" ) - @PreAuthorize("@pms.hasPermission('wallet_actCouponRecord_view')" ) - public R getById(@PathVariable("id" ) Long id) { + @Operation(summary = "通过id查询", description = "通过id查询") + @GetMapping("/{id}") + @PreAuthorize("@pms.hasPermission('wallet_actCouponRecord_view')") + public R getById(@PathVariable("id") Long id) { return R.ok(actCouponRecordService.getById(id)); } /** * 新增优惠券领取记录表 */ - @Operation(summary = "新增优惠券领取记录表" , description = "新增优惠券领取记录表" ) - @SysLog("新增优惠券领取记录表" ) + @Operation(summary = "新增优惠券领取记录表", description = "新增优惠券领取记录表") + @SysLog("新增优惠券领取记录表") @PostMapping - @PreAuthorize("@pms.hasPermission('wallet_actCouponRecord_add')" ) + @PreAuthorize("@pms.hasPermission('wallet_actCouponRecord_add')") public R save(@RequestBody ActCouponRecordEntity actCouponRecord) { return R.ok(actCouponRecordService.save(actCouponRecord)); } @@ -70,10 +89,10 @@ public class ActCouponRecordController { /** * 修改优惠券领取记录表 */ - @Operation(summary = "修改优惠券领取记录表" , description = "修改优惠券领取记录表" ) - @SysLog("修改优惠券领取记录表" ) + @Operation(summary = "修改优惠券领取记录表", description = "修改优惠券领取记录表") + @SysLog("修改优惠券领取记录表") @PutMapping - @PreAuthorize("@pms.hasPermission('wallet_actCouponRecord_edit')" ) + @PreAuthorize("@pms.hasPermission('wallet_actCouponRecord_edit')") public R updateById(@RequestBody ActCouponRecordEntity actCouponRecord) { return R.ok(actCouponRecordService.updateById(actCouponRecord)); } @@ -81,10 +100,10 @@ public class ActCouponRecordController { /** * 通过id删除优惠券领取记录表 */ - @Operation(summary = "通过id删除优惠券领取记录表" , description = "通过id删除优惠券领取记录表" ) - @SysLog("通过id删除优惠券领取记录表" ) + @Operation(summary = "通过id删除优惠券领取记录表", description = "通过id删除优惠券领取记录表") + @SysLog("通过id删除优惠券领取记录表") @DeleteMapping - @PreAuthorize("@pms.hasPermission('wallet_actCouponRecord_del')" ) + @PreAuthorize("@pms.hasPermission('wallet_actCouponRecord_del')") public R removeById(@RequestBody Long[] ids) { return R.ok(actCouponRecordService.removeBatchByIds(CollUtil.toList(ids))); } @@ -94,8 +113,8 @@ public class ActCouponRecordController { */ @ResponseExcel @GetMapping("/export") - @PreAuthorize("@pms.hasPermission('wallet_actCouponRecord_export')" ) - public List export(ActCouponRecordEntity actCouponRecord,Long[] ids) { + @PreAuthorize("@pms.hasPermission('wallet_actCouponRecord_export')") + public List export(ActCouponRecordEntity actCouponRecord, Long[] ids) { return actCouponRecordService.list(Wrappers.lambdaQuery(actCouponRecord).in(ArrayUtil.isNotEmpty(ids), ActCouponRecordEntity::getId, ids)); } } \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/act/ActCouponMapper.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/act/ActCouponMapper.java index a0f5088fb..a37075e4a 100755 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/act/ActCouponMapper.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/act/ActCouponMapper.java @@ -1,10 +1,16 @@ package com.bsd.pjcloud.wallet.mapper.act; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper; +import com.bsd.pjcloud.wallet.api.dto.act.ActCouponDto; import com.bsd.pjcloud.wallet.api.entity.act.ActCouponEntity; +import com.bsd.pjcloud.wallet.api.vo.act.ActCouponVo; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; @Mapper public interface ActCouponMapper extends PjcloudBaseMapper { + Page pageJoin(Page page, @Param("dto") ActCouponDto dto); + } \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/mch/view/MchDeptViewMapper.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/mch/view/MchDeptViewMapper.java index 4184bd696..cda0073fc 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/mch/view/MchDeptViewMapper.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/mapper/mch/view/MchDeptViewMapper.java @@ -14,4 +14,6 @@ public interface MchDeptViewMapper { List selectList(@Param("dto") WalletMchDeptViewDto dto); + WalletMchDeptViewVo selectByUserId(@Param("userId") Long userId); + } diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActCancelItemService.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActCancelItemService.java index 5acc3833a..4d94ac456 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActCancelItemService.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActCancelItemService.java @@ -3,6 +3,7 @@ package com.bsd.pjcloud.wallet.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.bsd.pjcloud.common.security.service.PjcloudUser; +import com.bsd.pjcloud.wallet.api.constant.act.ActUserReceiveEnum; import com.bsd.pjcloud.wallet.api.dto.act.ActCancelItemDto; import com.bsd.pjcloud.wallet.api.entity.act.ActCancelItemEntity; import com.bsd.pjcloud.wallet.api.vo.act.ActCancelItemVo; @@ -22,6 +23,11 @@ public interface ActCancelItemService extends IService { */ ActCancelItemVo appFindUnique(Long actId, PjcloudUser user); + /** + * 判断用户是否可以参加活动 + */ + ActUserReceiveEnum isEligibleForAct(Long actId, Long userId); + /** * app查询本店优惠券列表 */ diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActComService.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActComService.java new file mode 100644 index 000000000..f30298bd8 --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActComService.java @@ -0,0 +1,23 @@ +package com.bsd.pjcloud.wallet.service; + + +import com.bsd.pjcloud.wallet.api.constant.act.ActTypeEnum; +import com.bsd.pjcloud.wallet.api.vo.act.ActSimpleNotfiyVo; + +public interface ActComService { + + /** + * 根据公告id查询对应的活动 + */ + ActSimpleNotfiyVo getActByNotifyId(Long notifyId); + + /** + * 获取活动详情 + */ + ActSimpleNotfiyVo getActDetail(ActTypeEnum actType, Long actId); + + /** + * 判断用户是否可以参加活动 + */ + String isEligibleForAct(ActTypeEnum actType, Long actId, Long userId); +} diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActCouponLifecycleService.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActCouponLifecycleService.java new file mode 100644 index 000000000..cb8575eb1 --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActCouponLifecycleService.java @@ -0,0 +1,35 @@ +package com.bsd.pjcloud.wallet.service; + +import com.bsd.pjcloud.wallet.api.entity.act.ActCouponEntity; +import com.bsd.pjcloud.wallet.api.entity.act.ActCouponRecordEntity; + +public interface ActCouponLifecycleService { + + /** + * 领取优惠券前的校验 + * @param couponId 优惠券ID + * @param userId 用户ID + * @return 优惠券实体 + */ + ActCouponEntity preReceive(Long couponId, Long userId); + + /** + * 领取优惠券后的处理 + * @param record 优惠券记录实体 + */ + void afterReceive(ActCouponRecordEntity record); + + /** + * 核销前的校验 + * @param record 优惠券记录实体 + * @return 优惠券实体 + */ + ActCouponRecordEntity preCancel(ActCouponRecordEntity record); + + /** + * 核销后的处理 + * @param record 优惠券记录实体 + */ + void afterCancel(ActCouponRecordEntity record); +} + diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActCouponRecordService.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActCouponRecordService.java index 104d2feb4..3405e88f2 100755 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActCouponRecordService.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActCouponRecordService.java @@ -1,8 +1,19 @@ package com.bsd.pjcloud.wallet.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.bsd.pjcloud.wallet.api.constant.act.ActUserReceiveEnum; +import com.bsd.pjcloud.wallet.api.dto.act.ActCouponReceiveDto; import com.bsd.pjcloud.wallet.api.entity.act.ActCouponRecordEntity; public interface ActCouponRecordService extends IService { + /** + * 领取优惠券 + */ + Long appReceive(ActCouponReceiveDto dto); + + /** + * 判断用户是否可以参加活动 + */ + ActUserReceiveEnum isEligibleForAct(Long actId, Long userId); } \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActCouponService.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActCouponService.java index ba6ecf782..bc87f4434 100755 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActCouponService.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/ActCouponService.java @@ -1,8 +1,38 @@ package com.bsd.pjcloud.wallet.service; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; +import com.bsd.pjcloud.wallet.api.dto.act.ActCouponDto; +import com.bsd.pjcloud.wallet.api.entity.act.ActCancelEntity; import com.bsd.pjcloud.wallet.api.entity.act.ActCouponEntity; +import com.bsd.pjcloud.wallet.api.vo.act.ActCouponVo; + +import java.util.ArrayList; public interface ActCouponService extends IService { + /** + * 分页查询 + */ + Page pageJoin(Page page, ActCouponDto dto); + + /** + * 新增优惠券 + */ + Long create(ActCouponEntity actCoupon); + + /** + * 修改优惠券 + */ + void modify(ActCouponEntity actCoupon); + + /** + * 删除优惠券 + */ + void delByIds(ArrayList list); + + /** + * 根据公告id查询核销活动 + */ + ActCouponEntity getDetailByNoticeId(Long notifyId); } \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/act/ActCancelItemServiceImpl.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/act/ActCancelItemServiceImpl.java index 44f69e7b5..7e3fe72da 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/act/ActCancelItemServiceImpl.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/act/ActCancelItemServiceImpl.java @@ -16,6 +16,7 @@ import com.bsd.pjcloud.common.security.service.PjcloudUser; import com.bsd.pjcloud.wallet.api.constant.WalletTypeEnum; import com.bsd.pjcloud.wallet.api.constant.act.ActCancelStatusEnum; import com.bsd.pjcloud.wallet.api.constant.act.ActStatusEnum; +import com.bsd.pjcloud.wallet.api.constant.act.ActUserReceiveEnum; import com.bsd.pjcloud.wallet.api.dto.act.ActCancelItemDto; import com.bsd.pjcloud.wallet.api.entity.WalletManageEntity; import com.bsd.pjcloud.wallet.api.entity.act.ActCancelEntity; @@ -152,10 +153,10 @@ public class ActCancelItemServiceImpl extends ServiceImpl() + .eq(ActCancelItemEntity::getActId, actId) + .eq(ActCancelItemEntity::getReceiverUserId, userId) + ); + if (ObjectUtil.isEmpty(detail)) { + return ActUserReceiveEnum.USER_LIMIT_REACHED; + } + if (ObjectUtil.isNotEmpty(detail.getExpireTime())) { + if (detail.getExpireTime().isBefore(LocalDateTime.now())) { + return ActUserReceiveEnum.ACT_EXPIRED; + } + } + return ActUserReceiveEnum.USER_CAN_JOIN_ACT; + } + /** * app查询本店优惠券列表 */ diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/act/ActComServiceImpl.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/act/ActComServiceImpl.java new file mode 100644 index 000000000..303abcd5f --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/act/ActComServiceImpl.java @@ -0,0 +1,101 @@ +package com.bsd.pjcloud.wallet.service.impl.act; + +import cn.hutool.core.util.ObjectUtil; +import com.bsd.pjcloud.wallet.api.constant.act.ActTypeEnum; +import com.bsd.pjcloud.wallet.api.constant.act.ActUserReceiveEnum; +import com.bsd.pjcloud.wallet.api.entity.act.ActCancelEntity; +import com.bsd.pjcloud.wallet.api.entity.act.ActCouponEntity; +import com.bsd.pjcloud.wallet.api.vo.act.ActSimpleNotfiyVo; +import com.bsd.pjcloud.wallet.service.*; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 活动公用方法 + */ +@Service +@Slf4j +@RequiredArgsConstructor +public class ActComServiceImpl implements ActComService { + + private final ActCancelService actCancelService; + private final ActCancelItemService actCancelItemService; + + private final ActCouponService actCouponService; + private final ActCouponRecordService actCouponRecordService; + + /** + * 根据公告id查询对应的活动 + */ + @Override + public ActSimpleNotfiyVo getActByNotifyId(Long notifyId) { + ActSimpleNotfiyVo result = new ActSimpleNotfiyVo<>(); + List actEnumList = ActTypeEnum.sortList(); + for (ActTypeEnum act : actEnumList) { + if (ObjectUtil.equals(act, ActTypeEnum.CANCEL_ACT)) { + ActCancelEntity detail = actCancelService.getDetailByNoticeId(notifyId); + if (ObjectUtil.isNotEmpty(detail)) { + result.setActId(detail.getId()); + result.setActType(act); + result.setDetail(detail); + return result; + } + } + if (ObjectUtil.equals(act, ActTypeEnum.COUPON_ACT)) { + ActCouponEntity detail = actCouponService.getDetailByNoticeId(notifyId); + if (ObjectUtil.isNotEmpty(detail)) { + result.setActId(detail.getId()); + result.setActType(act); + result.setDetail(detail); + return result; + } + } + } + return null; + } + + /** + * 获取活动详情 + */ + @Override + public ActSimpleNotfiyVo getActDetail(ActTypeEnum actType, Long actId) { + ActSimpleNotfiyVo result = new ActSimpleNotfiyVo<>(); + result.setActId(actId); + if (ObjectUtil.equals(actType, ActTypeEnum.CANCEL_ACT)) { + ActCancelEntity detail = actCancelService.getById(actId); + if (ObjectUtil.isNotEmpty(detail)) { + result.setActType(actType); + result.setDetail(detail); + return result; + } + } + if (ObjectUtil.equals(actType, ActTypeEnum.COUPON_ACT)) { + ActCouponEntity detail = actCouponService.getById(actId); + if (ObjectUtil.isNotEmpty(detail)) { + result.setActType(actType); + result.setDetail(detail); + return result; + } + } + return null; + } + + /** + * 判断用户是否可以参加活动 + */ + @Override + public String isEligibleForAct(ActTypeEnum actType, Long actId, Long userId) { + ActUserReceiveEnum status = ActUserReceiveEnum.USER_CANNOT_PARTICIPATE; + // 核销活动目前只能参加一次 + if (ObjectUtil.equals(actType, ActTypeEnum.CANCEL_ACT)) { + status = actCancelItemService.isEligibleForAct(actId, userId); + } + if (ObjectUtil.equals(actType, ActTypeEnum.COUPON_ACT)) { + status = actCouponRecordService.isEligibleForAct(actId, userId); + } + return status.getCode(); + } +} diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/act/ActCouponRecordServiceImpl.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/act/ActCouponRecordServiceImpl.java index 7ca130a9c..7201a9a70 100755 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/act/ActCouponRecordServiceImpl.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/act/ActCouponRecordServiceImpl.java @@ -1,15 +1,102 @@ package com.bsd.pjcloud.wallet.service.impl.act; +import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bsd.pjcloud.admin.api.dto.UserInfo; +import com.bsd.pjcloud.admin.api.entity.SysUser; +import com.bsd.pjcloud.admin.api.feign.RemoteUserService; +import com.bsd.pjcloud.common.core.constant.enums.MerchantTypeEnum; +import com.bsd.pjcloud.common.core.exception.ServiceException; +import com.bsd.pjcloud.wallet.api.constant.act.ActUserReceiveEnum; +import com.bsd.pjcloud.wallet.api.dto.act.ActCouponReceiveDto; +import com.bsd.pjcloud.wallet.api.entity.act.ActCouponEntity; import com.bsd.pjcloud.wallet.api.entity.act.ActCouponRecordEntity; +import com.bsd.pjcloud.wallet.api.vo.MchManageVo; +import com.bsd.pjcloud.wallet.mapper.act.ActCouponMapper; import com.bsd.pjcloud.wallet.mapper.act.ActCouponRecordMapper; import com.bsd.pjcloud.wallet.service.ActCouponRecordService; +import com.bsd.pjcloud.wallet.service.MchManageService; +import com.bsd.pjcloud.wallet.utils.act.service.ActCouponComUtilService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + /** * 优惠券领取记录表 */ +@Slf4j +@RequiredArgsConstructor @Service public class ActCouponRecordServiceImpl extends ServiceImpl implements ActCouponRecordService { + private final ActCouponMapper actCouponMapper; + + private final MchManageService mchManageService; + private final ActCouponComUtilService actCouponComUtilService; + + private final RemoteUserService remoteUserService; + + /** + * 领取优惠券 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Long appReceive(ActCouponReceiveDto dto) { + // 1. 获取当前用户 + UserInfo userInfo = remoteUserService.getByUserId(dto.getReceiveUserId()).getData(); + if (ObjectUtil.isEmpty(userInfo)) { + throw new ServiceException("用户不存在"); + } + SysUser sysUser = userInfo.getSysUser(); + // 2. 预处理 + ActCouponEntity actCouponEntity = actCouponComUtilService.preReceive(dto.getCouponId(), dto.getReceiveUserId()); + if (ObjectUtil.isEmpty(actCouponEntity)) { + return null; + } + // 3. 特殊优惠券判断 + ActUserReceiveEnum specialCouponStatus = specialCoupon(actCouponEntity, sysUser); + if (ObjectUtil.isNotEmpty(specialCouponStatus) && ObjectUtil.notEqual(specialCouponStatus, ActUserReceiveEnum.USER_CAN_JOIN_ACT)) { + throw new ServiceException(specialCouponStatus.getDesc()); + } + // 4. 执行领取逻辑 + ActCouponRecordEntity record = actCouponComUtilService.doReceive(actCouponEntity, sysUser); + // 5. 优惠券领取成功后,执行生命周期方法 + actCouponComUtilService.afterReceive(record); + return record.getId(); + } + + public ActUserReceiveEnum specialCoupon(ActCouponEntity actCouponEntity, SysUser sysUser) { + // 食堂生日券 + if (ObjectUtil.equals(actCouponEntity.getUniqueCode(), "1qRgFo")) { + // 判断是否为食堂用户 + MchManageVo userMch = mchManageService.getFirstMchByDeptId(sysUser.getDeptId(), List.of(MerchantTypeEnum.CANTEEN)); + if (ObjectUtil.isEmpty(userMch)) { + return ActUserReceiveEnum.USER_CANNOT_PARTICIPATE; + } + // 判断用户最近一年充值是否为500,1500,800,2400 + + return ActUserReceiveEnum.USER_CAN_JOIN_ACT; + } + return null; + } + + /** + * 判断用户是否可以参加活动 + */ + @Override + public ActUserReceiveEnum isEligibleForAct(Long actId, Long userId) { + ActUserReceiveEnum userReceiveEnum = actCouponComUtilService.isEligibleForAct(actId, userId); + if (ObjectUtil.equals(userReceiveEnum, ActUserReceiveEnum.USER_CAN_JOIN_ACT)) { + UserInfo userInfo = remoteUserService.getByUserId(userId).getData(); + ActCouponEntity actCouponEntity = actCouponMapper.selectById(actId); + if (ObjectUtil.isNotEmpty(userInfo) && ObjectUtil.isNotEmpty(actCouponEntity)) { + userReceiveEnum = specialCoupon(actCouponEntity, userInfo.getSysUser()); + } + } + return userReceiveEnum; + } } \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/act/ActCouponServiceImpl.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/act/ActCouponServiceImpl.java index 18e51e810..00e0ebbc9 100755 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/act/ActCouponServiceImpl.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/act/ActCouponServiceImpl.java @@ -1,15 +1,91 @@ package com.bsd.pjcloud.wallet.service.impl.act; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.RandomUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bsd.pjcloud.wallet.api.dto.act.ActCouponDto; import com.bsd.pjcloud.wallet.api.entity.act.ActCouponEntity; +import com.bsd.pjcloud.wallet.api.vo.act.ActCouponVo; import com.bsd.pjcloud.wallet.mapper.act.ActCouponMapper; import com.bsd.pjcloud.wallet.service.ActCouponService; import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.List; + /** * 优惠券活动 */ @Service public class ActCouponServiceImpl extends ServiceImpl implements ActCouponService { + @Override + public Page pageJoin(Page page, ActCouponDto dto) { + return baseMapper.pageJoin(page, dto); + } + + /** + * 新增优惠券 + */ + @Override + public Long create(ActCouponEntity actCoupon) { + actCoupon.setUniqueCode(generateUniqueCode()); + baseMapper.insert(actCoupon); + return actCoupon.getId(); + } + + /** + * 修改优惠券 + */ + @Override + public void modify(ActCouponEntity actCoupon) { + // 是否存在 + ActCouponEntity exist = baseMapper.selectById(actCoupon.getId()); + if (ObjectUtil.isEmpty(exist)) { + throw new RuntimeException("优惠券不存在"); + } + if (ObjectUtil.isEmpty(exist.getUniqueCode())) { + actCoupon.setUniqueCode(generateUniqueCode()); + } + baseMapper.updateById(actCoupon); + } + + /** + * 删除优惠券 + */ + @Override + public void delByIds(ArrayList list) { + List couponList = baseMapper.selectByIds(list); + if (ObjectUtil.isEmpty(couponList)) return; + for (ActCouponEntity coupon : couponList) { + // 如果有人领取了优惠券,则不能删除 + } + baseMapper.deleteByIds(list); + } + + /** + * 根据公告id查询核销活动 + */ + @Override + public ActCouponEntity getDetailByNoticeId(Long notifyId) { + return baseMapper.selectOne(new LambdaQueryWrapper() + .eq(ActCouponEntity::getBindNotifyId, notifyId) + ); + } + + /** + * 生成唯一code + */ + private String generateUniqueCode() { + String string = RandomUtil.randomString(6); + while (true) { + Long isExist = baseMapper.selectCount(new LambdaQueryWrapper().eq(ActCouponEntity::getUniqueCode, string)); + if (isExist == null || isExist == 0) { + return string; + } + } + } + } \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/utils/act/impl/ActCouponLifecycleService.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/utils/act/impl/ActCouponLifecycleService.java new file mode 100644 index 000000000..ec5b96b88 --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/utils/act/impl/ActCouponLifecycleService.java @@ -0,0 +1,27 @@ +package com.bsd.pjcloud.wallet.utils.act.impl; + +import com.bsd.pjcloud.wallet.api.entity.act.ActCouponEntity; +import com.bsd.pjcloud.wallet.api.entity.act.ActCouponRecordEntity; + +/** + * 优惠券生命周期 + */ +public interface ActCouponLifecycleService { + + /** + * 领取优惠券前的校验 + * + * @param couponId 优惠券ID + * @param userId 用户ID + * @return 优惠券实体 + */ + ActCouponEntity preReceive(Long couponId, Long userId); + + /** + * 领取优惠券后的处理 + * + * @param record 优惠券记录实体 + */ + void afterReceive(ActCouponRecordEntity record); + +} diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/utils/act/service/ActCouponComUtilService.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/utils/act/service/ActCouponComUtilService.java new file mode 100644 index 000000000..faa05c3d7 --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/utils/act/service/ActCouponComUtilService.java @@ -0,0 +1,252 @@ +package com.bsd.pjcloud.wallet.utils.act.service; + +import cn.hutool.core.lang.UUID; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.bsd.pjcloud.admin.api.entity.SysUser; +import com.bsd.pjcloud.wallet.api.constant.act.*; +import com.bsd.pjcloud.wallet.api.entity.act.ActCouponEntity; +import com.bsd.pjcloud.wallet.api.entity.act.ActCouponRecordEntity; +import com.bsd.pjcloud.wallet.mapper.act.ActCouponMapper; +import com.bsd.pjcloud.wallet.mapper.act.ActCouponRecordMapper; +import com.bsd.pjcloud.wallet.service.ActCouponLifecycleService; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.temporal.TemporalAdjusters; + +/** + * @author liusiyang_dxm + * @since 2026/1/28 + */ +@Service +@AllArgsConstructor +public class ActCouponComUtilService implements ActCouponLifecycleService { + + private final ActCouponMapper actCouponMapper; + private final ActCouponRecordMapper actCouponRecordMapper; + + /** + * 领取优惠券前的校验 + */ + @Override + public ActCouponEntity preReceive(Long couponId, Long userId) { + ActCouponEntity coupon = actCouponMapper.selectById(couponId); + if (ObjectUtil.isEmpty(coupon)) { + throw new RuntimeException("此优惠券活动不存在"); + } + + assertStatus(coupon); + assertReceiveWindow(coupon); + assertLimit(coupon, userId); + + return coupon; + } + + /** + * 领取优惠券 + */ + public ActCouponRecordEntity doReceive(ActCouponEntity coupon, SysUser sysUser) { + ActCouponRecordEntity record = new ActCouponRecordEntity(); + record.setCouponId(coupon.getId()); + record.setUserId(sysUser.getUserId()); + record.setUserName(sysUser.getName()); + record.setCouponCode(UUID.fastUUID().toString()); + record.setStatus(ActCouponRecordStatusEnum.UNUSED.getCode()); + // 优惠券冗余字段(不更新) + record.setCouponName(coupon.getName()); + record.setCouponType(coupon.getType()); + record.setFaceValue(coupon.getFaceValue()); + record.setMinPoint(coupon.getMinPoint()); + // 这个时间要根据`优惠券过期类型来设置` + // 1-固定日期 + if (ObjectUtil.equals(ActCouponValidTypeEnum.FIXED_DATE.getCode(), coupon.getValidType())) { + record.setStartTime(coupon.getValidStartTime()); + record.setEndTime(coupon.getValidEndTime()); + } + // 2-领取后生效 + if (ObjectUtil.equals(ActCouponValidTypeEnum.AFTER_RECEIVE.getCode(), coupon.getValidType())) { + Integer validDays = coupon.getValidDays(); + record.setStartTime(LocalDateTime.now()); + record.setEndTime(record.getStartTime().plusDays(validDays)); + } + actCouponRecordMapper.insert(record); + return record; + } + + /** + * 领取优惠券后的处理 + */ + @Override + public void afterReceive(ActCouponRecordEntity record) { + + } + + /** + * 核销前的校验 + */ + @Override + public ActCouponRecordEntity preCancel(ActCouponRecordEntity record) { + ActCouponRecordEntity couponRecord = actCouponRecordMapper.selectById(record.getCouponId()); + if (ObjectUtil.isEmpty(couponRecord)) { + throw new RuntimeException("优惠券不存在"); + } + // 基本校验:状态是否可用 + if (ObjectUtil.notEqual(ActCouponRecordStatusEnum.UNUSED.getCode(), couponRecord.getStatus())) { + throw new RuntimeException("优惠券不可用"); + } + // 校验有效期 + LocalDateTime now = LocalDateTime.now(); + if (ObjectUtil.isNotEmpty(couponRecord.getStartTime()) && now.isBefore(couponRecord.getStartTime())) { + throw new RuntimeException("优惠券尚未生效"); + } + if (ObjectUtil.isNotEmpty(couponRecord.getEndTime()) && now.isAfter(couponRecord.getEndTime())) { + throw new RuntimeException("优惠券已过期"); + } + return couponRecord; + } + + public void doCancel(Long couponRecordId, Long orderId, int carTotalPrice) { + ActCouponRecordEntity couponRecord = actCouponRecordMapper.selectById(couponRecordId); + if (ObjectUtil.isEmpty(couponRecord)) { + throw new RuntimeException("此优惠券不存在"); + } + ActCouponRecordEntity updateObj = new ActCouponRecordEntity(); + updateObj.setId(couponRecordId); + updateObj.setStatus(ActCouponRecordStatusEnum.USED.getCode()); + updateObj.setUseTime(LocalDateTime.now()); + updateObj.setOrderId(String.valueOf(orderId)); + updateObj.setUseAmount(carTotalPrice); + actCouponRecordMapper.updateById(updateObj); + } + + /** + * 核销后的处理 + */ + @Override + public void afterCancel(ActCouponRecordEntity record) { + + } + + /** + * 查询用户是否可以参加活动 + */ + public ActUserReceiveEnum isEligibleForAct(Long couponId, Long userId) { + ActCouponEntity coupon = actCouponMapper.selectById(couponId); + if (ObjectUtil.isEmpty(coupon)) { + return ActUserReceiveEnum.ACT_NOT_EXIST; + } + try { + assertStatus(coupon); + } catch (Exception e) { + return ActUserReceiveEnum.ACT_NOT_STARTED; + } + try { + assertReceiveWindow(coupon); + } catch (Exception e) { + return ActUserReceiveEnum.ACT_EXPIRED; + } + try { + assertLimit(coupon, userId); + } catch (Exception e) { + return ActUserReceiveEnum.USER_LIMIT_REACHED; + } + return ActUserReceiveEnum.USER_CAN_JOIN_ACT; + } + + + /** + * 校验优惠券活动状态为进行中 + */ + private void assertStatus(ActCouponEntity coupon) { + if (!ObjectUtil.equals(ActCouponStatusEnum.JINXINGZHONG.getCode(), coupon.getStatus())) { + throw new RuntimeException("此优惠券不在进行中"); + } + } + + /** + * 校验领取时间窗(固定日期型需在有效期内) + */ + private void assertReceiveWindow(ActCouponEntity coupon) { + if (ObjectUtil.equals(ActCouponValidTypeEnum.FIXED_DATE.getCode(), coupon.getValidType())) { + LocalDateTime now = LocalDateTime.now(); + if (ObjectUtil.isNotEmpty(coupon.getValidStartTime()) && now.isBefore(coupon.getValidStartTime())) { + throw new RuntimeException("此优惠券活动尚未开始"); + } + if (ObjectUtil.isNotEmpty(coupon.getValidEndTime()) && now.isAfter(coupon.getValidEndTime())) { + throw new RuntimeException("此优惠券活动已结束"); + } + } + } + + /** + * 校验用户在限领规则下是否超过可领取次数 + */ + private void assertLimit(ActCouponEntity coupon, Long userId) { + if (ObjectUtil.isEmpty(coupon.getLimitCount()) || coupon.getLimitCount() <= 0) { + return; + } + + LocalDateTime start = buildLimitStartTime(coupon.getLimitType()); + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(ActCouponRecordEntity::getCouponId, coupon.getId()).eq(ActCouponRecordEntity::getUserId, userId); + if (ObjectUtil.isNotEmpty(start)) { + wrapper.ge(ActCouponRecordEntity::getCreateTime, start); + } + Long cnt = actCouponRecordMapper.selectCount(wrapper); + if (cnt != null && cnt >= coupon.getLimitCount()) { + throw new RuntimeException(buildLimitExceededMessage(coupon.getLimitType())); + } + } + + /** + * 构造限领类型的统计起始时间(一次型不限制返回 null) + */ + private LocalDateTime buildLimitStartTime(String limitType) { + if (ObjectUtil.equals(ActCouponLimitTypeEnum.ONCE.getCode(), limitType)) { + return null; + } + LocalDate today = LocalDate.now(); + if (ObjectUtil.equals(ActCouponLimitTypeEnum.EVERY_DAY.getCode(), limitType)) { + return LocalDateTime.of(today, LocalTime.MIN); + } + if (ObjectUtil.equals(ActCouponLimitTypeEnum.EVERY_WEEK.getCode(), limitType)) { + LocalDate monday = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); + return LocalDateTime.of(monday, LocalTime.MIN); + } + if (ObjectUtil.equals(ActCouponLimitTypeEnum.EVERY_MONTH.getCode(), limitType)) { + LocalDate firstDay = today.with(TemporalAdjusters.firstDayOfMonth()); + return LocalDateTime.of(firstDay, LocalTime.MIN); + } + if (ObjectUtil.equals(ActCouponLimitTypeEnum.EVERY_YEAR.getCode(), limitType)) { + LocalDate firstDay = today.with(TemporalAdjusters.firstDayOfYear()); + return LocalDateTime.of(firstDay, LocalTime.MIN); + } + return null; + } + + private String buildLimitExceededMessage(String limitType) { + if (ObjectUtil.equals(ActCouponLimitTypeEnum.ONCE.getCode(), limitType)) { + return "活动期间已达领取上限"; + } + if (ObjectUtil.equals(ActCouponLimitTypeEnum.EVERY_DAY.getCode(), limitType)) { + return "今日已达领取上限"; + } + if (ObjectUtil.equals(ActCouponLimitTypeEnum.EVERY_WEEK.getCode(), limitType)) { + return "本周已达领取上限"; + } + if (ObjectUtil.equals(ActCouponLimitTypeEnum.EVERY_MONTH.getCode(), limitType)) { + return "本月已达领取上限"; + } + if (ObjectUtil.equals(ActCouponLimitTypeEnum.EVERY_YEAR.getCode(), limitType)) { + return "本年已达领取上限"; + } + return "已达到领取上限"; + } + +} diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/act/ActCouponMapper.xml b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/act/ActCouponMapper.xml index 7568de12f..8410d4523 100755 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/act/ActCouponMapper.xml +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/act/ActCouponMapper.xml @@ -2,9 +2,10 @@ - select a.id, + a.unique_code, + a.bind_notify_id, a.name, a.type, a.face_value, @@ -37,6 +38,16 @@ and a.type = #{dto.type} + + and a.status = #{dto.status} + + \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/mch/view/MchDeptViewMapper.xml b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/mch/view/MchDeptViewMapper.xml index 709f63c6e..e1a143647 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/mch/view/MchDeptViewMapper.xml +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/mch/view/MchDeptViewMapper.xml @@ -52,4 +52,6 @@ order by a.mchDeptId, a.level + \ No newline at end of file