diff --git a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/entity/order/HardOrderEntity.java b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/entity/order/HardOrderEntity.java index 0f1f7b4b4..aed8e7a88 100644 --- a/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/entity/order/HardOrderEntity.java +++ b/pjcloud-hardware/pjcloud-hardware-api/src/main/java/com/bsd/pjcloud/hard/api/entity/order/HardOrderEntity.java @@ -219,6 +219,18 @@ public class HardOrderEntity extends Model { @Schema(description = "离线自动支付是否成功") private String offlinePaySuccess; + /** + * 优惠券id + */ + @Schema(description = "优惠券id") + private String couponRecordId; + + /** + * 优惠金额 + */ + @Schema(description = "优惠金额") + private Integer couponPrice; + /** * 创建人 */ diff --git a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java index 56675da8f..81f93ef46 100644 --- a/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java +++ b/pjcloud-hardware/pjcloud-hardware-biz/src/main/java/com/bsd/pjcloud/hard/service/impl/order/HardAfterSaleServiceImpl.java @@ -45,6 +45,7 @@ import com.bsd.pjcloud.hard.mapper.order.HardAfterSaleMapper; import com.bsd.pjcloud.hard.mapper.order.HardOrderMapper; import com.bsd.pjcloud.hard.service.*; import com.bsd.pjcloud.wallet.api.dto.recharge.WalletRechargeRefundDto; +import com.bsd.pjcloud.wallet.api.feign.RemoteActCouponCancelService; import com.bsd.pjcloud.wallet.api.feign.RemoteWalletRechargeService; import com.bsd.pjcloud.wallet.api.feign.RemoteWalletSettingService; import com.bsd.pjcloud.wallet.api.vo.recharge.WalletRechargeVo; @@ -86,6 +87,7 @@ public class HardAfterSaleServiceImpl extends ServiceImpl 0) { + payPrice -= actCouponRecord.getUseAmountPrice(); + if (payPrice < 0) payPrice = 0; + useAmountPrice = actCouponRecord.getUseAmountPrice(); + } } String subject = "未知商品x?"; @@ -782,10 +790,14 @@ public class HardOrderServiceImpl extends ServiceImpl yyxService.send(orderObj.getMerchantId(), orderObj.getPayPrice(), userDetail.getSysUser().getPhone())); @@ -1048,6 +1064,9 @@ public class HardOrderServiceImpl extends ServiceImpl 0) { WalletBalanceTransactionDto reduceBuild = new WalletBalanceTransactionDto(); reduceBuild.setWalletId(order.getWalletId()); @@ -1078,6 +1097,9 @@ public class HardOrderServiceImpl extends ServiceImpl remoteCancel(@RequestBody ActCouponRecordRemoteCancelDto dto); + /** + * 退回优惠券 + */ + @NoToken + @GetMapping("/act-coupon-record/remote/return") + R remoteReturn(@RequestParam Long actCouponRecordId); + } 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 6f0ee90a5..28105ffd8 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 @@ -2,12 +2,14 @@ package com.bsd.pjcloud.wallet.controller.act; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; 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.constant.act.ActCouponTypeEnum; 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; @@ -65,6 +67,13 @@ public class ActCouponController { @PostMapping @PreAuthorize("@pms.hasPermission('wallet_actCoupon_add')") public R save(@RequestBody ActCouponEntity actCoupon) { + if (ObjectUtil.isNotEmpty(actCoupon.getTotalCount())) { + actCoupon.setSurplusCount(actCoupon.getTotalCount()); + } + // 如果是立减券,则使用门槛设置为0 + if (ObjectUtil.equals(actCoupon.getType(), ActCouponTypeEnum.LIJIAN_QUAN.getCode())) { + actCoupon.setMinPoint(0); + } return R.ok(actCouponService.create(actCoupon)); } @@ -76,6 +85,10 @@ public class ActCouponController { @PutMapping @PreAuthorize("@pms.hasPermission('wallet_actCoupon_edit')") public R updateById(@RequestBody ActCouponEntity actCoupon) { + // 如果是立减券,则使用门槛设置为0 + if (ObjectUtil.equals(actCoupon.getType(), ActCouponTypeEnum.LIJIAN_QUAN.getCode())) { + actCoupon.setMinPoint(0); + } actCouponService.modify(actCoupon); 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 e7e213726..52e14792a 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 @@ -64,6 +64,13 @@ public class ActCouponRecordController { return R.ok(actCouponRecordService.remoteCancel(dto)); } + @Inner() + @Operation(summary = "远程退回优惠券", description = "远程退回优惠券") + @GetMapping("/remote/return") + R remoteReturn(@RequestParam Long actCouponRecordId) { + return R.ok(actCouponRecordService.remoteCancel(actCouponRecordId)); + } + /* ************************************* end 远程调用 end ************************************* */ /* ************************************* start app start ************************************* */ 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 a37075e4a..4159c0a96 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 @@ -13,4 +13,12 @@ public interface ActCouponMapper extends PjcloudBaseMapper { Page pageJoin(Page page, @Param("dto") ActCouponDto dto); + /** + * 原子扣减库存(乐观锁) + * + * @param couponId 优惠券ID + * @return 影响行数,如果返回0表示库存不足 + */ + int deductStock(@Param("couponId") Long couponId); + } \ No newline at end of file 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 index 108ac7e1b..a41859ee6 100644 --- 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 @@ -20,7 +20,7 @@ public interface ActCouponLifecycleService { * * @param record 优惠券记录实体 */ - void afterReceive(ActCouponRecordEntity record, SysUser sysUser); + void afterReceive(ActCouponEntity coupon, ActCouponRecordEntity record, SysUser sysUser); /** * 核销前的校验 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 cae2f295f..b35812e5c 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 @@ -34,6 +34,11 @@ public interface ActCouponRecordService extends IService */ Boolean remoteCancel(ActCouponRecordRemoteCancelDto dto); + /** + * 远程退回优惠券 + */ + Boolean remoteCancel(Long actCouponRecordId); + /** * 远程查询优惠券详情 */ 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 b4508ff5f..52202b914 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 @@ -6,6 +6,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSON; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.bsd.pjcloud.admin.api.dto.UserInfo; @@ -138,7 +139,7 @@ public class ActCouponRecordServiceImpl extends ServiceImpl updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper + .eq(ActCouponRecordEntity::getId, detail.getId()) + .set(ActCouponRecordEntity::getStatus, ActCouponRecordStatusEnum.UNUSED.getCode()) + .set(ActCouponRecordEntity::getUseTime, null) + .set(ActCouponRecordEntity::getOrderId, null) + .set(ActCouponRecordEntity::getUseAmount, null); + + int rows = baseMapper.update(null, updateWrapper); + return rows > 0; + } + /** * 远程查询优惠券详情 */ @@ -192,7 +218,7 @@ public class ActCouponRecordServiceImpl extends ServiceImpl 0) { return 0; } - return detail.getUseAmount(); + return detail.getFaceValue(); } // 折扣券 else if (ObjectUtil.equals(detail.getCouponType(), ActCouponTypeEnum.ZHEKOU_QUAN.getCode())) { @@ -203,7 +229,7 @@ public class ActCouponRecordServiceImpl extends ServiceImpl 0) { + if (ObjectUtil.isNotEmpty(actCouponEntity.getSurplusCount()) && actCouponEntity.getSurplusCount() <= 0) { + userReceiveEnum = ActUserReceiveEnum.GET_DONE; + } } } } 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 index 8ef870723..8325f48dc 100644 --- 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 @@ -3,6 +3,7 @@ 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.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; 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; @@ -42,6 +43,14 @@ public class ActCouponComUtilService implements ActCouponLifecycleService { throw new RuntimeException("此优惠券活动不存在"); } + if (ObjectUtil.isNotEmpty(coupon.getTotalCount()) && coupon.getTotalCount() > 0) { + if (ObjectUtil.isNotEmpty(coupon.getSurplusCount())) { + if (coupon.getSurplusCount() <= 0) { + throw new RuntimeException("此优惠券已领完"); + } + } + } + assertStatus(coupon); assertReceiveWindow(coupon); assertLimit(coupon, userId); @@ -89,8 +98,12 @@ public class ActCouponComUtilService implements ActCouponLifecycleService { * 领取优惠券后的处理 */ @Override - public void afterReceive(ActCouponRecordEntity record, SysUser sysUser) { - + public void afterReceive(ActCouponEntity coupon, ActCouponRecordEntity record, SysUser sysUser) { + // 使用原子更新操作,避免并发问题 + int rows = actCouponMapper.deductStock(coupon.getId()); + if (rows == 0) { + throw new RuntimeException("优惠券库存不足或已被领完"); + } } /** 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 efd7f5cd0..e2c6cb9b1 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 @@ -4,30 +4,30 @@ select a.id, - a.unique_code, - a.bind_notify_id, - a.name, - a.type, - a.face_value, - a.min_point, - a.total_count, - a.surplus_count, - a.limit_count, - a.limit_type, - a.valid_type, - a.valid_start_time, - a.valid_end_time, - a.valid_days, - a.use_scope_type, - a.scope_id, - a.status, - a.description, - a.create_by, - a.create_time, - a.update_by, - a.update_time, - a.del_flag, - a.tenant_id + a.unique_code, + a.bind_notify_id, + a.name, + a.type, + a.face_value, + a.min_point, + a.total_count, + a.surplus_count, + a.limit_count, + a.limit_type, + a.valid_type, + a.valid_start_time, + a.valid_end_time, + a.valid_days, + a.use_scope_type, + a.scope_id, + a.status, + a.description, + a.create_by, + a.create_time, + a.update_by, + a.update_time, + a.del_flag, + a.tenant_id @@ -51,4 +51,14 @@ order by a.create_time desc , a.id desc + + + + UPDATE act_coupon + SET surplus_count = surplus_count - 1, + update_time = NOW() + WHERE id = #{couponId} + AND surplus_count > 0 + + \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/act/ActCouponRecordMapper.xml b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/act/ActCouponRecordMapper.xml index 1f7596999..63122b9cf 100755 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/act/ActCouponRecordMapper.xml +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/act/ActCouponRecordMapper.xml @@ -63,8 +63,15 @@