Browse Source

微信登录

xiatian 2 years ago
parent
commit
2bd5d63d13

+ 13 - 0
db/init.sql

@@ -1,3 +1,16 @@
+DROP TABLE IF EXISTS `mps_wxapp_info`;
+CREATE TABLE `mps_wxapp_info` (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `create_time` datetime DEFAULT NULL,
+  `update_time` datetime DEFAULT NULL,
+  `creator_id` bigint DEFAULT NULL,
+  `updater_id` bigint DEFAULT NULL,
+  `openid` varchar(255) COLLATE utf8_bin NOT NULL,
+  `phone` varchar(255) COLLATE utf8_bin NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `IDX_WXAPP_INFO_01` (`openid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
 DROP TABLE IF EXISTS `mps_wxapp_access_token`;
 CREATE TABLE `mps_wxapp_access_token` (
   `id` bigint NOT NULL AUTO_INCREMENT,

+ 15 - 6
src/main/java/cn/com/qmth/mps/controller/AuthController.java

@@ -6,6 +6,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
 import com.qmth.boot.api.constant.ApiConstant;
 
 import cn.com.qmth.mps.bean.User;
@@ -28,17 +30,24 @@ public class AuthController extends BaseController {
 	}
 
 	@ApiOperation(value = "微信小程序登录")
-	@PostMapping("login/wxapp/code")
-	public AdminLoginVo loginWxAppCode(@RequestParam String wxappCode) {
-		return authService.loginWxAppCode(wxappCode);
+	@PostMapping("login/wxapp/login-code")
+	public AdminLoginVo loginWxApp(@RequestParam String loginCode) {
+		return authService.loginWxAppCode(loginCode);
 	}
 	
-	@ApiOperation(value = "微信小程序登录")
+	@ApiOperation(value = "绑定微信手机号并登录(新api)")
+	@PostMapping("login/wxapp/phone-code")
+	public AdminLoginVo loginWxAppByPhoneCode(@RequestParam String loginCode,@RequestParam String phoneCode) {
+		return authService.loginWxAppByPhoneCode(loginCode,phoneCode);
+	}
+	
+	@ApiOperation(value = "绑定微信手机号并登录(旧api)")
 	@PostMapping("login/wxapp/encrypted-data")
-	public AdminLoginVo loginWxAppEncryptedData(@RequestParam String wxappCode,@RequestParam String encryptedData,@RequestParam String iv) {
-		return authService.loginWxAppEncryptedData(wxappCode,encryptedData,iv);
+	public AdminLoginVo loginWxAppByEncryptedData(@RequestParam String loginCode,@RequestParam String encryptedData,@RequestParam String iv) {
+		return authService.loginWxAppByEncryptedData(loginCode,encryptedData,iv);
 	}
 
+	@Aac(strict = BOOL.FALSE, auth = BOOL.TRUE)
 	@ApiOperation(value = "登出")
 	@PostMapping("logout")
 	public void logout() {

+ 9 - 0
src/main/java/cn/com/qmth/mps/dao/WxappInfoDao.java

@@ -0,0 +1,9 @@
+package cn.com.qmth.mps.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import cn.com.qmth.mps.entity.WxappInfoEntity;
+
+public interface WxappInfoDao extends BaseMapper<WxappInfoEntity> {
+
+}

+ 29 - 0
src/main/java/cn/com/qmth/mps/entity/WxappInfoEntity.java

@@ -0,0 +1,29 @@
+package cn.com.qmth.mps.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import cn.com.qmth.mps.entity.base.AuditingEntity;
+@TableName("mps_wxapp_info")
+public class WxappInfoEntity extends AuditingEntity {
+
+	private static final long serialVersionUID = -6261302618070108336L;
+
+	private String openid;
+	private String phone;
+	public String getOpenid() {
+		return openid;
+	}
+	public void setOpenid(String openid) {
+		this.openid = openid;
+	}
+	public String getPhone() {
+		return phone;
+	}
+	public void setPhone(String phone) {
+		this.phone = phone;
+	}
+
+
+	
+
+}

+ 9 - 0
src/main/java/cn/com/qmth/mps/exception/ParameterExceptions.java

@@ -0,0 +1,9 @@
+package cn.com.qmth.mps.exception;
+
+import com.qmth.boot.core.exception.ParameterException;
+
+public interface ParameterExceptions {
+
+    ParameterException OPENID_NOT_FOUND = new ParameterException(101, null, "微信用户未绑定", null);
+
+}

+ 3 - 3
src/main/java/cn/com/qmth/mps/service/AuthService.java

@@ -13,8 +13,8 @@ public interface AuthService {
 
 	void modifyWxappAccessToken();
 
-	AdminLoginVo loginWxAppEncryptedData(String wxappCode, String encryptedData, String iv);
-
-
+	AdminLoginVo loginWxAppByEncryptedData(String loginCode, String encryptedData, String iv);
+	
+	AdminLoginVo loginWxAppByPhoneCode(String loginCode,String phoneCode);
 
 }

+ 12 - 0
src/main/java/cn/com/qmth/mps/service/WxappInfoService.java

@@ -0,0 +1,12 @@
+package cn.com.qmth.mps.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import cn.com.qmth.mps.entity.WxappInfoEntity;
+
+public interface WxappInfoService  extends IService<WxappInfoEntity> {
+
+	WxappInfoEntity getByOpenId(String openid);
+
+
+}

+ 81 - 20
src/main/java/cn/com/qmth/mps/service/impl/AuthServiceImpl.java

@@ -10,6 +10,7 @@ import javax.crypto.spec.SecretKeySpec;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import com.qmth.boot.core.exception.StatusException;
 import com.qmth.boot.core.security.annotation.AuthorizationComponent;
@@ -21,11 +22,14 @@ import cn.com.qmth.mps.bean.User;
 import cn.com.qmth.mps.config.SysProperty;
 import cn.com.qmth.mps.entity.UserEntity;
 import cn.com.qmth.mps.entity.WxappAccessTokenEntity;
+import cn.com.qmth.mps.entity.WxappInfoEntity;
 import cn.com.qmth.mps.enums.Role;
+import cn.com.qmth.mps.exception.ParameterExceptions;
 import cn.com.qmth.mps.service.AuthService;
 import cn.com.qmth.mps.service.SessionService;
 import cn.com.qmth.mps.service.UserService;
 import cn.com.qmth.mps.service.WxappAccessTokenService;
+import cn.com.qmth.mps.service.WxappInfoService;
 import cn.com.qmth.mps.util.ByteUtil;
 import cn.com.qmth.mps.util.HttpUtil;
 import cn.com.qmth.mps.util.SHA256;
@@ -44,24 +48,18 @@ public class AuthServiceImpl implements AuthorizationService<User>, AuthService
 	private WxappAccessTokenService wxappAccessTokenService;
 	@Autowired
 	private SysProperty sysProperty;
+	@Autowired
+	private WxappInfoService wxappInfoService;
 
 	@Override
-	public AdminLoginVo loginWxAppCode(String wxappCode) {
-
-		Map<String, String> params = new HashMap<>();
-		params.put("code", wxappCode);
-		String ret;
-		try {
-			ret = HttpUtil.httpActionPost("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="
-					+ wxappAccessTokenService.getWxappAccessToken().getAccessToken(), null, params);
-		} catch (Exception e) {
-			throw new StatusException("登录失败", e);
+	public AdminLoginVo loginWxAppCode(String loginCode) {
+		JSONObject auth=getAuthorization(loginCode);
+		String openid=auth.getString("openid");
+		WxappInfoEntity wi=wxappInfoService.getByOpenId(openid);
+		if(wi==null) {
+			throw ParameterExceptions.OPENID_NOT_FOUND;
 		}
-		JSONObject jo = JSONObject.fromObject(ret);
-		if (jo.getInt("errcode") != 0) {
-			throw new StatusException("登录失败," + jo.getString("errmsg"));
-		}
-		UserEntity userEntity = userService.getByLoginName(jo.getJSONObject("phone_info").getString("purePhoneNumber"));
+		UserEntity userEntity = userService.getByLoginName(wi.getPhone());
 		if (userEntity == null) {
 			throw new StatusException("微信所绑定手机号系统中不存在");
 		}
@@ -166,9 +164,12 @@ public class AuthServiceImpl implements AuthorizationService<User>, AuthService
 		}
 	}
 
+	@Transactional
 	@Override
-	public AdminLoginVo loginWxAppEncryptedData(String wxappCode, String encryptedData, String iv) {
-		JSONObject jo=decrypt(encryptedData, iv, getSessionKey(wxappCode));
+	public AdminLoginVo loginWxAppByEncryptedData(String loginCode, String encryptedData, String iv) {
+		JSONObject auth=getAuthorization(loginCode);
+		String openid=auth.getString("openid");
+		JSONObject jo=decrypt(encryptedData, iv, auth.getString("session_key"));
 		String phone=jo.getString("purePhoneNumber");
 		UserEntity userEntity = userService.getByLoginName(phone);
 		if (userEntity == null) {
@@ -180,6 +181,13 @@ public class AuthServiceImpl implements AuthorizationService<User>, AuthService
 		if (!userEntity.getRoleId().equals(Role.SECTION_LEADER.getId())) {
 			throw new StatusException("该用户不是科组长");
 		}
+		WxappInfoEntity wi=wxappInfoService.getByOpenId(openid);
+		if(wi==null) {
+			wi=new WxappInfoEntity();
+			wi.setOpenid(openid);
+		}
+		wi.setPhone(phone);
+		wxappInfoService.saveOrUpdate(wi);
 		User user = new User();
 		user.setName(userEntity.getName());
 		user.setSchoolId(userEntity.getSchoolId());
@@ -197,11 +205,11 @@ public class AuthServiceImpl implements AuthorizationService<User>, AuthService
 		return vo;
 	}
 
-	private String getSessionKey(String wxappCode) {
+	private JSONObject getAuthorization(String loginCode) {
 		Map<String, String> params = new HashMap<>();
 		params.put("appid", sysProperty.getWxappAppid());
 		params.put("secret", sysProperty.getWxappSecret());
-		params.put("js_code", wxappCode);
+		params.put("js_code", loginCode);
 		params.put("grant_type", "authorization_code");
 		String ret;
 		try {
@@ -213,7 +221,7 @@ public class AuthServiceImpl implements AuthorizationService<User>, AuthService
 		if (jo.containsKey("errcode")) {
 			throw new StatusException("登录失败," + jo.getString("errmsg"));
 		}
-		return jo.getString("session_key");
+		return jo;
 	}
 
 	private JSONObject decrypt(String encryptedData, String iv, String sessionKey){
@@ -246,4 +254,57 @@ public class AuthServiceImpl implements AuthorizationService<User>, AuthService
 		JSONObject jsonObject = JSONObject.fromObject(jsonStr);
 		return jsonObject;
 	}
+
+	@Transactional
+	@Override
+	public AdminLoginVo loginWxAppByPhoneCode(String loginCode,String phoneCode) {
+		Map<String, String> params = new HashMap<>();
+		params.put("code", phoneCode);
+		String ret;
+		try {
+			ret = HttpUtil.httpActionPost("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="
+					+ wxappAccessTokenService.getWxappAccessToken().getAccessToken(), null, params);
+		} catch (Exception e) {
+			throw new StatusException("登录失败", e);
+		}
+		JSONObject jo = JSONObject.fromObject(ret);
+		if (jo.getInt("errcode") != 0) {
+			throw new StatusException("登录失败," + jo.getString("errmsg"));
+		}
+		String phone=jo.getJSONObject("phone_info").getString("purePhoneNumber");
+		UserEntity userEntity = userService.getByLoginName(phone);
+		if (userEntity == null) {
+			throw new StatusException("微信所绑定手机号系统中不存在");
+		}
+		if (!userEntity.getEnable()) {
+			throw new StatusException("该用户已禁用");
+		}
+		if (!userEntity.getRoleId().equals(Role.SECTION_LEADER.getId())) {
+			throw new StatusException("该用户不是科组长");
+		}
+		JSONObject auth=getAuthorization(loginCode);
+		String openid=auth.getString("openid");
+		WxappInfoEntity wi=wxappInfoService.getByOpenId(openid);
+		if(wi==null) {
+			wi=new WxappInfoEntity();
+			wi.setOpenid(openid);
+		}
+		wi.setPhone(phone);
+		wxappInfoService.saveOrUpdate(wi);
+		User user = new User();
+		user.setName(userEntity.getName());
+		user.setSchoolId(userEntity.getSchoolId());
+		user.setId(userEntity.getId());
+		user.setRole(Role.getById(userEntity.getRoleId()));
+		user.setAccessToken(FastUUID.get());
+		user.buildKey();
+		sessionService.userLogin(user);
+		AdminLoginVo vo = new AdminLoginVo();
+		vo.setAccessToken(user.getAccessToken());
+		vo.setName(user.getName());
+		vo.setSessionId(user.getSessionId());
+		vo.setSchoolId(user.getSchoolId());
+		vo.setRole(user.getRole());
+		return vo;
+	}
 }

+ 25 - 0
src/main/java/cn/com/qmth/mps/service/impl/WxappInfoServiceImpl.java

@@ -0,0 +1,25 @@
+package cn.com.qmth.mps.service.impl;
+
+import org.springframework.stereotype.Service;
+
+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 cn.com.qmth.mps.dao.WxappInfoDao;
+import cn.com.qmth.mps.entity.WxappInfoEntity;
+import cn.com.qmth.mps.service.WxappInfoService;
+
+@Service
+public class WxappInfoServiceImpl extends ServiceImpl<WxappInfoDao, WxappInfoEntity> implements WxappInfoService {
+
+	@Override
+	public WxappInfoEntity getByOpenId(String openid) {
+		QueryWrapper<WxappInfoEntity> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<WxappInfoEntity> lw = wrapper.lambda();
+        lw.eq(WxappInfoEntity::getOpenid, openid);
+        return this.getOne(wrapper);
+	}
+
+
+}

+ 4 - 5
src/main/java/cn/com/qmth/mps/util/HttpUtil.java

@@ -19,6 +19,8 @@ import javax.net.ssl.X509TrustManager;
 
 import com.qmth.boot.core.exception.StatusException;
 
+import net.sf.json.JSONObject;
+
 public class HttpUtil {
 
 	/** 默认的编码格式 */
@@ -79,12 +81,9 @@ public class HttpUtil {
 			// 创建链接
 			conn.connect();
 			if (params != null) {
-				StringBuilder sb = new StringBuilder();
-				for (Map.Entry<String, String> data : params.entrySet()) {
-					sb.append(data.getKey()).append("=").append(data.getValue()).append("&");
-				}
+				String s=JSONObject.fromObject(params).toString();
 				os = conn.getOutputStream();
-				os.write(sb.toString().getBytes());
+				os.write(s.toString().getBytes());
 				os.flush();
 			}
 			result = getResult(conn);

+ 2 - 2
src/main/resources/application.properties

@@ -30,8 +30,8 @@ spring.jackson.time-zone=GMT+8
 session-timeout=7200
 
 wxapp-url=xxx
-wxapp-appid=xxx
-wxapp-secret=xxx
+wxapp-appid=wx10dd4d0b8b83cc1f
+wxapp-secret=e2cddb7ac0962f6b92ea860aeaeb4b77
 markingcloud.server=http://192.168.10.224:8080
 qmth.solar.host=https://solar.qmth.com.cn
 qmth.solar.org.uri=/api/open/org/query