소스 검색

下单微信支付

wangwl 4 달 전
부모
커밋
10fb4a44be

+ 5 - 0
leromro-common/pom.xml

@@ -105,6 +105,11 @@
             <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson-spring-boot-starter</artifactId>
+        </dependency>
+
         <!-- pool 对象池 -->
         <dependency>
             <groupId>org.apache.commons</groupId>

+ 26 - 0
leromro-core/src/main/java/com/leromro/core/controller/OrdersController.java

@@ -1,8 +1,13 @@
 package com.leromro.core.controller;
 
 import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
 import com.leromro.common.core.domain.R;
 import com.leromro.common.core.page.TableDataInfo;
 import com.leromro.common.utils.SecurityUtils;
@@ -13,12 +18,14 @@ import com.leromro.core.domain.VolunteerInfo;
 import com.leromro.core.domain.dto.OrderRequestDTO;
 import com.leromro.core.domain.dto.UserOrderReviewDTO;
 import com.leromro.core.domain.vo.*;
+import com.leromro.core.facade.OrdersFacade;
 import com.leromro.core.service.IAddressService;
 import com.leromro.core.service.IMainOrderService;
 import com.leromro.core.service.ISecondOrderService;
 import com.leromro.core.service.IVolunteerInfoService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -33,6 +40,7 @@ import com.leromro.common.enums.BusinessType;
  * @author ruoyi
  * @date 2025-04-09
  */
+@Slf4j
 @RestController
 @Api(tags = "用户订单")
 @RequestMapping("/core/users/orders")
@@ -45,6 +53,8 @@ public class OrdersController extends BaseController {
     private IAddressService addressService;
     @Autowired
     private IVolunteerInfoService volunteerInfoService;
+    @Autowired
+    private OrdersFacade ordersFacade;
 
 
     /**
@@ -153,6 +163,22 @@ public class OrdersController extends BaseController {
 
 
 
+    /**
+     * 支付超时或取消
+     */
+    public AjaxResult PayCancel(MainOrders order) {
+        ordersFacade.PayCancel(order);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 订单支付回调
+     */
+    @PostMapping("/payNotify")
+    public String payNotify(@RequestBody String xmlData) {
+        return ordersFacade.payNotify(xmlData);
+    }
+
 
 
 

+ 4 - 0
leromro-core/src/main/java/com/leromro/core/domain/MainOrders.java

@@ -191,4 +191,8 @@ public class MainOrders extends BaseEntity
     @ApiModelProperty("志愿者信息主键")
     private Long volunteerInfoId;
 
+    @TableField("out_trade_no")
+    @ApiModelProperty("商户订单号")
+    private String outTradeNo;
+
 }

+ 4 - 0
leromro-core/src/main/java/com/leromro/core/domain/SecondOrder.java

@@ -175,5 +175,9 @@ public class SecondOrder extends BaseEntity
     @ApiModelProperty("区级名称")
     private String districtName;
 
+    @TableField("out_trade_no")
+    @ApiModelProperty("商户订单号")
+    private String outTradeNo;
+
 
 }

+ 93 - 0
leromro-core/src/main/java/com/leromro/core/facade/OrdersFacade.java

