赞
踩
本文将介绍如何利用Spring Boot与Redis结合实现消息队列的在实际业务中实践。
具体场景描述步骤如下:
用户在自助棋牌室小程序上充值支付后
调用后台服务端接口首先添加用户充值订单为待支付状态
调用微信支付接口,支付成功后,微信回调方法设置(充值订单为已支付、添加用户余额、同时发送消息队列通知升级会员、开卡赠礼)
先视频看下效果吧,有个感观了解
无人自助棋牌室系统实现充值升级会员及开卡赠礼
后台设置会员等级效果
后台设置升级会员开卡效果
程序开发实现步骤如下:
1、用户在小程序充值,小程序使用uniapp开发
- // 充值提交
- confirmRechargeMoney(){
- let that = this
- if(this.topUpList.length<=0){
- uni.showToast({
- title: '商家未设置充值信息',
- icon: 'none',
- duration: 2000,
- })
- }else{
-
- let doRechargeParam = {
- storeId:this.storeId,
- userId:this.userInfo.uid,
- rechargeAmount:this.rechargeAmount
- }
- doRecharge(doRechargeParam).then(res => {
- var payment = res.data.payment;
- weappPay(payment)
- .then(() => {
- this.$yrouter.back();
- })
- })
- }
- },

2、调用后台服务端接口
- export function doRecharge(data) {
- return request.post("/balance/doRecharge", data, {
- login: true
- });
- }
3、后台服务端添加用户充值订单为待支付状态
- /**
- * 充值余额
- */
- @AppLog(value = "充值余额", type = 1)
- //@AuthCheck
- @PostMapping("/balance/doRecharge")
- @ApiOperation(value = "充值余额", notes = "充值余额")
- public ApiResult<Map<String, Object>> doRecharge(HttpServletRequest request, @RequestBody TBalanceParam param) {
- //Integer storeId = request.getHeader("storeId") == null ? 0 : Integer.parseInt(request.getHeader("storeId"));
- // Integer userId = Integer.parseInt(param.get("userId").toString());
- Integer storeId = param.getStoreId();
- Integer userId = param.getUserId();
- Map<String, Object> data = new HashMap();
- // String rechargeAmount = param.get("rechargeAmount") == null ? "" : param.get("rechargeAmount").toString();
- //String customAmount = param.get("customAmount") == null ? "" : param.get("customAmount").toString();
- String rechargeAmount = param.getRechargeAmount();
- String customAmount = param.getCustomAmount();
- if (StringUtil.isEmpty(rechargeAmount) && StringUtil.isEmpty(customAmount)) {
- //return getFailureResult(2000, "请确认充值金额");
- //throw new YshopException("请确认充值金额");
- return ApiResult.fail(ErrorEnum.E_100028.getErrorMsg(), data);
- }
- // 充值赠送金额
- String ruleParam = "";
- MtSetting mtSetting = mtSettingService.querySettingByName(BalanceSettingEnum.RECHARGE_RULE.getKey(), storeId);
- if (StringUtil.isNotEmpty(rechargeAmount) && mtSetting != null) {
- if (mtSetting.getValue() != null && StringUtil.isNotEmpty(mtSetting.getValue())) {
- String rules[] = mtSetting.getValue().split(",");
- for (String rule : rules) {
- String amountArr[] = rule.split("_");
- if (amountArr.length == 2) {
- if (amountArr[0].equals(rechargeAmount)) {
- ruleParam = rule;
- break;
- }
- }
- }
- }
- }
-
- // 自定义充值没有赠送金额
- if (StringUtil.isEmpty(rechargeAmount)) {
- rechargeAmount = customAmount;
- ruleParam = customAmount + "_0";
- }
-
- if (StringUtil.isEmpty(ruleParam)) {
- ruleParam = rechargeAmount + "_0";
- }
- MtStore mtStore = storeService.queryStoreById(storeId);
- BigDecimal amount = new BigDecimal(rechargeAmount);
- OrderDto orderDto = new OrderDto();
- orderDto.setType(OrderTypeEnum.RECHARGE.getKey());
- orderDto.setUserId(userId);
- orderDto.setStoreId(storeId);
- orderDto.setAmount(amount);
- orderDto.setUsePoint(0);
- if(mtStore!=null){
- orderDto.setRemark(mtStore.getName()+"会员充值");
- }else{
- orderDto.setRemark("平台通用会员充值");
- }
- orderDto.setParam(ruleParam);
- orderDto.setStatus(OrderStatusEnumV.CREATED.getKey());
- orderDto.setPayStatus(PayStatusEnum.WAIT.getKey());
- orderDto.setPointAmount(new BigDecimal("0"));
- orderDto.setOrderMode("");
- orderDto.setCouponId(0);
- MtOrder orderInfo = mtOrderService.saveOrder(orderDto);
- YxUser user = userService.getById(userId);
- String ip = CommonUtilV.getIPFromHttpRequest(request);
- BigDecimal pay = amount.multiply(new BigDecimal("100"));
- orderInfo.setPayType(PayTypeEnumV.JSAPI.getKey());
- ResponseObject paymentInfo = weixinService.createPrepayOrder(user, orderInfo, (pay.intValue()), "", 0, ip, PlatformTypeEnum.MP_WEIXIN.getCode());
- //ResponseObject paymentInfo = weixinService.createPrepayOrder(user, orderInfo, pay, "", 0, ip,PlatformTypeEnum.MP_WEIXIN.getCode());
- if (paymentInfo.getData() == null) {
- //return getFailureResult(201, "抱歉,发起支付失败");
- return ApiResult.fail(ErrorEnum.E_100029.getErrorMsg(), data);
- }
- Object payment = paymentInfo.getData();
- data.put("payment", payment);
- data.put("orderInfo", orderInfo);
- return ApiResult.ok(data);
- }

