会员积分代码提交
This commit is contained in:
@@ -219,8 +219,8 @@ public class MemberPointsServiceImpl extends ServiceImpl<MemberPointsMapper, Mem
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean addPoints(Long memberId, int points, String content, Long orderId) {
|
||||
MemberPoints entity = initMemberPoints(memberId);
|
||||
public boolean addPoints(Long userId, int points, String content, Long orderId) {
|
||||
MemberPoints entity = initMemberPoints(userId);
|
||||
// 增加账户积分
|
||||
entity.setAccountPoints(entity.getAccountPoints() + points);
|
||||
entity.setLastPointsChangeTime(LocalDateTime.now());
|
||||
@@ -246,7 +246,7 @@ public class MemberPointsServiceImpl extends ServiceImpl<MemberPointsMapper, Mem
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void consumeAwardPoints(Long memberId, Long orderId) {
|
||||
public void consumeAwardPoints(Long userId, Long orderId) {
|
||||
OrderInfo orderInfo = orderInfoService.getById(orderId);
|
||||
if (orderInfo == null) {
|
||||
throw new CzgException("订单不存在");
|
||||
@@ -266,7 +266,7 @@ public class MemberPointsServiceImpl extends ServiceImpl<MemberPointsMapper, Mem
|
||||
String rewardsGroup = basicSetting.getRewardsGroup();
|
||||
MemberPoints entity;
|
||||
try {
|
||||
entity = initMemberPoints(memberId);
|
||||
entity = initMemberPoints(userId);
|
||||
} catch (Exception e) {
|
||||
return;
|
||||
}
|
||||
@@ -282,6 +282,6 @@ public class MemberPointsServiceImpl extends ServiceImpl<MemberPointsMapper, Mem
|
||||
return;
|
||||
}
|
||||
BigDecimal awardPoints = NumberUtil.roundDown(NumberUtil.div(payAmount, consumeAmount), 0);
|
||||
addPoints(memberId, awardPoints.intValue(), StrUtil.format("消费¥{}送{}积分", payAmount, awardPoints.intValue()), orderId);
|
||||
addPoints(userId, awardPoints.intValue(), StrUtil.format("消费¥{}送{}积分", payAmount, awardPoints.intValue()), orderId);
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,37 @@
|
||||
package com.czg.service.account.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.lang.Snowflake;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.servlet.JakartaServletUtil;
|
||||
import com.czg.account.dto.points.PointsExchangeRecordDTO;
|
||||
import com.czg.account.entity.*;
|
||||
import com.czg.account.enums.PointsExchangeStatusEnum;
|
||||
import com.czg.account.enums.PointsOrderPayTypeEnum;
|
||||
import com.czg.account.param.PointsExchangeCfParam;
|
||||
import com.czg.account.param.PointsExchangeRecordParam;
|
||||
import com.czg.account.param.PointsOrderCreateParam;
|
||||
import com.czg.account.param.PointsOrderPayParam;
|
||||
import com.czg.account.service.PointsExchangeRecordService;
|
||||
import com.czg.account.vo.PointsExchangeSummaryVo;
|
||||
import com.czg.exception.CzgException;
|
||||
import com.czg.sa.StpKit;
|
||||
import com.czg.service.account.mapper.*;
|
||||
import com.czg.utils.HttpContextUtil;
|
||||
import com.czg.utils.PageUtil;
|
||||
import com.czg.validator.ValidatorUtil;
|
||||
import com.czg.validator.group.DefaultGroup;
|
||||
import com.czg.validator.group.InsertGroup;
|
||||
import com.mybatisflex.core.paginate.Page;
|
||||
import com.mybatisflex.core.query.QueryColumn;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.core.update.UpdateChain;
|
||||
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -42,6 +55,7 @@ public class PointsExchangeRecordServiceImpl extends ServiceImpl<PointsExchangeR
|
||||
private final MemberPointsLogMapper memberPointsLogMapper;
|
||||
private final ShopInfoMapper shopInfoMapper;
|
||||
private final ShopMerchantMapper shopMerchantMapper;
|
||||
private final PointsBasicSettingMapper pointsBasicSettingMapper;
|
||||
|
||||
private QueryWrapper buildQueryWrapper(PointsExchangeRecordParam param) {
|
||||
QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
|
||||
@@ -107,6 +121,221 @@ public class PointsExchangeRecordServiceImpl extends ServiceImpl<PointsExchangeR
|
||||
pointsGoodsSettingMapper.update(goods);
|
||||
}
|
||||
|
||||
private Object[] verify(PointsOrderCreateParam param) {
|
||||
ValidatorUtil.validateEntity(param, InsertGroup.class);
|
||||
PointsBasicSetting basic = pointsBasicSettingMapper.selectOneByQuery(query().eq(PointsBasicSetting::getShopId, param.getShopId()));
|
||||
if (basic == null) {
|
||||
throw new CzgException("商家未配置积分锁客基本设置");
|
||||
}
|
||||
if (basic.getEnablePointsMall() != 1) {
|
||||
throw new CzgException("积分商城未开启");
|
||||
}
|
||||
PointsGoodsSetting goods = pointsGoodsSettingMapper.selectOneById(param.getPointsGoodsId());
|
||||
if (goods == null) {
|
||||
throw new CzgException("兑换的商品信息不存在");
|
||||
}
|
||||
if (goods.getDelFlag() == 1) {
|
||||
throw new CzgException("兑换的商品信息不存在");
|
||||
}
|
||||
param.setPointsGoodsName(goods.getGoodsName());
|
||||
param.setGoodsImageUrl(goods.getGoodsImageUrl());
|
||||
|
||||
Integer status = goods.getStatus();
|
||||
if (status != 1) {
|
||||
throw new CzgException("兑换的商品已下架");
|
||||
}
|
||||
Integer quantity = goods.getQuantity();
|
||||
if (quantity <= 0) {
|
||||
throw new CzgException("兑换的商品库存不足");
|
||||
}
|
||||
MemberPoints memberPoints = memberPointsMapper.selectOneByQuery(query().eq(MemberPoints::getUserId, param.getUserId()));
|
||||
if (memberPoints == null) {
|
||||
throw new CzgException("会员积分不足无法兑换此商品");
|
||||
}
|
||||
Integer accountPoints = memberPoints.getAccountPoints();
|
||||
Integer requiredPoints = goods.getRequiredPoints();
|
||||
if (accountPoints < requiredPoints) {
|
||||
throw new CzgException("会员积分不足无法兑换此商品");
|
||||
}
|
||||
return new Object[]{basic, goods, memberPoints};
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointsExchangeRecordDTO create(PointsOrderCreateParam param) {
|
||||
Long shopId = StpKit.USER.getShopId(0L);
|
||||
param.setShopId(shopId);
|
||||
Object[] verify = verify(param);
|
||||
PointsBasicSetting basic = (PointsBasicSetting) verify[0];
|
||||
PointsGoodsSetting goods = (PointsGoodsSetting) verify[1];
|
||||
MemberPoints memberPoints = (MemberPoints) verify[2];
|
||||
PointsExchangeRecord entity = BeanUtil.copyProperties(param, PointsExchangeRecord.class);
|
||||
entity.setExtraPaymentAmount(goods.getExtraPrice());
|
||||
entity.setSpendPoints(goods.getRequiredPoints());
|
||||
Snowflake seqNo = IdUtil.getSnowflake(0, 0);
|
||||
String orderNo = DateUtil.format(new Date(), "yyyyMMddHH") + StrUtil.subSuf(seqNo.nextIdStr(), -12);
|
||||
entity.setOrderNo(orderNo);
|
||||
entity.setStatus(PointsExchangeStatusEnum.UNPAID.value());
|
||||
// 生成订单
|
||||
super.save(entity);
|
||||
return BeanUtil.copyProperties(entity, PointsExchangeRecordDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public PointsExchangeRecordDTO pay(PointsOrderPayParam param) {
|
||||
ValidatorUtil.validateEntity(param, DefaultGroup.class);
|
||||
PointsExchangeRecord entity = super.getById(param.getId());
|
||||
if (entity == null) {
|
||||
throw new CzgException("订单不存在");
|
||||
}
|
||||
try {
|
||||
PointsOrderCreateParam pointsOrderCreateParam = BeanUtil.copyProperties(entity, PointsOrderCreateParam.class);
|
||||
verify(pointsOrderCreateParam);
|
||||
} catch (Exception e) {
|
||||
throw new CzgException(e.getMessage().concat(",请您取消订单"));
|
||||
}
|
||||
if (!PointsExchangeStatusEnum.UNPAID.value().equals(entity.getStatus())) {
|
||||
throw new CzgException("订单状态异常,请刷新后重试");
|
||||
}
|
||||
entity.setPayType(param.getPayType().toUpperCase());
|
||||
if (!PointsOrderPayTypeEnum.getValues().contains(param.getPayType().toUpperCase())) {
|
||||
throw new CzgException("支付方式不合法");
|
||||
}
|
||||
// 设置支付方式
|
||||
entity.setPayMethod(PointsOrderPayTypeEnum.getText(param.getPayType().toUpperCase()));
|
||||
// 纯积分支付并且商品需要额外支付金额,需要抛出异常
|
||||
if (PointsOrderPayTypeEnum.POINTS.getValue().equals(entity.getPayType()) && NumberUtil.isGreater(entity.getExtraPaymentAmount(), BigDecimal.ZERO)) {
|
||||
throw new CzgException("此商品需要额外支付金额");
|
||||
}
|
||||
if (!PointsOrderPayTypeEnum.POINTS.getValue().equals(entity.getPayType()) && NumberUtil.equals(entity.getExtraPaymentAmount(), BigDecimal.ZERO)) {
|
||||
throw new CzgException("此商品不需要额外支付金额");
|
||||
}
|
||||
// 如果不需要额外支付
|
||||
if (NumberUtil.equals(entity.getExtraPaymentAmount(), BigDecimal.ZERO)) {
|
||||
// 设置核销券码
|
||||
entity.setCouponCode(IdUtil.getSnowflakeNextIdStr());
|
||||
entity.setStatus("waiting");
|
||||
entity.setPayTime(LocalDateTime.now());
|
||||
entity.setPayType(param.getPayType().toUpperCase());
|
||||
super.updateById(entity);
|
||||
waitingAfter(entity);
|
||||
return BeanUtil.copyProperties(entity, PointsExchangeRecordDTO.class);
|
||||
}
|
||||
if (StrUtil.isBlank(param.getOpenId())) {
|
||||
throw new CzgException("openId/userId不能为空");
|
||||
}
|
||||
HttpServletRequest request = HttpContextUtil.getHttpServletRequest();
|
||||
String ip = null;
|
||||
if (request != null) {
|
||||
ip = JakartaServletUtil.getClientIP(request);
|
||||
}
|
||||
if (StrUtil.isBlank(ip)) {
|
||||
throw new CzgException("无法获取用户ip地址");
|
||||
}
|
||||
// 需要额外支付
|
||||
ShopInfo shopInfo = shopInfoMapper.selectOneById(entity.getShopId());
|
||||
if (shopInfo == null) {
|
||||
throw new CzgException("店铺信息不存在");
|
||||
}
|
||||
ShopMerchant shopMerchant = shopMerchantMapper.selectOneById(shopInfo.getId());
|
||||
if (shopMerchant == null) {
|
||||
throw new CzgException("支付通道不存在");
|
||||
}
|
||||
if ("alipay".equalsIgnoreCase(entity.getPayType()) && StrUtil.isBlank(shopMerchant.getAlipaySmallAppid())) {
|
||||
throw new CzgException("店铺未配置支付宝小程序appId");
|
||||
}
|
||||
if (1 == 1) {
|
||||
// TODO 对接支付接口
|
||||
throw new CzgException("TODO暂未对接支付接口");
|
||||
}
|
||||
return null;
|
||||
/*// 准备支付参数
|
||||
// 应用ID
|
||||
String appId = thirdApply.getAppId();
|
||||
String appToken = thirdApply.getAppToken();
|
||||
String storeId = thirdApply.getStoreId();
|
||||
|
||||
// 订单标题(商品名称)
|
||||
String subject = entity.getPointsGoodsName();
|
||||
// 商品描述
|
||||
String body = StrUtil.format("兑换商品:{} * {}", entity.getPointsGoodsName(), "1");
|
||||
// 交易金额 单位分 100 表示1元
|
||||
long amount = NumberUtil.mul(entity.getExtraPaymentAmount(), new BigDecimal("100")).longValue();
|
||||
// 支付方式
|
||||
String payType = entity.getPayType().toUpperCase();
|
||||
// 子商户APPID
|
||||
String subAppid = thirdApply.getSmallAppid();
|
||||
if ("alipay".equalsIgnoreCase(entity.getPayType())) {
|
||||
subAppid = thirdApply.getAlipaySmallAppid();
|
||||
}
|
||||
// 用户唯一标识 微信支付时,传入用户的openId;支付宝支付和银联支付时,传入用户的userId
|
||||
String openId = record.getOpenId();
|
||||
// 用户IP
|
||||
String clientIp = record.getIp();
|
||||
// 商户订单号 mchOrderNo
|
||||
String mchOrderNo = IdUtil.getSnowflakeNextIdStr();
|
||||
// 回调地址
|
||||
String notifyUrl = pointsGoodsOrderCallBack;
|
||||
// 支付成功后的跳转页面
|
||||
String returnUrl = null;
|
||||
PublicResp<WxScanPayResp> publicResp;
|
||||
try {
|
||||
publicResp = thirdPayService.scanpay(thirdUrl, appId, subject, body, amount, payType, subAppid, openId, clientIp, mchOrderNo, storeId, notifyUrl, returnUrl, appToken);
|
||||
} catch (Exception e) {
|
||||
log.error("拉起支付失败:", e);
|
||||
throw new MsgException(StrUtil.format("拉起支付失败:{}", e.getMessage()));
|
||||
}
|
||||
if (publicResp == null) {
|
||||
throw new MsgException("拉起支付失败:无响应");
|
||||
}
|
||||
if (!"000000".equals(publicResp.getCode())) {
|
||||
throw new MsgException(publicResp.getMsg());
|
||||
}
|
||||
WxScanPayResp payResp = publicResp.getObjData();
|
||||
if (!"TRADE_AWAIT".equals(payResp.getState())) {
|
||||
throw new MsgException(StrUtil.format("拉起支付失败:{}", payResp.getState()));
|
||||
}
|
||||
entity.setPayOrderId(payResp.getPayOrderId());
|
||||
super.updateById(entity);
|
||||
entity.setPayInfo(payResp.getPayInfo());
|
||||
return entity;*/
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付完成的后续操作
|
||||
*
|
||||
* @param entity 积分兑换实体
|
||||
*/
|
||||
private void waitingAfter(PointsExchangeRecord entity) {
|
||||
PointsGoodsSetting goods = pointsGoodsSettingMapper.selectOneById(entity.getPointsGoodsId());
|
||||
if (goods == null) {
|
||||
throw new CzgException("积分商品不存在");
|
||||
}
|
||||
MemberPoints memberPoints = memberPointsMapper.selectOneById(entity.getUserId());
|
||||
if (memberPoints == null) {
|
||||
throw new CzgException("会员积分不足无法兑换此商品");
|
||||
}
|
||||
Integer quantity = goods.getQuantity();
|
||||
Integer accountPoints = memberPoints.getAccountPoints();
|
||||
Integer requiredPoints = goods.getRequiredPoints();
|
||||
// 扣减积分
|
||||
memberPoints.setAccountPoints(accountPoints - requiredPoints);
|
||||
memberPoints.setLastPointsChangeTime(LocalDateTime.now());
|
||||
memberPoints.setLastFloatPoints(-requiredPoints);
|
||||
memberPointsMapper.update(memberPoints);
|
||||
// 扣减库存
|
||||
goods.setQuantity(quantity - 1);
|
||||
pointsGoodsSettingMapper.update(goods);
|
||||
// 记录积分浮动流水
|
||||
MemberPointsLog log = new MemberPointsLog();
|
||||
log.setShopId(entity.getShopId());
|
||||
log.setUserId(entity.getUserId());
|
||||
log.setContent(StrUtil.format("兑换商品:{} * {}", entity.getPointsGoodsName(), "1"));
|
||||
log.setFloatType("subtract");
|
||||
log.setFloatPoints(-requiredPoints);
|
||||
memberPointsLogMapper.insert(log);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel(PointsExchangeCfParam param) {
|
||||
if (param.getId() == null) {
|
||||
@@ -171,7 +400,7 @@ public class PointsExchangeRecordServiceImpl extends ServiceImpl<PointsExchangeR
|
||||
if (NumberUtil.equals(entity.getExtraPaymentAmount(), BigDecimal.ZERO)) {
|
||||
return;
|
||||
}
|
||||
// 需要额外支付
|
||||
// 需要额外退款
|
||||
ShopInfo shopInfo = shopInfoMapper.selectOneById(entity.getShopId());
|
||||
if (shopInfo == null) {
|
||||
throw new CzgException("店铺信息不存在");
|
||||
|
||||
Reference in New Issue
Block a user