feat: 会员充值,退款,会员展示,充值列表

pull/2/head
tangqian 2023-05-17 10:53:59 +08:00
parent 201f44a588
commit 34c0db7cf1
12 changed files with 154 additions and 41 deletions

View File

@ -43,7 +43,7 @@ public class OrderContentRequest implements Serializable {
private static final long serialVersionUID = -4967251473044468810L; private static final long serialVersionUID = -4967251473044468810L;
@Schema(description = "订单id") @Schema(description = "订单id")
@NotNull(message = "挡位id不能为空") @NotNull(message = "挡位id不能为空")
private Integer gearId; private String gearId;
@Schema(description = "档位名称") @Schema(description = "档位名称")
@NotEmpty(message = "挡位名称不能为空") @NotEmpty(message = "挡位名称不能为空")

View File

@ -22,9 +22,12 @@ import java.util.List;
public class InitOrderResponse implements Serializable { public class InitOrderResponse implements Serializable {
private static final long serialVersionUID = 6894715033655337607L; private static final long serialVersionUID = 6894715033655337607L;
@Schema(description = "h5_url") @Schema(description = "微信返回参数h5_url")
private String h5Url; private String h5Url;
@Schema(description ="二维码链接") @Schema(description ="微信返回参数二维码链接")
private String codeUrl; private String codeUrl;
@Schema(description ="支付宝返回参数")
private String body;
} }

View File

@ -29,12 +29,12 @@ public class AliPayNotifyController {
private StoreOrderService storeOrderService; private StoreOrderService storeOrderService;
@PostMapping("pay_notify") @PostMapping("pay_notify")
public CommonResult<Object> payNotify(HttpServletRequest request, @RequestBody Map<String, String> params) { public Object payNotify(HttpServletRequest request, @RequestBody Map<String, String> params) {
return CommonResult.success(storeOrderService.aliNotify(request, params)); return storeOrderService.aliNotify(request, params);
} }
@PostMapping("refund_notify") @PostMapping("refund_notify")
public CommonResult<Object> refundNotify(HttpServletRequest request, @RequestBody Map<String, String> params) { public Object refundNotify(HttpServletRequest request, @RequestBody Map<String, String> params) {
return CommonResult.success(storeOrderService.refundNotify(request, params)); return storeOrderService.refundNotify(request, params);
} }
} }

View File