注:weixinService.createPrepayOrder为微信支付方式
4、微信回调方法-充值订单为已支付、添加用户余额
- /**
- * 支付回调
- */
- @RequestMapping(value = "/pay/weixinCallback", method = RequestMethod.POST)
- @CrossOrigin
- public void weixinCallback(HttpServletRequest request, HttpServletResponse response) throws Exception {
- log.info("微信支付结果回调....");
- Map<String, String> inParams = weixinService.processResXml(request);
- log.info("微信返回Map:" + inParams);
- if (!CollectionUtils.isEmpty(inParams)) {
- String orderSn = inParams.get("out_trade_no");// 商户订单号
- String orderId = inParams.get("transaction_id");// 微信订单号
- String tranAmt = inParams.get("total_fee");// 交易金额
- BigDecimal tranAmount = new BigDecimal(tranAmt).divide(new BigDecimal("100"), BigDecimal.ROUND_CEILING);
- // 参数校验
- if (StringUtil.isNotEmpty(orderSn) && StringUtil.isNotEmpty(tranAmt) && StringUtil.isNotEmpty(orderId)) {
- UserOrderDto orderInfo = mtOrderService.getOrderByOrderSn(orderSn);
- if (orderInfo != null) {
- //MtStore storeInfo = orderInfo.getStoreInfo();
- String callbackUrl = this.getApiUrl() + "/api/pay/weixinCallback";
- WXPayConfigImpl wxPayConfig = WXPayConfigImpl.getInstance(callbackUrl, orderInfo.getStoreId(), redisUtils, storeService);
- //WXPayConfigImpl wxPayConfig = WXPayConfigImpl.getInstance(env, storeInfo == null ? 0 : storeInfo.getId(), storeService);
- boolean valid = WXPayUtil.isSignatureValid(inParams, wxPayConfig.getKey());
- /* if (!valid) {
- log.error("微信支付回调接口验签失败");
- return;
- }*/
- // 订单金额
- BigDecimal payAmount = orderInfo.getPayAmount();
- int compareFlag = tranAmount.compareTo(payAmount);
- if (true) { // compareFlag == 0,测试暂时去掉
- if (orderInfo.getStatus().equals(OrderStatusEnumV.CREATED.getKey())) {
- boolean flag = weixinService.paymentCallback(orderInfo);
- log.info("回调结果:" + flag);
- if (flag) {
- weixinService.processRespXml(response, true);
- } else {
- weixinService.processRespXml(response, false);
- }
- } else {
- log.error("订单{}已经支付,orderInfo.getStatus() = {}, CREATED.getKey() = {}", orderSn, orderInfo.getStatus(), OrderStatusEnumV.CREATED.getKey());
- }
- } else {
- log.error("回调金额与支付金额不匹配 tranAmount = {}, payAmount = {}, compareFlag = {}", tranAmount, orderInfo.getPayAmount(), compareFlag);
- }
- } else {
- log.error("支付订单{}对应的信息不存在", orderSn);
- }
- }
- }
- }