@@ -0,0 +1,93 @@
+package com.leromro.core.facade;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+import com.github.binarywang.wxpay.service.WxPayService;
+import com.leromro.core.domain.MainOrders;
+import com.leromro.core.service.IMainOrderService;
+import com.leromro.core.service.IOrderRefundService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@Service
+public class OrdersFacade {
+
+    @Autowired
+    private IMainOrderService mainOrderService;
+
+    @Autowired
+    private IOrderRefundService orderRefundService;
+
+    @Autowired
+    @Qualifier("wxMiniPayService")
+    private WxPayService wxMiniPayService;
+
+    @Autowired
+    @Qualifier("wxMiniPayRefundService")
+    private  WxPayService wxMiniPayRefundService;
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+
+    /**
+     * 支付超时或取消
+     */
+    public void PayCancel(MainOrders order) {
+        //查询订单
+        //查询小订单
+        //修改大小订单状态
+        //修改志愿者排班与预约时间表
+        //修改平台流水表
+    }
+
+
+    /**
+     * 订单支付回调
+     */
+    public String payNotify(String xmlData) {
+        RLock fairLock = null;
+        try {
+            log.info("=====================>>>微信支付回调接收<<====================={}", xmlData);
+            //解析微信回调数据
+            WxPayOrderNotifyResult notifyResult = wxMiniPayService.parseOrderNotifyResult(xmlData);
+            log.info("=====================>>>微信支付回调解析<<====================={}", notifyResult);
+            //查询订单相关信息
+            fairLock = redissonClient.getLock("order:notify:"+notifyResult.getOutTradeNo());
+            //获取锁
+            boolean lock = fairLock.tryLock(1000, TimeUnit.MILLISECONDS);
+            if (lock){
+                //再执行订单状态修改
+                MainOrders mainOrders = mainOrderService.getOne(new QueryWrapper<MainOrders>().eq("main_order_id", notifyResult.getOutTradeNo()));
+                if (ObjectUtil.isNull(mainOrders)){
+                    log.error("微信支付回调结果异常1,异常原因:订单号无法找到对应订单{}",notifyResult.getOutTradeNo() );
+                }
+                //判断支付结果
+
+
+                //向志愿者推送消息,并且插入未读消息
+            }
+            //根据商户单号查询订单,然后修改订单状态
+            return WxPayNotifyResponse.success("成功");
+        }catch (Exception e){
+            log.error("微信支付回调结果异常2,异常原因:{}", e.getMessage());
+            return WxPayNotifyResponse.fail("code:9999微信支付回调结果异常,异常原因:" + e.getMessage());
+        }finally {
+            if (ObjectUtil.isNotNull(fairLock) && fairLock.isLocked() && fairLock.isHeldByCurrentThread()) {
+                fairLock.unlock();
+            }
+        }
+    }
+
+
+}

+ 73 - 6
leromro-core/src/main/java/com/leromro/core/service/impl/MainOrderServiceImpl.java

@@ -1,10 +1,20 @@
 package com.leromro.core.service.impl;
 
 import cn.hutool.core.lang.Snowflake;
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
+import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
+import com.github.binarywang.wxpay.service.WxPayService;
 import com.leromro.common.core.domain.R;
+import com.leromro.common.core.domain.entity.SysUser;
+import com.leromro.common.exception.ServiceException;
 import com.leromro.common.utils.SecurityUtils;
+import com.leromro.common.utils.ip.IpUtils;
 import com.leromro.core.domain.*;
 import com.leromro.core.domain.dto.OrderRequestDTO;
 import com.leromro.core.domain.vo.MainOrdersVO;
@@ -13,9 +23,15 @@ import com.leromro.core.domain.vo.WebMainOrdersInfoVO;
 import com.leromro.core.domain.vo.webMainOrderListVO;
 import com.leromro.core.mapper.*;
 import com.leromro.core.service.IMainOrderService;
+import com.leromro.core.utils.BigDecimalUtil;
 import com.leromro.core.utils.DateTimeUtil;