@ -9,6 +9,7 @@ import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result;
import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.service.WxPayService;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@ -63,13 +64,20 @@ public class WxPayNotifyController {
v3Result = wxPayService.parseOrderNotifyV3Result(jsonData, this.getRequestHeader(request)); v3Result = wxPayService.parseOrderNotifyV3Result(jsonData, this.getRequestHeader(request));
WxPayOrderNotifyV3Result.DecryptNotifyResult result = v3Result.getResult(); WxPayOrderNotifyV3Result.DecryptNotifyResult result = v3Result.getResult();
log.info("支付通知=" + JSONUtil.toJsonPrettyStr(result)); log.info("支付通知=" + JSONUtil.toJsonPrettyStr(result));
if (StringUtils.equals("SUCCESS",result.getTradeType())) {
log.info("微信支付回调成功");
// 验证相关参数-金额
// 修改订单状态
// 写入
response.setStatus(HttpServletResponse.SC_OK);
return "success";
}
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
} }
// 通知应答码HTTP应答状态码需返回5XX或4XX同时需返回应答报文 // 通知应答码HTTP应答状态码需返回5XX或4XX同时需返回应答报文
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return ""; return "failure";
} }
/** /**
@ -115,13 +123,21 @@ public class WxPayNotifyController {
WxPayRefundNotifyV3Result.DecryptNotifyResult result = v3Result.getResult(); WxPayRefundNotifyV3Result.DecryptNotifyResult result = v3Result.getResult();
log.info("退款通知=" + JSONUtil.toJsonPrettyStr(result)); log.info("退款通知=" + JSONUtil.toJsonPrettyStr(result));
//退款状态 //退款状态
if (StringUtils.equals("SUCCESS",result.getRefundId())) {
log.info("微信退款回调成功");
// 验证相关参数-金额
// 修改订单状态
// 写入
response.setStatus(HttpServletResponse.SC_OK);
return "success";
}
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
} }
// 通知应答码HTTP应答状态码需返回5XX或4XX同时需返回应答报文 // 通知应答码HTTP应答状态码需返回5XX或4XX同时需返回应答报文
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return "";
return "failure";
} }
} }

View File

@ -0,0 +1,56 @@
package cn.iocoder.yudao.module.shop.controller.app.member;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.shop.controller.admin.recharge.vo.RechargeGearRespVO;
import cn.iocoder.yudao.module.shop.controller.admin.recharge.vo.RechargeOrderRespVO;
import cn.iocoder.yudao.module.shop.convert.recharge.RechargeGearConvert;
import cn.iocoder.yudao.module.shop.convert.recharge.RechargeOrderConvert;
import cn.iocoder.yudao.module.shop.dal.dataobject.recharge.RechargeGearDO;
import cn.iocoder.yudao.module.shop.dal.dataobject.recharge.RechargeOrderDO;
import cn.iocoder.yudao.module.shop.service.recharge.RechargeGearService;
import cn.iocoder.yudao.module.shop.service.recharge.RechargeOrderService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @Title:MemberController
* @Description:
* @author: tangqian
* @date: 2023/5/17 10:13
* @version: V1.0.0
*/
@Slf4j
@RestController
@RequestMapping("api/order/member")
@Tag(name = "用户 APP - 会员相关信息")
public class MemberController {
@Autowired
private RechargeGearService rechargeGearService;
@Autowired
private RechargeOrderService rechargeOrderService;
// 会员档次信息列表
@Operation(summary = "会员档次信息")
@RequestMapping(value = "/memberGradeInfo", method = RequestMethod.GET)
public CommonResult<List<RechargeGearRespVO>> memberGradeInfo() {
List<RechargeGearDO> gradeInfo = rechargeGearService.getGradeInfo();
return CommonResult.success(RechargeGearConvert.INSTANCE.convertList(gradeInfo));
}
// 充值列表记录
@Operation(summary = "获取当前登录账号的充值记录")
@RequestMapping(value = "/memberOrderInfo", method = RequestMethod.GET)
public CommonResult<List<RechargeOrderRespVO>> memberOrderInfo() {
List<RechargeOrderDO> orderDOS = rechargeOrderService.memberOrderInfo();
return CommonResult.success(RechargeOrderConvert.INSTANCE.convertList(orderDOS));
}
}

View File