5、微信回调方法-同时发送消息队列通知升级会员、开卡赠礼
以下是关键代码步骤片段
- // redis发送消息队列,充值升级会员等级,享受预约下单折扣,并有开卡赠礼(赠券)
- PublishMessage publishMessage = new PublishMessage();
- publishMessage.setMsgType(2);
- publishMessage.setStoreId(orderInfo.getStoreId());
- publishMessage.setUserId(orderInfo.getUserId());
- redisSqueueService.doSomethingAndPublishMessage(publishMessage);
doSomethingAndPublishMessage()方法时,消息将被发布到Redis的消息队列中,并由订阅者接收和处理
- @Service
- public class RedisSqueueService {
-
- private final MessagePublisher messagePublisher;
-
- public RedisSqueueService(MessagePublisher messagePublisher) {
- this.messagePublisher = messagePublisher;
- }
-
- public void doSomethingAndPublishMessage(PublishMessage publishMessage) {
-
- // 执行一些操作
- // String message = uid.toString();
- messagePublisher.publishMessage(publishMessage);
-
- }
-
- }

消息订阅者接收消息,进行升级会员、开卡赠礼
- @Override
- public void onMessage(Message message, byte[] pattern) {
-
- // 获取消息
- byte[] messageBody = message.getBody();
- // 使用值序列化器转换
- Object msg = redisTemplate.getValueSerializer().deserialize(messageBody);
- PublishMessage publishMessage = (PublishMessage)msg;
- // 添加新注册用户赠送卡券
- if(publishMessage.getMsgType()==1){
-
- Integer userId = publishMessage.getUserId();
- MtCoupon coupon = new MtCoupon();
- // 是否新注册赠送,A:是;D:否
- coupon.setIsNewGive("A");
- List<MtCoupon> list = couponService.queryCouponListByCondi(coupon);
- if(list!=null && list.size()>0){
- for(MtCoupon mtCoupon:list){
- if(mtCoupon.getStoreIds()!=null||!"".equals(mtCoupon.getStoreIds())){
- String[] storeIds = mtCoupon.getStoreIds().split(",");
- for(String storeId : storeIds){
- couponService.sendCoupon(mtCoupon.getId(), 1 , userId, Integer.parseInt(storeId));
- }
- }
- }
- }
- // 充值升级会员等级,享受预约下单折扣,并有开卡赠礼(赠券)
- }else if (publishMessage.getMsgType()==2){
-
- LambdaQueryWrapper<MtUserGrade> lambdaQueryWrapper = Wrappers.lambdaQuery();
- lambdaQueryWrapper.eq(MtUserGrade::getStatus, StatusEnum.ENABLED.getKey());
- lambdaQueryWrapper.orderByDesc(MtUserGrade::getId);
- List<MtUserGrade> dataList = mtUserGradeMapper.selectList(lambdaQueryWrapper);
- log.info("dataList.size():"+dataList.size());
- if(dataList!=null){
- for (MtUserGrade item : dataList) {
- // 升级方式是充值获取的
- if(item.getCatchType().equals(UserGradeCatchTypeEnum.RECHARGE.getKey())){
- log.info(" openGiftService.openGift");
- openGiftService.openGift(
- publishMessage.getUserId(),
- item.getId(),
- false,
- publishMessage.getStoreId());
- }
- }
- }
- }
- }

具体Redis消息队列基础实现说明,在无人自助系统使用Redis消息队列实现新用户注册送券
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。