+import com.leromro.core.utils.NoUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -26,8 +42,10 @@ import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
+@Slf4j
 @Service
 public class MainOrderServiceImpl extends ServiceImpl<MainOrdersMapper, MainOrders> implements IMainOrderService{
     @Autowired
@@ -51,6 +69,17 @@ public class MainOrderServiceImpl extends ServiceImpl<MainOrdersMapper, MainOrde
     @Autowired
     private ClientAccountChangeMapper clientAccountChangeMapper;
 
+    @Autowired
+    @Qualifier("wxMiniPayService")
+    private WxPayService wxMiniPayService;
+
+    @Autowired
+    @Qualifier("wxMiniPayRefundService")
+    private  WxPayService wxMiniPayRefundService;
+
+    @Autowired
+    private RedissonClient redissonClient;
+
     /**
      * @param userId
      * @return
@@ -81,20 +110,27 @@ public class MainOrderServiceImpl extends ServiceImpl<MainOrdersMapper, MainOrde
                 .sorted(Comparator.comparing(VolunteerWorkDate::getWorkDate))
                 .collect(Collectors.toList());
         Long userId = SecurityUtils.getUserId();
+        //主键id
         long orderId = snowflake.nextId();
         vo.setMainOrderId(orderId);
+        //订单号
+        String orderNo = NoUtil.getOrderNo();
+        orders.setOutTradeNo(orderNo);
 
 
         //获取志愿者信息,同时服务时长和价格也都在志愿者id中进行获取
         VolunteerInfo info = volunteerInfoMapper.selectOne(new LambdaQueryWrapper<VolunteerInfo>()
                 .eq(VolunteerInfo::getVolunteerInfoId, orders.getVolunteerInfoId()));
+        /** 商品数量单价金额信息*/
         BigDecimal serviceOnePrice = info.getBusinessPrice();
         Integer businessDurationMin = info.getBusinessDuration();
-        String seconderStatus;
+        Long totalTimes = orders.getTotalTimes();
+        BigDecimal totalPrice = serviceOnePrice.multiply(BigDecimal.valueOf(totalTimes));
+        orders.setServiceTotalPrice(totalPrice);
         // 判断支付方式,余额扣减余额。 1 余额 2 微信
+        String seconderStatus;
         if (orders.getPaymentMethod().equals("1")){
             // 查看余额够不够  修改用户余额表
-            BigDecimal totalPrice = orders.getServiceTotalPrice();
             ClientAccount clientAccount = clientAccountMapper.selectBalanceByuserID(userId);
             BigDecimal balanceOld = clientAccount.getBalance();
             BigDecimal newBalance = balanceOld.subtract(totalPrice);
@@ -113,13 +149,36 @@ public class MainOrderServiceImpl extends ServiceImpl<MainOrdersMapper, MainOrde
             clientAccountChange.setCreateTime(DateTimeUtil.getNowTime1());
             clientAccountChangeMapper.insert(clientAccountChange);
         }else if (orders.getPaymentMethod().equals("2")){
-            //待完成 微信支付
-            System.out.println("微信支付");
+           /**微信支付 */
+            //组装微信预下单参数
+            try {
+                WxPayUnifiedOrderRequest orderReq = new WxPayUnifiedOrderRequest();
+                orderReq.setOutTradeNo(orderNo);
+                //单位分
+                orderReq.setTotalFee(BigDecimalUtil.yuanToFee(totalPrice));
+                SysUser user = SecurityUtils.getLoginUser().getUser();
+                orderReq.setOpenid(user.getUserOpenId());
+                orderReq.setBody("微信支付");
+                orderReq.setSpbillCreateIp(user.getLoginIp());
+                log.info("【微信支付】预下单开始,参数={}", orderReq);
+                WxPayMpOrderResult result = wxMiniPayService.createOrder(orderReq);
+                if (result == null) {
+                    throw new ServiceException();
+                }
+                vo.setTimeStamp(result.getTimeStamp());
+                vo.setNonceStr(result.getNonceStr());
+                vo.setPackageValue(result.getPackageValue());
+                vo.setSignType(result.getSignType());
+                vo.setPaySign(result.getPaySign());
+                log.info("【微信支付】预下单成功,结果={}", result);
+            }catch (Exception e){
+                log.error("【微信支付】支付失败 原因={}", e.getMessage());
+                return R.fail("服务器繁忙,暂时无法下单,请稍后再试");
+            }
 
             //设置订单支付状态
             orders.setOrderStatus("0");
-             seconderStatus = "0";
-
+            seconderStatus = "0";
         }else {
             throw new RuntimeException("支付方式错误");
         }
@@ -195,6 +254,7 @@ public class MainOrderServiceImpl extends ServiceImpl<MainOrdersMapper, MainOrde
             secondOrder1.setWorkEndTime(workDate.getWorkStartTime().plus(Duration.ofMinutes(orders.getServiceDuration())));
             secondOrder1.setWorkNumber(number);
             secondOrder1.setSecondOrderId(secondOrderIdL);
+            secondOrder1.setOutTradeNo(orderNo);
             secondOrderList.add(secondOrder1);
             //向平台流水中添加数据
             PlatformFinance platformFinance1 = new PlatformFinance();
@@ -262,4 +322,11 @@ public class MainOrderServiceImpl extends ServiceImpl<MainOrdersMapper, MainOrde
     }
 
 
