Selaa lähdekoodia

增加微信登陆及绑定

mingfu 1 kuukausi sitten
vanhempi
commit
a3f8b6e218

+ 7 - 1
ie-admin/src/main/java/com/ruoyi/web/controller/front/FrontECardController.java

@@ -205,12 +205,15 @@ public class FrontECardController extends BaseController {
     @PostMapping(value = "createOrder")
     public AjaxResult createOrder(HttpServletRequest request, Double totalFee, @RequestParam(required = false) String type) throws WxPayException {
         if (null==totalFee){
-            AjaxResult.error("金额不能为空");
+            return AjaxResult.error("金额不能为空");
         }
         if(StringUtils.isBlank(type)) {
             type = "h5";
         }
         SysUser u = SecurityUtils.getLoginUser().getUser();
+        if("jsapi".equals(type) && StringUtils.isBlank(u.getOpenId())) {
+            return AjaxResult.error("微信用户未绑定");
+        }
         Integer totalFee2 = totalFee.intValue();
 
         BBusiPaymentOrders insertOrder = new BBusiPaymentOrders();
@@ -265,6 +268,9 @@ public class FrontECardController extends BaseController {
             upOrder.setDetail(h5Url);
             data.put("h5url", h5Url);
         } else {
+            WxPayUnifiedOrderV3Request.Payer payer = new WxPayUnifiedOrderV3Request.Payer();
+            payer.setOpenid(u.getOpenId());
+            order.setPayer(payer);
             WxPayUnifiedOrderV3Result.JsapiResult jsapiResult = wxService.createOrderV3(TradeTypeEnum.JSAPI, order);
             String detail = JSONObject.toJSONString(jsapiResult);
             String prepayId = StringUtils.substringAfterLast(jsapiResult.getPackageValue(), "prepay_id=");

+ 46 - 1
ie-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java

@@ -4,6 +4,10 @@ import java.util.Date;
 import java.util.List;
 import java.util.Set;
 
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
+import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
+import com.alibaba.fastjson2.JSONObject;
 import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.enums.AccessFromType;
 import com.ruoyi.common.enums.BusinessType;
@@ -15,6 +19,7 @@ import com.ruoyi.system.service.ISysUserService;
 import com.ruoyi.web.service.CommService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import me.chanjar.weixin.common.error.WxErrorException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -63,10 +68,13 @@ public class SysLoginController
 
     private final ISysConfigService configService;
 
-    public SysLoginController(ISysUserService userService, IDzCardsService cardsService, ISysConfigService configService) {
+    private final WxMaService wxMaService;
+
+    public SysLoginController(ISysUserService userService, IDzCardsService cardsService, ISysConfigService configService, WxMaService wxMaService) {
         this.userService = userService;
         this.cardsService = cardsService;
         this.configService = configService;
+        this.wxMaService = wxMaService;
     }
 
     /**
@@ -84,6 +92,43 @@ public class SysLoginController
         return ajax;
     }
 
+    /**
+     * 微信登录方法
+     *
+     * @param body 登录信息
+     * @return 结果
+     */
+    @PostMapping("loginByCode")
+    @ApiOperation("微信登陆")
+    public AjaxResult loginByCode(@RequestBody JSONObject body)
+    {
+        String loginCode = body.getString("loginCode");
+        try {
+            WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(loginCode);
+            String openId = sessionInfo.getOpenid();
+            return loginService.loginByCode(openId);
+        } catch (WxErrorException e) {
+            return AjaxResult.error("登陆失败: " + e.getMessage());
+        }
+    }
+
+    @PostMapping("bindOpenId")
+    @ApiOperation("绑定微信")
+    public AjaxResult bindOpenId(@RequestBody JSONObject body)
+    {
+        String loginCode = body.getString("loginCode");
+        String phoneCode = body.getString("phoneCode");
+        try {
+            WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(loginCode);
+            WxMaPhoneNumberInfo phoneNumberInfo = wxMaService.getUserService().getPhoneNumber(phoneCode);
+            String openid = sessionInfo.getOpenid();
+            String phoneNumber = phoneNumberInfo.getPhoneNumber();
+            return loginService.bindOpenId(openid, phoneNumber);
+        } catch (WxErrorException e) {
+            return AjaxResult.error("绑定失败: " + e.getMessage());
+        }
+    }
+
     /**
      * 获取用户信息
      *

+ 14 - 0
ie-admin/src/main/java/com/ruoyi/web/core/config/WxPayConfiguration.java

@@ -1,5 +1,8 @@
 package com.ruoyi.web.core.config;
 
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
+import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
 import com.github.binarywang.wxpay.config.WxPayConfig;
 import com.github.binarywang.wxpay.service.WxPayService;
 import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
@@ -21,6 +24,17 @@ import org.springframework.context.annotation.Configuration;
 public class WxPayConfiguration {
     private WxPayProperties properties;
 
+    @Bean
+    @ConditionalOnMissingBean
+    public WxMaService wxMaService() {
+        WxMaDefaultConfigImpl wxMaConfig = new WxMaDefaultConfigImpl();
+        wxMaConfig.setAppid(properties.getAppId());
+        wxMaConfig.setSecret(properties.getAppSecret());
+        WxMaService service = new WxMaServiceImpl();
+        service.setWxMaConfig(wxMaConfig);
+        return service;
+    }
+
     @Bean
     @ConditionalOnMissingBean
     public WxPayService wxService() {

+ 2 - 0
ie-admin/src/main/java/com/ruoyi/web/core/config/WxPayProperties.java

@@ -11,6 +11,8 @@ public class WxPayProperties {
      */
     private String appId;
 
+    private String appSecret;
+
     /**
      * 微信支付商户号
      */

+ 34 - 11
ie-admin/src/main/java/com/ruoyi/web/service/SysLoginService.java

@@ -2,6 +2,7 @@ package com.ruoyi.web.service;
 
 import javax.annotation.Resource;
 
+import com.alibaba.fastjson2.JSONObject;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.ruoyi.common.core.domain.AjaxResult;
@@ -9,7 +10,7 @@ import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.enums.AccessFromType;
 import com.ruoyi.common.enums.ErrorCodes;
 import com.ruoyi.common.exception.ErrorException;
-import com.ruoyi.common.utils.PhoneUtils;
+import com.ruoyi.common.utils.*;
 import com.ruoyi.dz.domain.DzCards;
 import com.ruoyi.dz.service.IDzCardsService;
 import com.ruoyi.dz.service.impl.DzCardsServiceImpl;
@@ -37,9 +38,6 @@ import com.ruoyi.common.exception.user.CaptchaException;
 import com.ruoyi.common.exception.user.CaptchaExpireException;
 import com.ruoyi.common.exception.user.UserNotExistsException;
 import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
-import com.ruoyi.common.utils.DateUtils;
-import com.ruoyi.common.utils.MessageUtils;
-import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.ip.IpUtils;
 import com.ruoyi.framework.manager.AsyncManager;
 import com.ruoyi.framework.manager.factory.AsyncFactory;
@@ -82,6 +80,28 @@ public class SysLoginService
     @Autowired
     private IZuserTokenService zuserTokenService;
 
+    public AjaxResult bindOpenId(String openid, String phoneNumber) {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        if(StringUtils.isBlank(phoneNumber) || phoneNumber.equals(loginUser.getUser().getPhonenumber())) {
+            return AjaxResult.error("用户手机号不一致");
+        }
+        SysUser upUser = new SysUser();
+        upUser.setUserId(loginUser.getUserId());
+        upUser.setOpenId(openid);
+        if (userService.updateUserProfile(upUser) > 0)
+        {
+            // 更新缓存用户信息
+            loginUser.getUser().setOpenId(openid);
+            tokenService.setLoginUser(loginUser);
+            return AjaxResult.success(JSONObject.of("openId", openid));
+        }
+        return AjaxResult.success(JSONObject.of("openId", openid));
+    }
+
+    public AjaxResult loginByCode(String openId) {
+        SysUser u = userService.selectUserByOpenId(openId);
+        return loginByUserAndPass("front", u.getUserName(), u.getPassword2());
+    }
 
     /**
      * 登录验证
@@ -108,30 +128,33 @@ public class SysLoginService
             validateCaptcha(username, code, uuid);
             // 登录前置校验
             loginPreCheck(username, password);
-            if(AccessFromType.isFrontApp(type)||AccessFromType.isH5(type)||AccessFromType.isWechat(type)){
+            if (AccessFromType.isFrontApp(type) || AccessFromType.isH5(type) || AccessFromType.isWechat(type)) {
                 //卡密登录时,要将卡的密码转换为用户的密码。手机号的密码与卡的密码分开
                 DzCards card = cardsService.selectDzCardsByCardNo(username);
-                if (null==card){
-                    if(username.length()>6&&username.length()<8){
+                if (null == card) {
+                    if (username.length() > 6 && username.length() < 8) {
                         //老师账号,直接跳过
 
-                    }else if(username.length()>=8){
+                    } else if (username.length() >= 8) {
                         //卡用户
                         return AjaxResult.error("卡不存在");
                     }
                 }
-                if(null!=card&&username.length()>=8){
+                if (null != card && username.length() >= 8) {
                     //卡用户
-                    if (!password.trim().equalsIgnoreCase(card.getPassword())){
+                    if (!password.trim().equalsIgnoreCase(card.getPassword())) {
                         return AjaxResult.error("密码错误");
                     }
                     String dbPwd = userService.selectPasswordByCardId(card.getCardId());
-                    if (StringUtils.isNotEmpty(dbPwd)){
+                    if (StringUtils.isNotEmpty(dbPwd)) {
                         password = dbPwd;
                     }
                 }
             }
         }
+        return loginByUserAndPass(type, username, password);
+    }
+    private AjaxResult loginByUserAndPass(String type, String username, String password) {
         // 用户验证
         Authentication authentication = null;
         try

+ 1 - 1
ie-admin/src/main/resources/application-druid.yml

@@ -6,7 +6,7 @@ spring:
         druid:
             # 主库数据源
             master:
-                url: jdbc:mysql://49.234.186.218:3306/ie2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                url: jdbc:mysql://49.234.186.218:3306/ie3?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
                 username: ietest
                 password: 5arg$sKkztn3FzyU*b
             # 从库数据源

+ 2 - 1
ie-admin/src/main/resources/application.yml

@@ -167,7 +167,8 @@ wxpay:
   key: zhilongsanjiasanzhilongsanjiasan
   mchKey: zhilongsanjiasanzhilongsanjiasan
   apiV3Key: zhilongsanjiasanzhilongsanjiasan
-  appId: wx7b9ff116a897456a
+  appId: wxadcab19e07ceef0f
+  appSecret: fd7787e5882ecb60a7cfee40c45bd6d5
   keyPath: /app/art/wxpayCert/
   mchsn: 21925f369f23cdf8ea3a913c541d4239d1bcc8af
   privateKey: "-----BEGIN PRIVATE KEY-----\

+ 10 - 0
ie-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java

@@ -42,6 +42,8 @@ public class SysUser extends BaseEntity
 //    @Excel(name = "机构编号", type = Type.IMPORT)
     private Long deptId;
 
+    private String openId;
+
     /** 用户账号 */
 //    @Excel(name = "登录名称")
     private String userName;
@@ -297,6 +299,14 @@ public class SysUser extends BaseEntity
         this.nickName = nickName;
     }
 
+    public String getOpenId() {
+        return openId;
+    }
+
+    public void setOpenId(String openId) {
+        this.openId = openId;
+    }
+
     @Xss(message = "用户账号不能包含脚本字符")
     @NotBlank(message = "用户账号不能为空")
     @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")

+ 1 - 0
ie-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java

@@ -49,6 +49,7 @@ public interface SysUserMapper
      * @return 用户对象信息
      */
     public SysUser selectUserByUserName(String userName);
+    public SysUser selectUserByOpenId(String openId);
     public String selectPasswordByCardId(Long cardId);
     public List<java.util.Map<String, Object>> selectPassword2ByUserIds(@Param("userIds") Collection<Long> userIds);
 

+ 1 - 0
ie-system/src/main/java/com/ruoyi/system/service/ISysUserService.java

@@ -47,6 +47,7 @@ public interface ISysUserService
      * @return 用户对象信息
      */
     public SysUser selectUserByUserName(String userName);
+    public SysUser selectUserByOpenId(String openId);
     public String selectPasswordByCardId(Long cardId);
     public Map<Long, String> selectPassword2ByUserIds(Collection<Long> userIds);
     /**

+ 4 - 0
ie-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java

@@ -179,6 +179,10 @@ public class SysUserServiceImpl implements ISysUserService
         return userMapper.selectUserByUserName(userName);
     }
 
+    public SysUser selectUserByOpenId(String openId) {
+        return userMapper.selectUserByOpenId(openId);
+    }
+
     /**
      * 通过手机号查询用户
      * @param mobileNo

+ 7 - 1
ie-system/src/main/resources/mapper/system/SysUserMapper.xml

@@ -70,7 +70,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         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.pwd_update_date, u.create_by, u.create_time, u.remark,
 		u.location,u.exam_type,u.reg_status,u.end_year,u.invite_code,u.scores,u.exam_major,u.score,u.score_lock,u.seat_input,u.exam_major_name,u.directed_study,u.eval_counts,u.card_id,u.bind_status,u.account_type,
         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, u.user_type, u.user_type_id
+        r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status, u.user_type, u.user_type_id, u.open_id
         from sys_user u
 		    left join sys_dept d on u.dept_id = d.dept_id
 		    left join sys_user_role ur on u.user_id = ur.user_id
@@ -266,6 +266,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		and u.del_flag = '0'
 	</select>
 
+	<select id="selectUserByOpenId" parameterType="String" resultMap="SysUserResult">
+		<include refid="selectUserVo"/>
+		where u.open_id = #{openId} and u.del_flag = '0'
+	</select>
+
 	<select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult">
 	    <include refid="selectUserVo"/>
 		where u.user_name = #{userName} and u.del_flag = '0'
@@ -402,6 +407,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			<if test="userName != null and userName != ''">user_name = #{userName},</if>
  			<if test="email != null ">email = #{email},</if>
  			<if test="phonenumber != null ">phonenumber = #{phonenumber},</if>
+ 			<if test="openId != null ">open_id = #{openId},</if>
  			<if test="sex != null and sex != ''">sex = #{sex},</if>
  			<if test="avatar != null and avatar != ''">avatar = #{avatar},</if>
  			<if test="password != null and password != ''">password = #{password},</if>