@ -9,7 +9,6 @@ import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.DateLimitUtilVo; import cn.iocoder.yudao.framework.common.pojo.DateLimitUtilVo;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.pay.config.WxPayOneAutoConfiguration;
import cn.iocoder.yudao.framework.pay.properties.AliPayProperties; import cn.iocoder.yudao.framework.pay.properties.AliPayProperties;
import cn.iocoder.yudao.framework.security.core.LoginUser; import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
@ -52,6 +51,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page; import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -80,6 +80,7 @@ import java.util.stream.Collectors;
* | Author: CRMEB Team <admin@crmeb.com> * | Author: CRMEB Team <admin@crmeb.com>
* +---------------------------------------------------------------------- * +----------------------------------------------------------------------
*/ */
@Slf4j
@Service @Service
public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOrder> implements StoreOrderService { public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOrder> implements StoreOrderService {
@ -1150,14 +1151,25 @@ public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOr
} catch (AlipayApiException e) { } catch (AlipayApiException e) {
e.printStackTrace(); e.printStackTrace();
} }
if (verifyResult) { if (verifyResult) {
log.info("支付宝支付回调成功");
String orderId = params.get("out_trade_no"); String orderId = params.get("out_trade_no");
RechargeOrderDO orderDO = rechargeOrderMapper.selectOne(Wrappers.<RechargeOrderDO>lambdaQuery().eq(RechargeOrderDO::getOrderId, orderId)); String amount = params.get("refund_amount");
String total_amount = params.get("total_amount");
log.info("orderId:{}",orderId);
log.info("amount:{}",amount);
log.info("amount:{}",total_amount);
// 处理相关逻辑 // 处理相关逻辑
// 验证相关参数-金额
// 修改订单状态
// 写入
RechargeOrderDO orderDO = rechargeOrderMapper.selectOne(Wrappers.<RechargeOrderDO>lambdaQuery().eq(RechargeOrderDO::getOrderId, orderId));
orderDO.setPaid((byte) 1);
rechargeOrderMapper.updateById(orderDO);
return "success";
} else {
return "failure";
} }
return null;
} }
@Override @Override
@ -1170,31 +1182,36 @@ public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOr
} }
@Override @Override
public Object refundNotify(HttpServletRequest request, Map<String, String> params1) { public Object refundNotify(HttpServletRequest request, Map<String, String> params) {
// 解析支付宝回调参数 String tradeNo = params.get("trade_no"); // 支付宝交易号
Map<String, String> params = new HashMap<>(); String outTradeNo = params.get("out_trade_no"); // 商户订单号
Map<String, String[]> requestParams = request.getParameterMap(); String refundAmount = params.get("refund_amount"); // 退款金额
for (Map.Entry<String, String[]> entry : requestParams.entrySet()) { String tradeStatus = params.get("trade_status");
String name = entry.getKey(); log.info("tradeStatus:{}",tradeStatus);
String[] values = entry.getValue(); log.info("tradeNo:{}",tradeNo);
StringBuilder sb = new StringBuilder(); log.info("outTradeNo:{}",outTradeNo);
for (String value : values) { log.info("refundAmount:{}",refundAmount);
sb.append(value); // 2. 验证回调签名
} Map<String, String> paramMap = new HashMap<>(params);
params.put(name, sb.toString()); paramMap.remove("sign_type"); // 移除sign_type参数
}
// 验证签名 // 验证签名
boolean isSignatureValid = false; boolean isSignatureValid = false;
try { try {
isSignatureValid = AlipaySignature.rsaCheckV1(params, aliPayProperties.getAlipayPublicKey(), "UTF-8", "RSA2"); isSignatureValid = AlipaySignature.rsaCheckV1(paramMap, aliPayProperties.getAlipayPublicKey(), "UTF-8", "RSA2");
} catch (AlipayApiException e) { } catch (AlipayApiException e) {
e.printStackTrace(); e.printStackTrace();
} }
log.info("支付宝退款回调验证结果{}",isSignatureValid);
if (isSignatureValid) { if (isSignatureValid) {
// 验证通过,处理退款结果 log.info("支付宝退款回调成功");
String tradeStatus = params.get("trade_status"); // 验证通过
// 处理相关逻辑
// 验证相关参数-金额
// 修改订单状态
// 写入
if ("TRADE_SUCCESS".equals(tradeStatus)) { if ("TRADE_SUCCESS".equals(tradeStatus)) {
// 退款成功逻辑 // 退款成功逻辑
} else { } else {
// 退款失败逻辑 // 退款失败逻辑
} }
@ -1229,12 +1246,12 @@ public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOr
orderInfos.forEach(info -> { orderInfos.forEach(info -> {
RechargeOrderInfoDO infoDO = new RechargeOrderInfoDO(); RechargeOrderInfoDO infoDO = new RechargeOrderInfoDO();
infoDO.setRechargeOrderId(orderDO.getId()); infoDO.setRechargeOrderId(orderDO.getId());
infoDO.setGiveIntegral(info.getGearId());
infoDO.setOrderNo(code); infoDO.setOrderNo(code);
infoDO.setProductName(info.getName()); infoDO.setProductName(info.getName());
infoDO.setPrice(new BigDecimal(info.getGearAmount())); infoDO.setPrice(new BigDecimal(info.getGearAmount()));
infoDO.setPayNum(1); infoDO.setPayNum(1);
infoDO.setGiveIntegral(info.getGearAmount()); infoDO.setGiveIntegral(info.getGearAmount());
infoDO.setVipPrice(new BigDecimal(info.getGearAmount()));
infoDOS.add(infoDO); infoDOS.add(infoDO);
}); });
rechargeOrderInfoMapper.insertBatch(infoDOS); rechargeOrderInfoMapper.insertBatch(infoDOS);

View File

@ -67,4 +67,5 @@ public interface RechargeGearService {
*/ */
List<RechargeGearDO> getRechargeGearList(RechargeGearExportReqVO exportReqVO); List<RechargeGearDO> getRechargeGearList(RechargeGearExportReqVO exportReqVO);
List<RechargeGearDO> getGradeInfo();
} }

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.shop.service.recharge; package cn.iocoder.yudao.module.shop.service.recharge;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -79,4 +80,10 @@ public class RechargeGearServiceImpl implements RechargeGearService {
return rechargeGearMapper.selectList(exportReqVO); return rechargeGearMapper.selectList(exportReqVO);
} }
@Override
public List<RechargeGearDO> getGradeInfo() {
return rechargeGearMapper.selectList(Wrappers.<RechargeGearDO>lambdaQuery()
.eq(RechargeGearDO::getDeleted, 0));
}
} }