+
+
+
+
+
+
+
 }

+ 17 - 0
leromro-core/src/main/java/com/leromro/core/utils/BigDecimalUtil.java

@@ -0,0 +1,17 @@
+package com.leromro.core.utils;
+
+import java.math.BigDecimal;
+
+public class BigDecimalUtil {
+
+    /**
+     * 1 块钱转为 100 分
+     * 元转分
+     *
+     * @param bigDecimal 钱数目
+     * @return 分
+     */
+    public static int yuanToFee(BigDecimal bigDecimal) {
+        return bigDecimal.multiply(new BigDecimal(100)).intValue();
+    }
+}

+ 207 - 0
leromro-core/src/main/java/com/leromro/core/utils/NoUtil.java

@@ -0,0 +1,207 @@
+package com.leromro.core.utils;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.google.common.hash.HashFunction;
+import com.google.common.hash.Hashing;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.time.Duration;
+import java.util.Date;
+import java.util.Random;
+
+import com.leromro.common.exception.ServiceException;
+import org.springframework.data.redis.core.RedisTemplate;
+
+public class NoUtil {
+    private static final String ORDER_CODE = "OD";
+    private static final String PAY_CODE = "PAY";
+    private static final String COUPON_ORDER_CODE = "POD";
+    private static final String PER_ORDER_CODE = "PR";
+    private static final String RETURN_ORDER = "RT";
+    private static final String REFUND_ORDER = "RF";
+    private static final String ACTIVITY = "AT";
+    private static final String PRODUCT = "SN";
+    private static final String PARCAL = "BP";
+    private static final String PROFIT_SHARE = "PS";
+    private static final String TAKE_MONEY = "TX";
+    private static final String ORG = "OR";
+    private static final String STO = "sto";
+    private static final String BILL = "FP";
+    private static final String TEMPLATE_NO = "TNO";
+    private static final String PACK_NO = "PNO";
+    private static final String CON_NO = "DTO";
+    private static final String CHECK_NO = "SP";
+    private static final String ACOUNT_NO = "WA";
+    private static final String CA_NO = "CA";
+    private static final String BX_ORDER = "BX";
+    private static final String REVENUE_NO = "LX";
+    private static final String RENT_CAR_TYPE_NO = "ZC";
+    private static final int maxLength = 12;
+    private static final int[] r = {7, 9, 6, 2, 8, 1, 3, 0, 5, 4};
+    private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    private static final int ALPHABET_LENGTH = ALPHABET.length();
+    private static int counter = 0;
+
+    private static String toCode(Integer userId) {
+        String idStr = userId.toString();
+        StringBuilder idsbs = new StringBuilder();
+        for (int i = idStr.length() - 1; i >= 0; i--) {
+            idsbs.append(r[idStr.charAt(i) - '0']);
+        }
+        return idsbs.append(getRandom(12 - idStr.length())).toString();
+    }
+
+    private static String toAutoCode(Integer length) {
+        return getRandom(length.intValue()) + "";
+    }
+
+    private static String getDateTime() {
+        DateFormat sdf = new SimpleDateFormat("yyMMddHHmmssSSS");
+        return sdf.format(new Date());
+    }
+
+    private static long getRandom(long n) {
+        long min = 1;
+        long max = 9;
+        for (int i = 1; i < n; i++) {
+            min *= 10;
+            max *= 10;
+        }
+        long rangeLong = ((long) (new Random().nextDouble() * (max - min))) + min;
+        return rangeLong;
+    }
+
+    private static synchronized String getCode(Integer userId) {
+        return getDateTime() + toCode(Integer.valueOf(userId == null ? 10000 : userId.intValue()));
+    }
+
+    private static synchronized String getAutoCode(Integer length) {
+        return getDateTime() + toAutoCode(length);
+    }
+
+    private static synchronized String getNo(String code) {
+        Date date = new Date();
+        RedisTemplate<String, Object> redisTemplate = (RedisTemplate) SpringUtil.getBean("redisTemplate");
+        Long yyyyMMddHHmmss = Long.valueOf(Long.valueOf(DateUtil.format(date, "yyyyMMddHHmmss")).longValue() * 2);
+        String redisKey = "no:" + code + ":" + yyyyMMddHHmmss;
+        Long increment = redisTemplate.opsForValue().increment(redisKey);
+        if (increment.longValue() == 1) {
+            redisTemplate.expire(redisKey, Duration.ofSeconds(1L));
+        }
+        String s = increment.toString();
+        if (s.length() > 6) {
+            throw new ServiceException("服务器繁忙,请稍后再试");
+        }
+        StringBuilder suffix = new StringBuilder();
+        for (int i = s.length(); i < 6; i++) {
+            suffix.append("0");
+        }
+        return code + yyyyMMddHHmmss + suffix.toString() + s;
+    }
+
+    public static String getOrderNo() {
+        return ORDER_CODE + getAutoCode(2);
+    }
+
+    public static String getPayNo() {
+        return getNo(PAY_CODE);
+    }
+
+    public static String getPayRefundNo() {
+        return getNo(REFUND_ORDER);
+    }
+
+    public static String getCouponOrderNo() {
+        return COUPON_ORDER_CODE + getAutoCode(2);
+    }
+
+    public static String getOrgNo() {
+        return ORG + getAutoCode(2);
+    }
+
+    public static String getStoreNo() {
+        return STO + getAutoCode(2);
+    }
+
+    public static String getCheckNo() {
+        return ORG + getAutoCode(2);
+    }
+
+    public static String getBillSn() {
+        return BILL + getAutoCode(2);
+    }
+
+    public static String getPerOrderNo() {
+        return PER_ORDER_CODE + getAutoCode(2);
+    }
+
+    public static String getActNo(Integer userId) {
+        return ACTIVITY + getAutoCode(2);
+    }
+
+    public static String getProductNo(Integer userId) {
+        return PRODUCT + getAutoCode(2);
+    }
+
+    public static String getParcalNo(Integer userId) {
+        return PARCAL + getAutoCode(2);
+    }
+
+    public static String getProfitShareNo(Integer userId) {
+        return PROFIT_SHARE + getAutoCode(2);
+    }
+
+    public static String getTakeMoneyNo() {
+        return TAKE_MONEY + getAutoCode(2);
+    }
+
+    public static String getTemplateNo() {
+        return TEMPLATE_NO + getAutoCode(2);
+    }
+
+    public static String getCouponPackNo() {
+        return PACK_NO + getAutoCode(2);
+    }
+
+    public static String getContractActivityNo() {
+        return "CA" + getAutoCode(2);
+    }
+
+    public static String getContractNo() {
+        return CON_NO + getAutoCode(2);
+    }
+
+    public static String getAccountNo() {
+        return ACOUNT_NO + getAutoCode(2);
+    }
+
+    public static String getRefundNo() {
+        return REFUND_ORDER + getAutoCode(2);
+    }
+
+    public static String getBxNo() {
+        return BX_ORDER + getAutoCode(2);
+    }
+
+    public static String getRentCarTypeNo() {
+        return RENT_CAR_TYPE_NO + getAutoCode(2);
+    }
+
+    public static String getRevenueNO() {
+        return REVENUE_NO + getAutoCode(2);
+    }
+
+    public static String generateUniqueCode() {
+        int index1 = (int) (Math.random() * ALPHABET_LENGTH);
+        int index2 = (int) (Math.random() * ALPHABET_LENGTH);
+        String letters = "" + ALPHABET.charAt(index1) + ALPHABET.charAt(index2);
+        HashFunction murmur3_32 = Hashing.murmur3_32();
+        StringBuilder append = new StringBuilder().append(letters);
+        int i = counter;
+        counter = i + 1;
+        String hash = murmur3_32.hashString(append.append(i).toString(), StandardCharsets.UTF_8).toString();
+        return letters + hash.substring(0, 4);
+    }
+}

+ 32 - 0
leromro-framework/src/main/java/com/leromro/framework/config/RedisConfig.java

@@ -4,11 +4,18 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect;
 import com.fasterxml.jackson.annotation.PropertyAccessor;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import org.redisson.Redisson;
+import org.redisson.api.RedissonClient;
+import org.redisson.config.Config;
+import org.redisson.spring.data.connection.RedissonConnectionFactory;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cache.annotation.CachingConfigurerSupport;
 import org.springframework.cache.annotation.EnableCaching;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
+import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.data.redis.core.script.DefaultRedisScript;
@@ -24,6 +31,24 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
 @EnableCaching
 public class RedisConfig extends CachingConfigurerSupport
 {
+    @Value("${spring.redis.host}")
+    private String redisHost;
+    @Value("${spring.redis.password}")
+    private String redisPassword;
+    @Value("${spring.redis.port}")
+    private String port;
+
+
+    @Bean
+    public RedisConnectionFactory redisConnectionFactory() {
+        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
+        configuration.setHostName(redisHost);
+        configuration.setPort(Integer.parseInt(port));
+        configuration.setPassword(redisPassword);
+
+        return new LettuceConnectionFactory(configuration);
+    }
+
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })
     public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory)
@@ -51,6 +76,13 @@ public class RedisConfig extends CachingConfigurerSupport
         return new StringRedisTemplate(factory);
     }
 