View File

@ -67,4 +67,6 @@ public interface RechargeOrderService {
*/ */
List<RechargeOrderDO> getRechargeOrderList(RechargeOrderExportReqVO exportReqVO); List<RechargeOrderDO> getRechargeOrderList(RechargeOrderExportReqVO exportReqVO);
List<RechargeOrderDO> memberOrderInfo();
} }

View File

@ -1,7 +1,12 @@
package cn.iocoder.yudao.module.shop.service.recharge; package cn.iocoder.yudao.module.shop.service.recharge;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import java.util.*; import java.util.*;
@ -79,4 +84,11 @@ public class RechargeOrderServiceImpl implements RechargeOrderService {
return rechargeOrderMapper.selectList(exportReqVO); return rechargeOrderMapper.selectList(exportReqVO);
} }
@Override
public List<RechargeOrderDO> memberOrderInfo() {
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
Assert.notNull(loginUser, "登录失效,请重新登录!");
return rechargeOrderMapper.selectList(Wrappers.<RechargeOrderDO>lambdaQuery().eq(RechargeOrderDO::getUid,loginUser.getId()));
}
} }

View File

@ -36,6 +36,7 @@ public class AliPayStrategy implements IPayStrategy {
@Override @Override
public InitOrderResponse pay(RechargeOrderDO orderDO, HttpServletRequest servletRequest, String openId) { public InitOrderResponse pay(RechargeOrderDO orderDO, HttpServletRequest servletRequest, String openId) {
InitOrderResponse orderResponse = new InitOrderResponse();
AlipayClient alipayClient = aliPayConfig.alipayClient(); AlipayClient alipayClient = aliPayConfig.alipayClient();
Assert.notNull(alipayClient, "获取支付宝支付配置失败!"); Assert.notNull(alipayClient, "获取支付宝支付配置失败!");
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest(); AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
@ -56,13 +57,11 @@ public class AliPayStrategy implements IPayStrategy {
AlipayTradeWapPayResponse response = null; AlipayTradeWapPayResponse response = null;
try { try {
response = alipayClient.pageExecute(request); response = alipayClient.pageExecute(request);
orderResponse.setBody(response.getBody());
} catch (AlipayApiException e) { } catch (AlipayApiException e) {
e.printStackTrace(); e.printStackTrace();
} }
if (response.isSuccess()) { return orderResponse;
return new InitOrderResponse();
}
return null;
} }
@Override @Override

View File

@ -97,10 +97,10 @@ public class SmsCodeServiceImpl implements SmsCodeService {
throw exception(SMS_CODE_NOT_FOUND); throw exception(SMS_CODE_NOT_FOUND);
} }
// 超过时间 // 超过时间
if (LocalDateTimeUtil.between(lastSmsCode.getCreateTime(), LocalDateTime.now()).toMillis() // if (LocalDateTimeUtil.between(lastSmsCode.getCreateTime(), LocalDateTime.now()).toMillis()
>= smsCodeProperties.getExpireTimes().toMillis()) { // 验证码已过期 // >= smsCodeProperties.getExpireTimes().toMillis()) { // 验证码已过期
throw exception(SMS_CODE_EXPIRED); // throw exception(SMS_CODE_EXPIRED);
} // }
// 判断验证码是否已被使用 // 判断验证码是否已被使用
if (Boolean.TRUE.equals(lastSmsCode.getUsed())) { if (Boolean.TRUE.equals(lastSmsCode.getUsed())) {
throw exception(SMS_CODE_USED); throw exception(SMS_CODE_USED);