+    @Bean
+    public RedissonClient redissonClient() {
+        Config config = new Config();
+        config.useSingleServer().setAddress("redis://" + redisHost + ":" + port).setPassword(redisPassword);
+        return Redisson.create(config);
+    }
+
     @Bean
     public DefaultRedisScript<Long> limitScript()
     {

+ 2 - 1
leromro-system/src/main/resources/mapper/system/SysUserMapper.xml

@@ -31,6 +31,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="cityName"       column="city_name"       />
         <result property="districtCode"       column="district_code"       />
         <result property="districtName"       column="district_name"       />
+        <result property="userOpenId"       column="user_open_id"       />
         <association property="dept"    javaType="SysDept"         resultMap="deptResult" />
         <collection  property="roles"   javaType="java.util.List"  resultMap="RoleResult" />
     </resultMap>
@@ -55,7 +56,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 	
 	<sql id="selectUserVo">
-        select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.user_or_worker as user_or_worker,u.user_platform as user_platform,
+        select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.user_or_worker as user_or_worker,u.user_platform as user_platform,u.user_open_id as user_open_id,
                u.province_code as province_code, u.province_name as province_name, u.city_code as city_code, u.city_name as city_name, u.district_code as district_code, u.district_name as district_name,
         d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status,
         r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status

+ 6 - 0
pom.xml

@@ -299,6 +299,12 @@
                 <version>4.7.0</version>
             </dependency>
 
+            <dependency>
+                <groupId>org.redisson</groupId>
+                <artifactId>redisson-spring-boot-starter</artifactId>
+                <version>3.16.3</version>
+            </dependency>
+
 
 
         </dependencies>