diff --git a/src/main/java/com/ynxbd/common/action/pay/WxAuthAction.java b/src/main/java/com/ynxbd/common/action/auth/WxAuthAction.java similarity index 66% rename from src/main/java/com/ynxbd/common/action/pay/WxAuthAction.java rename to src/main/java/com/ynxbd/common/action/auth/WxAuthAction.java index 914439d..b633aa4 100644 --- a/src/main/java/com/ynxbd/common/action/pay/WxAuthAction.java +++ b/src/main/java/com/ynxbd/common/action/auth/WxAuthAction.java @@ -1,45 +1,37 @@ -package com.ynxbd.common.action.pay; - -import com.ynxbd.common.action.base.BaseAction; -import com.ynxbd.common.result.Result; -import com.ynxbd.wx.config.WeChatConfig; -import com.ynxbd.wx.wxfactory.WxAuthHelper; -import lombok.extern.slf4j.Slf4j; -import org.apache.struts2.convention.annotation.Action; -import org.apache.struts2.convention.annotation.Namespace; - - -@Slf4j -@Namespace("/wx_auth") -public class WxAuthAction extends BaseAction { - - @Action("is_auth") - public Result is_auth() throws Exception { - return WxAuthHelper.isAuth(request, response, false); - } - - @Action("u_auth") - public Result u_auth() { - String auth = WxAuthHelper.auth(request, response, true); - return Result.redirect(auth); - } - - @Action("b_auth") - public Result b_auth() { - String auth = WxAuthHelper.auth(request, response, false); - return Result.redirect(auth); - } - - - @Action("is_pay_auth") - public Result is_pay_auth() throws Exception { - // 支付使用普通授权 - return WxAuthHelper.isAuth(request, response, true); - } - -// @Action("pay_b_auth") -// public Result pay_b_auth() throws Exception { -// String auth = WxAuthHelper.auth(request, response, true, true); -// return Result.redirect(auth); -// } -} +package com.ynxbd.common.action.auth; + +import com.ynxbd.common.action.base.BaseAction; +import com.ynxbd.common.result.Result; +import com.ynxbd.wx.wxfactory.WxAuthHelper; +import lombok.extern.slf4j.Slf4j; +import org.apache.struts2.convention.annotation.Action; +import org.apache.struts2.convention.annotation.Namespace; + + +@Slf4j +@Namespace("/wx_auth") +public class WxAuthAction extends BaseAction { + + @Action("is_auth") + public Result is_auth() throws Exception { + return WxAuthHelper.isAuth(request, response); + } + + @Action("u_auth") + public Result u_auth() { + String auth = WxAuthHelper.auth(request, response, true); + return Result.redirect(auth); + } + + @Action("b_auth") + public Result b_auth() { + String auth = WxAuthHelper.auth(request, response, false); + return Result.redirect(auth); + } + + @Action("is_pay_auth") + public Result is_pay_auth() throws Exception { + // 支付使用普通授权 + return WxAuthHelper.isAuth(request, response); + } +} diff --git a/src/main/java/com/ynxbd/common/bean/GMCUser.java b/src/main/java/com/ynxbd/common/bean/GMCUser.java new file mode 100644 index 0000000..4ef5b67 --- /dev/null +++ b/src/main/java/com/ynxbd/common/bean/GMCUser.java @@ -0,0 +1,29 @@ +package com.ynxbd.common.bean; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +import java.util.Date; + + +@Setter +@Getter +@ToString +@NoArgsConstructor +public class GMCUser { + + private Long id; + + private Date updateTime; + + private String wxOpenId; + + private String gmcOpenId; + + private String gmcUnionId; + + private String gmcUUID; + +} diff --git a/src/main/java/com/ynxbd/common/dao/GMCUserDao.java b/src/main/java/com/ynxbd/common/dao/GMCUserDao.java new file mode 100644 index 0000000..8752b3d --- /dev/null +++ b/src/main/java/com/ynxbd/common/dao/GMCUserDao.java @@ -0,0 +1,33 @@ +package com.ynxbd.common.dao; + +import com.ynxbd.common.bean.GMCUser; +import com.ynxbd.common.config.db.DataBase; +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +public class GMCUserDao { + + /** + * 查询用户关联关系 + */ + public GMCUser selectByOpenId(String wxOpenId) { + String sql = "select * from gmc_user where wxOpenId=?"; + return DataBase.selectOne(sql, GMCUser.class, ps -> { + ps.setString(1, wxOpenId); + }); + } + + /** + * 添加关系 + */ + public boolean insert(String wxOpenId, String gmcOpenId, String gmcUnionId, String gmcUUID) { + String sql = "insert into gmc_user(updateTime, wxOpenId, gmcOpenId, gmcUnionId, gmcUUID) values (now(),?,?,?,?)"; + return DataBase.insert(sql, ps -> { + ps.setString(1, wxOpenId); + ps.setString(2, gmcOpenId); + ps.setString(3, gmcUnionId); + ps.setString(4, gmcUUID); + }) > 0; + } +} diff --git a/src/main/java/com/ynxbd/common/helper/common/CodeHelper.java b/src/main/java/com/ynxbd/common/helper/common/CodeHelper.java index 361e254..d7d4900 100644 --- a/src/main/java/com/ynxbd/common/helper/common/CodeHelper.java +++ b/src/main/java/com/ynxbd/common/helper/common/CodeHelper.java @@ -55,11 +55,8 @@ public class CodeHelper { } public static void main(String[] args) { - String outTradeNo = getOutTradeNo(MerchantEnum.WX); - String bankTransNo = outTradeNo.substring(MerchantEnum.WX.CODE.length()); - System.out.println(bankTransNo); + System.out.println(UUID.randomUUID()); } - /** * 生成数字验证码 * diff --git a/src/main/java/com/ynxbd/common/helper/http/OkHttpHelper.java b/src/main/java/com/ynxbd/common/helper/http/OkHttpHelper.java index acf16ca..00db11c 100644 --- a/src/main/java/com/ynxbd/common/helper/http/OkHttpHelper.java +++ b/src/main/java/com/ynxbd/common/helper/http/OkHttpHelper.java @@ -197,9 +197,7 @@ public class OkHttpHelper { if (body == null) { return null; } - String respBody = body.string(); - log.info("接口响应数据resp={}", respBody); - return respBody; + return body.string(); } } catch (Exception e) { ErrorHelper.println(e); diff --git a/src/main/java/com/ynxbd/common/result/JsonResult.java b/src/main/java/com/ynxbd/common/result/JsonResult.java index 52b0eeb..5d55a97 100644 --- a/src/main/java/com/ynxbd/common/result/JsonResult.java +++ b/src/main/java/com/ynxbd/common/result/JsonResult.java @@ -420,6 +420,25 @@ public class JsonResult { return JsonHelper.decodeBean(data.toString(), clazz); } + + public List dataMapGetNodeToList(Class clazz) { + return dataMapGetNodeToList(clazz, "data"); + } + + /** + * 获取DataMap为bean + * + * @param clazz 类型 + * @return bean + */ + public List dataMapGetNodeToList(Class clazz, String dataName) { + Object data = this.dataMap.get(dataName); + if (data == null) { + return null; + } + return JsonHelper.decodeList(data.toString(), clazz); + } + /** * 获取DataMap为bean * diff --git a/src/main/java/com/ynxbd/common/result/JsonResultEnum.java b/src/main/java/com/ynxbd/common/result/JsonResultEnum.java index 2d0070b..144f12d 100644 --- a/src/main/java/com/ynxbd/common/result/JsonResultEnum.java +++ b/src/main/java/com/ynxbd/common/result/JsonResultEnum.java @@ -16,16 +16,17 @@ public enum JsonResultEnum { SYS_ME("[医保]", "return_code", "return_msg", "SUCCESS", "FAIL", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)), + SYS_MICRO("[微官网]", "code", "message", "200", "0", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)), + SYS_MEDICAL_ASSISTANT("[就医助手]", "errcode", "errmsg", "0", "-1", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)), SYS_HIS("[HIS]", "ResponseCode", "ResponseMessage", "0", "-1", "500"), - SYS_RESERVE("[天助预约]","code","msg","0","-1",String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)), + SYS_RESERVE("[天助预约]", "code", "msg", "0", "-1", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)), SYS_RM_LIS("[瑞美LIS]", "ResultCode", "ResultMessage", "1", "0", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)), - SYS_PEIS_RESERVE("[体检预约]", "code", "message", "200", "0", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)) - ; + SYS_PEIS_RESERVE("[体检预约]", "code", "message", "200", "0", String.valueOf(HttpStatus.HTTP_CLIENT_TIMEOUT)); // 调用系统标识 public final String SYS; diff --git a/src/main/java/com/ynxbd/common/result/Result.java b/src/main/java/com/ynxbd/common/result/Result.java index 2ff6523..73ed323 100644 --- a/src/main/java/com/ynxbd/common/result/Result.java +++ b/src/main/java/com/ynxbd/common/result/Result.java @@ -1,5 +1,6 @@ package com.ynxbd.common.result; +import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonIgnore; import com.ynxbd.common.helper.common.DateHelper; @@ -12,7 +13,6 @@ import lombok.ToString; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; -import java.time.LocalDate; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -27,8 +27,6 @@ import java.util.Map; public class Result extends BaseResult { private static final long serialVersionUID = -1005L; - // - private Integer code; private String message; private Object data; @@ -192,5 +190,24 @@ public class Result extends BaseResult { this.date = DateHelper.getCurDateTime(); } + public String toDataStr(){ + if (data == null) return null; + return data.toString(); + } + + public T dataToBean(Class clazz) { + if(this.data == null) return null; + return JsonHelper.parseObject(JsonHelper.toJsonString(this.data), clazz); + } + + public List dataToList(Class clazz) { + if(this.data == null) return new ArrayList<>(); + return JsonHelper.parseArray(JsonHelper.toJsonString(this.data), clazz); + } + + public JSONObject dataToBean() { + return JsonHelper.parseObject(JsonHelper.toJsonString(this.data)); + } + } diff --git a/src/main/java/com/ynxbd/common/service/GMCUserService.java b/src/main/java/com/ynxbd/common/service/GMCUserService.java new file mode 100644 index 0000000..3301274 --- /dev/null +++ b/src/main/java/com/ynxbd/common/service/GMCUserService.java @@ -0,0 +1,31 @@ +package com.ynxbd.common.service; + +import com.ynxbd.common.bean.GMCUser; +import com.ynxbd.common.dao.GMCUserDao; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; + +@Slf4j +public class GMCUserService { + + /** + * 查询用户关联关系 + */ + public GMCUser queryInfoByOpenId(String wxOpenId) { + return new GMCUserDao().selectByOpenId(wxOpenId); + } + + /** + * 添加用户关系 + */ + public boolean addInfo(String wxOpenId, String gmcOpenId, String gmcUnionId, String gmcUUID) { + try { + if (ObjectUtils.isEmpty(wxOpenId) || ObjectUtils.isEmpty(gmcOpenId) || ObjectUtils.isEmpty(gmcUUID)) { + return false; + } + return new GMCUserDao().insert(wxOpenId, gmcOpenId, gmcUnionId, gmcUUID); + } catch (Exception e) { + return false; + } + } +} diff --git a/src/main/java/com/ynxbd/wx/wxfactory/WxAuthHelper.java b/src/main/java/com/ynxbd/wx/wxfactory/WxAuthHelper.java index 44c1ae0..5362712 100644 --- a/src/main/java/com/ynxbd/wx/wxfactory/WxAuthHelper.java +++ b/src/main/java/com/ynxbd/wx/wxfactory/WxAuthHelper.java @@ -1,13 +1,18 @@ package com.ynxbd.wx.wxfactory; +import com.ynxbd.common.bean.GMCUser; import com.ynxbd.common.bean.Patient; import com.ynxbd.common.bean.User; import com.ynxbd.common.helper.common.*; import com.ynxbd.common.helper.http.OkHttpHelper; +import com.ynxbd.common.result.JsonResult; +import com.ynxbd.common.result.JsonResultEnum; import com.ynxbd.common.result.Result; +import com.ynxbd.common.service.GMCUserService; import com.ynxbd.common.service.PatientService; import com.ynxbd.wx.config.WeChatConfig; -import com.ynxbd.wx.wxfactory.base.auth.models.AuthData; +import com.ynxbd.wx.wxfactory.base.auth.models.AuthResultData; +import com.ynxbd.wx.wxfactory.base.auth.models.AuthTokenData; import com.ynxbd.wx.wxfactory.base.auth.models.SnsOath2AccessToken; import com.ynxbd.wx.wxfactory.base.auth.models.SnsUserInfo; import lombok.extern.slf4j.Slf4j; @@ -19,7 +24,10 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.net.URLDecoder; import java.net.URLEncoder; -import java.util.*; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @Slf4j public class WxAuthHelper { @@ -29,47 +37,35 @@ public class WxAuthHelper { private static final String P_SUFFIX = ":"; // 后缀 private static final String AUTH_SESSION_ID_NAME = "SID"; - private static final String UNION_ID_NAME = "UID"; + private static final String GMC_ID = "GMCId"; + private static final String OPENID = "openid"; public static String auth(HttpServletRequest request, HttpServletResponse response, boolean isUserInfo) { - String code = request.getParameter("code"); - String state = request.getParameter("state"); // base64 - Map paramsMap = getParamsMap(request.getParameter("p")); - - log.info("[授权] code={}, state={}, paramsMap={}", code, state, JsonHelper.toJsonString(paramsMap)); try { + String code = request.getParameter("code"); + String state = request.getParameter("state"); // base64 + Map paramsMap = getParamsMap(request.getParameter("p")); + + log.info("[认证授权] code={}, state={}, paramsMap={}", code, state, JsonHelper.toJsonString(paramsMap)); + state = state == null ? "" : URLDecoder.decode(Base64Helper.decode(state), "UTF-8"); - String enUnionId = paramsMap.get(UNION_ID_NAME); - String enAuthSessionId = paramsMap.get(AUTH_SESSION_ID_NAME); - String authSessionId = AesWxHelper.decode(enAuthSessionId); - - paramsMap.get(AUTH_SESSION_ID_NAME); - -// if (!ObjectUtils.isEmpty(params)) { -// int index = params.indexOf("@" + AUTH_SESSION_ID_NAME + ":"); -// if (index == -1) index = params.indexOf("%40" + AUTH_SESSION_ID_NAME + ":"); // 防止数据转义失败 -// if (index != -1) { -// enUnionId = params.substring(0, index); -// authSessionId = params.substring(index); -// authSessionId = AesWxHelper.decode(authSessionId); -// } -// } - log.info("[授权-解码] enUnionId={}, enAuthSessionId={}, authSessionId={}, state={}", enUnionId, enAuthSessionId, authSessionId, state); + String authSessionId = AesWxHelper.decode(paramsMap.get(AUTH_SESSION_ID_NAME)); + + log.info("[认证授权-解码] authSessionId={}, state={}", authSessionId, state); SnsOath2AccessToken snsToken = WxFactory.Base.OAuth().oauth2AccessToken(WeChatConfig.APP_ID, WeChatConfig.APP_SECRET, code); - log.info("[授权-用户]snsToken={}", JsonHelper.toJsonString(snsToken)); + log.info("[认证授权]信息 snsToken={}", JsonHelper.toJsonString(snsToken)); if (snsToken != null) { String openid = snsToken.getOpenid(); String unionId = snsToken.getUnionid(); - if (unionId == null) { - log.info("[测试] enUnionId={}", enUnionId); - } + if (openid != null) { HttpSession session = request.getSession(); session.setMaxInactiveInterval(SESSION_MAX_INACTIVE_INTERVAL); - session.setAttribute("openid", openid); - WxCacheHelper.putOpenIdToAIDCache(authSessionId, openid); + session.setAttribute(OPENID, openid); + + WxCacheHelper.putOpenIdCacheToSessionIdCache(authSessionId, openid); Cache cache = WxCacheHelper.getUserCacheManager(); if (WeChatConfig.isDevUser(openid) || !cache.containsKey(openid)) { @@ -108,7 +104,6 @@ public class WxAuthHelper { } } - if (WeChatConfig.HAS_HTTPS_BY_BASE_URL) { // 强制为https String httpsURL = URLHelper.URLToHttps(state); state = httpsURL == null ? "" : httpsURL; @@ -130,127 +125,244 @@ public class WxAuthHelper { } - public static Result isAuth(HttpServletRequest request, HttpServletResponse response, boolean isPayOAuth) throws Exception { + public static Result isAuth(HttpServletRequest request, HttpServletResponse response) throws Exception { String token = request.getParameter("token"); // 前端缓存 String state = request.getParameter("state"); String isUserInfo = request.getParameter("isUserInfo"); - String UID = ParamHelper.filterParamNull(request.getParameter(UNION_ID_NAME), ""); String deState = URLDecoder.decode(Base64Helper.decode(state), "UTF-8"); - String authSessionId = null; - if (WeChatConfig.IS_ENABLE_GMC && WeChatConfig.IS_GMC_SERVER && !isPayOAuth) { // 开启医共体开关 & 是医共体主服务器 & 不是支付授权 - authSessionId = AesWxHelper.decode(request.getHeader(AUTH_SESSION_ID_NAME)); - } + HttpSession session = request.getSession(); + session.setMaxInactiveInterval(SESSION_MAX_INACTIVE_INTERVAL); - log.warn("[授权is_auth] token={}, state={}, isUserInfo={}, authSessionId={}, UID={}, deState={}", token, state, isUserInfo, authSessionId, UID, deState); - if (WeChatConfig.IS_ENABLE_GMC && !WeChatConfig.IS_GMC_SERVER && !isPayOAuth) { // 开启医共体开关 & 不是医共体主服务器 & 不是支付授权 - try { // 请求转发 - String serverDomain = WeChatConfig.getDomain(false, false); - if (deState != null && serverDomain != null && !deState.contains(serverDomain)) { - return Result.error("授权域名不匹配"); - } + Object sessionOpenIdObj = session.getAttribute(OPENID); // 自身openid + String sessionOpenId = sessionOpenIdObj == null ? null : sessionOpenIdObj.toString(); - HttpSession session = request.getSession(); - String sessionId = session.getId(); - - log.info("[认证请求转发] [sessionId:{}]URL:[{}]", sessionId, WeChatConfig.getGMCAuthDomain(isHttpsWithProxy(request), true)); - String data = OkHttpHelper.postFormStr(WeChatConfig.getGMCAuthDomain(isHttpsWithProxy(request), true) + "wx_auth/is_auth", params -> { - params.put("token", token); - params.put("state", state); - params.put("isUserInfo", isUserInfo); - params.put(UNION_ID_NAME, UID); - }, headers -> { - if (!ObjectUtils.isEmpty(sessionId)) { - headers.add(AUTH_SESSION_ID_NAME, AesWxHelper.encode(WeChatConfig.APP_ID + ":" + sessionId)); + AuthTokenData authTokenData = new AuthTokenData(); + String cacheTokenOpenId = authTokenData.decodeToken(token, WeChatConfig.APP_ID); + + log.warn("[授权is_auth] token={}, state={}, isUserInfo={}, deState={}", token, state, isUserInfo, deState); + + String authSessionId = null; + if (WeChatConfig.IS_ENABLE_GMC) { // 开启医共体开关 & 是医共体主服务器 & 不是支付授权 + try { + if (WeChatConfig.IS_GMC_SERVER) { + authSessionId = AesWxHelper.decode(request.getHeader(AUTH_SESSION_ID_NAME)); + + } else { // 请求转发 + String serverDomain = WeChatConfig.getDomain(false, false); + if (deState != null && serverDomain != null && !deState.contains(serverDomain)) { + return Result.error("授权域名不匹配"); } - }); - Result result = Result.dataToResult(data, true); - System.out.println(JsonHelper.toJsonString(result)); - return Result.dataToResult(data, true); + return gmc_server_auth(request, session, state, isUserInfo, cacheTokenOpenId, token, authTokenData, sessionOpenId, authSessionId); + } } catch (Exception e) { - e.printStackTrace(); + ErrorHelper.println(e); return Result.error(e); } } - boolean isFindUserInfo = ("true".equals(isUserInfo)); + if (cacheTokenOpenId != null) { + log.info("[微信token认证] token={}, cacheOpenId={}", token, cacheTokenOpenId); + AuthResultData authResultData = getTokenData(cacheTokenOpenId, token, authTokenData); + return Result.success(authResultData.toResultData()); + } - AuthData authData = new AuthData(); - String cacheOpenid = authData.decodeToken(token, WeChatConfig.APP_ID); - if (cacheOpenid != null) { - log.info("[微信token认证] token={}, openid={}", token, cacheOpenid); - User user = WxCacheHelper.getCacheUser(cacheOpenid); - List patients; - if (user == null) { - patients = new PatientService().queryPatientList(cacheOpenid, null, true); - Cache cache = WxCacheHelper.getUserCacheManager(); - User addCache = new User(); - addCache.setOpenid(cacheOpenid); - addCache.setUnionId(authData.getUnionId()); - addCache.setAvatar(authData.getAvatar()); - addCache.setNickName(authData.getNickName()); - addCache.setPatientList(patients); - cache.put(cacheOpenid, addCache); - } else { - patients = user.getPatientList(); - } + log.info("[微信认证]获取 openid={}, authSessionId={}", sessionOpenId, authSessionId); + if (!ObjectUtils.isEmpty(authSessionId) && ObjectUtils.isEmpty(sessionOpenId)) { + sessionOpenId = WxCacheHelper.findOpenIdBySessionIdCache(authSessionId); + log.info("[微信AID认证]sessionOpenId={}", sessionOpenId); + } - Map map = new HashMap<>(); - map.put("openid", cacheOpenid); - map.put("token", token); - map.put("enOpenId", AesWxHelper.encode(cacheOpenid, true)); - map.put("enUnionId", AesWxHelper.encode(authData.getUnionId(), true)); - map.put("date", new Date()); - map.put("avatar", authData.getAvatar()); - map.put("nickName", authData.getNickName()); - map.put("patients", CodeHelper.get28UUID() + Base64Helper.encode(URLEncoder.encode(JsonHelper.toJsonString(patients), "UTF-8"))); - map.put("enParams", AesMicroHelper.encode(cacheOpenid)); - return Result.success(map); + AuthResultData authResultData = getCacheUserData(request, sessionOpenId, state, isUserInfo, authSessionId); + if (authResultData.hasAuthUrl()) { + return Result.success(authResultData.getAuthUrl()); } + return Result.success(authResultData.toResultData()); + } - HttpSession session = request.getSession(); - Object sessionOpenId = session.getAttribute("openid"); - String openid = sessionOpenId == null ? null : sessionOpenId.toString(); + /** + * 主体服务器认证 + */ + public static Result gmc_server_auth(HttpServletRequest request, HttpSession session, String state, String isUserInfo, + String cacheTokenOpenId, String token, AuthTokenData tokenData, String sessionOpenId, String authSessionId) { + String reqGMCDomain = WeChatConfig.getGMCAuthDomain(isHttpsWithProxy(request), true); // 医共体请求服务地址 + // 自身认证 + boolean hasTokenCache = !ObjectUtils.isEmpty(cacheTokenOpenId); + String openId = hasTokenCache ? cacheTokenOpenId : sessionOpenId; + if (ObjectUtils.isEmpty(openId)) { // 自身认证未完成 + return Result.success(getAuthUrl(request, state, false, null, authSessionId)); + } +// log.info("cacheTokenOpenId={}, sessionOpenId={}", cacheTokenOpenId, sessionOpenId); - log.info("[微信认证] openid={}, authSessionId={}", openid, authSessionId); - if (!ObjectUtils.isEmpty(authSessionId) && ObjectUtils.isEmpty(openid)) { - openid = WxCacheHelper.getOpenIdByAIDCache(authSessionId); - log.warn("[微信AID认证]openid={}", openid); + // 判断是否有主体id + Object sessionGmcOpenId = session.getAttribute(GMC_ID); + String gmcOpenId = sessionGmcOpenId == null ? null : sessionGmcOpenId.toString(); + + if (gmcOpenId == null) { + GMCUser gmcUser = new GMCUserService().queryInfoByOpenId(openId); + if (gmcUser != null) { + gmcOpenId = gmcUser.getGmcOpenId(); + } } - if (openid != null) { - log.info("[微信认证]openid={}", openid); - User user = WxCacheHelper.getCacheUser(openid); - if (user == null) { - return Result.success(getAuthUrl(request, state, isFindUserInfo, UID, authSessionId)); - } else { - if (ObjectUtils.isEmpty(openid)) { - openid = user.getOpenid(); // sessionId认证openid补充 - } + if (!ObjectUtils.isEmpty(gmcOpenId)) { + if (sessionGmcOpenId == null) { + session.setAttribute(GMC_ID, gmcOpenId); } - if (isFindUserInfo) { // 更换授权模式,需更新信息 - if (user.getNickName() == null || user.getAvatar() == null) { - return Result.success(getAuthUrl(request, state, true, UID, authSessionId)); - } + // 查询返回数据 + AuthResultData authResultData = null; + if (hasTokenCache) { + authResultData = getTokenData(openId, token, tokenData); + } + if (authResultData == null) { + authResultData = getCacheUserData(request, sessionOpenId, state, isUserInfo, authSessionId); } + if (authResultData.hasAuthUrl()) { // 授权链接 + return Result.success(authResultData.getAuthUrl()); + } +// repeatPatients(reqGMCDomain, authResultData.getPatientList(), gmcOpenId); // 患者信息去重 + return Result.success(authResultData.toResultData()); + } - Map map = new HashMap<>(); - map.put("openid", openid); - map.put("token", new AuthData().createToken(WeChatConfig.APP_ID, openid, user.getUnionId(), user.getAvatar(), user.getNickName())); - map.put("enOpenId", AesWxHelper.encode(openid, true)); - map.put("enUnionId", AesWxHelper.encode(user.getUnionId(), true)); - map.put("date", new Date()); - map.put("avatar", user.getAvatar()); - map.put("nickName", user.getNickName()); - map.put("patients", CodeHelper.get28UUID() + Base64Helper.encode(URLEncoder.encode(JsonHelper.toJsonString(user.getPatientList()), "UTF-8"))); - map.put("enParams", AesMicroHelper.encode(openid)); - return Result.success(map); + + String sessionId = session.getId(); + log.info("[认证请求转发] [sessionId:{}]URL:[{}]", sessionId, reqGMCDomain); + String resultJson = OkHttpHelper.postFormStr(reqGMCDomain + "wx_auth/is_auth", params -> { + params.put("token", token); + params.put("state", state); + params.put("isUserInfo", "false"); + }, headers -> { + if (!ObjectUtils.isEmpty(sessionId)) { + headers.add(AUTH_SESSION_ID_NAME, AesWxHelper.encode(WeChatConfig.APP_ID + ":" + sessionId)); + } + }); + Result result = Result.dataToResult(resultJson, true); + if (!result.isOK()) { + return result; + } + String dataStr = result.toDataStr(); + if (dataStr != null && !dataStr.contains("{")) { + return Result.success(dataStr); + } + + AuthResultData gmcAuthResultData = result.dataToBean(AuthResultData.class); // 医共体医生 + String enGmcOpenId = gmcAuthResultData.getEnOpenId(); + gmcOpenId = AesWxHelper.decode(enGmcOpenId); // 主体openid + String gmcUUID = AesWxHelper.decode(gmcAuthResultData.getEnGmcUUID()); + + if (!ObjectUtils.isEmpty(gmcOpenId)) { // 授权主体完成认证 + session.setAttribute(GMC_ID, gmcOpenId); + boolean isOK = new GMCUserService().addInfo(sessionOpenId, gmcOpenId, null, gmcUUID); + log.info("[认证联系]添加{} wxOpenId={}, gmcOpenId={}, gmcUUID={}", (isOK ? "成功" : "失败"), sessionOpenId, gmcOpenId, gmcUUID); + + AuthResultData authResultData = getCacheUserData(request, sessionOpenId, state, isUserInfo, authSessionId); + authResultData.setEnGmcOpenId(enGmcOpenId); // 用于绑定传递数据,确保关系记录 + return Result.success(authResultData.toResultData()); + } + return result; + } + + /** + * 从token获取数据 + * + * @param cacheOpenId token中的openid + * @param token token + * @param tokenData token解析出来的数据 + * @return bean + */ + public static AuthResultData getTokenData(String cacheOpenId, String token, AuthTokenData tokenData) { + if (cacheOpenId == null) { + return null; + } + if (tokenData == null) { + return null; + } + log.info("[微信token认证] token={}, cacheOpenId={}", token, cacheOpenId); + User user = WxCacheHelper.getCacheUser(cacheOpenId); + List patients; + if (user == null) { + patients = new PatientService().queryPatientList(cacheOpenId, null, true); + Cache cache = WxCacheHelper.getUserCacheManager(); + User addCache = new User(); + addCache.setOpenid(cacheOpenId); + addCache.setUnionId(tokenData.getUnionId()); + addCache.setAvatar(tokenData.getAvatar()); + addCache.setNickName(tokenData.getNickName()); + addCache.setPatientList(patients); + cache.put(cacheOpenId, addCache); + } else { + patients = user.getPatientList(); } - return Result.success(getAuthUrl(request, state, isFindUserInfo, UID, authSessionId)); + AuthResultData authResultData = new AuthResultData(); + authResultData.setDate(new Date()); + authResultData.setOpenid(cacheOpenId); + authResultData.setToken(token); + authResultData.setEnOpenId(AesWxHelper.encode(cacheOpenId, true)); + authResultData.setEnUnionId(AesWxHelper.encode(tokenData.getUnionId(), true)); + authResultData.setNickName(tokenData.getNickName()); + authResultData.setAvatar(tokenData.getAvatar()); + authResultData.setPatientList(patients); + authResultData.setEnParams(AesMicroHelper.encode(cacheOpenId)); + authResultData.setEnGmcUUID(AesWxHelper.encode(CodeHelper.get32UUID())); + return authResultData; } + public static AuthResultData getCacheUserData(HttpServletRequest request, String openId, String state, String isUserInfo, String authSessionId) { + log.info("[微信认证]openid={}", openId); + AuthResultData authResultData = new AuthResultData(); + boolean isFindUserInfo = ("true".equals(isUserInfo)); + if (openId == null) { + authResultData.setAuthUrl(getAuthUrl(request, state, isFindUserInfo, null, authSessionId)); + return authResultData; + } + + User user = WxCacheHelper.getCacheUser(openId); + if (user == null) { + authResultData.setAuthUrl(getAuthUrl(request, state, isFindUserInfo, null, authSessionId)); + return authResultData; + } else { + if (ObjectUtils.isEmpty(openId)) { + openId = user.getOpenid(); // sessionId认证openid补充 + } + } + + if (isFindUserInfo) { // 更换授权模式,需更新信息 + if (user.getNickName() == null || user.getAvatar() == null) { + authResultData.setAuthUrl(getAuthUrl(request, state, true, null, authSessionId)); + return authResultData; + } + } + + authResultData.setDate(new Date()); + authResultData.setOpenid(openId); + authResultData.setToken(new AuthTokenData().createToken(WeChatConfig.APP_ID, openId, user.getUnionId(), user.getAvatar(), user.getNickName())); + authResultData.setEnOpenId(AesWxHelper.encode(openId, true)); + authResultData.setEnUnionId(AesWxHelper.encode(user.getUnionId(), true)); + authResultData.setNickName(user.getNickName()); + authResultData.setAvatar(user.getAvatar()); + authResultData.setPatientList(user.getPatientList()); + authResultData.setEnParams(AesMicroHelper.encode(openId)); + authResultData.setEnGmcUUID(AesWxHelper.encode(CodeHelper.get32UUID())); + return authResultData; + } + + public List repeatPatients(String reqDomain, List patientList, String gmcOpenId) throws Exception { + // 数据去重 + JsonResult jsonResult = postForm(reqDomain + "patient/authGMCPatients", params -> { + params.put("gmcOpenId", AesWxHelper.encode(gmcOpenId, true)); + }, headers -> { + headers.add("gmcOpenId", AesWxHelper.encode(gmcOpenId, true)); + }); + if (jsonResult.success()) { + List gmcPatientList = jsonResult.dataMapGetNodeToList(Patient.class); +// authResultData.setPatientList(patientList); + } + return patientList; + } + + private static final String OAUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WeChatConfig.APP_ID + "&redirect_uri="; private static String getAuthUrl(HttpServletRequest request, String state, boolean isFindUserInfo, String UID, String SID) { @@ -263,10 +375,10 @@ public class WxAuthHelper { String api = isFindUserInfo ? "u_auth" : "b_auth"; String scope = isFindUserInfo ? "snsapi_userinfo" : "snsapi_base"; - UID = toURLParam(UNION_ID_NAME, UID); + String enUID = toURLParam(GMC_ID, AesWxHelper.encode(UID, true)); String enSID = toURLParam(AUTH_SESSION_ID_NAME, AesWxHelper.encode(SID, true)); - String params = enSID + UID; + String params = enSID + enUID; try { params = ObjectUtils.isEmpty(params) ? "" : URLEncoder.encode(params, "UTF-8"); log.warn("[认证链接参数] params={}", params); @@ -333,7 +445,11 @@ public class WxAuthHelper { } - // // 医共体开启 & 不是支付授权 + public static JsonResult postForm(String url, OkHttpHelper.MapParams params, OkHttpHelper.Header header) { + return OkHttpHelper.postForm(url, params, header, JsonResultEnum.SYS_MICRO); + } + +// // 医共体开启 & 不是支付授权 // private static boolean isAuthGMC(boolean isPayOAuth) { // return WeChatConfig.IS_ENABLE_GMC && !isPayOAuth; // } diff --git a/src/main/java/com/ynxbd/wx/wxfactory/WxCacheHelper.java b/src/main/java/com/ynxbd/wx/wxfactory/WxCacheHelper.java index 3a0b050..4b3cfe6 100644 --- a/src/main/java/com/ynxbd/wx/wxfactory/WxCacheHelper.java +++ b/src/main/java/com/ynxbd/wx/wxfactory/WxCacheHelper.java @@ -2,7 +2,6 @@ package com.ynxbd.wx.wxfactory; import com.ynxbd.common.bean.User; import com.ynxbd.common.config.EhCacheConfig; -import com.ynxbd.wx.config.WeChatConfig; import com.ynxbd.wx.wxfactory.base.auth.models.AccessToken; import com.ynxbd.wx.wxfactory.base.auth.models.JsapiTicket; import lombok.extern.slf4j.Slf4j; @@ -20,12 +19,12 @@ public class WxCacheHelper { private static Cache JSAPI_TICKET_CACHE; - private static Cache AID_CACHE; + private static Cache AUTH_SESSION_ID_CACHE; static { createUserCacheManager(); createAccessTokenCache(); - createAuthSessionIdManager(); + createAuthSessionIdCacheManager(); } @@ -143,34 +142,34 @@ public class WxCacheHelper { } - private synchronized static void createAuthSessionIdManager() { - if (AID_CACHE == null) { - AID_CACHE = EhCacheConfig.createCacheTTL(String.class, String.class, "auth_session_id_cache", (3600L)); // 一个小时 + private synchronized static void createAuthSessionIdCacheManager() { + if (AUTH_SESSION_ID_CACHE == null) { + AUTH_SESSION_ID_CACHE = EhCacheConfig.createCacheTTL(String.class, String.class, "auth_session_id_cache", (3600L)); // 一个小时 } } - public static String getOpenIdByAIDCache(String authSessionId) { - if (AID_CACHE == null) { - createAuthSessionIdManager(); + public static String findOpenIdBySessionIdCache(String authSessionId) { + if (AUTH_SESSION_ID_CACHE == null) { + createAuthSessionIdCacheManager(); } if (ObjectUtils.isEmpty(authSessionId)) { return null; } - if (AID_CACHE.containsKey(authSessionId)) { - return AID_CACHE.get(authSessionId); + if (AUTH_SESSION_ID_CACHE.containsKey(authSessionId)) { + return AUTH_SESSION_ID_CACHE.get(authSessionId); } return null; } - public static void putOpenIdToAIDCache(String authSessionId, String openId) { - if (AID_CACHE == null) { - createAuthSessionIdManager(); + public static void putOpenIdCacheToSessionIdCache(String authSessionId, String openId) { + if (AUTH_SESSION_ID_CACHE == null) { + createAuthSessionIdCacheManager(); } if (ObjectUtils.isEmpty(authSessionId)) { return; } - if (!AID_CACHE.containsKey(authSessionId)) { - AID_CACHE.put(authSessionId, openId); + if (!AUTH_SESSION_ID_CACHE.containsKey(authSessionId)) { + AUTH_SESSION_ID_CACHE.put(authSessionId, openId); } } diff --git a/src/main/java/com/ynxbd/wx/wxfactory/base/auth/models/AuthResultData.java b/src/main/java/com/ynxbd/wx/wxfactory/base/auth/models/AuthResultData.java new file mode 100644 index 0000000..bb61b4b --- /dev/null +++ b/src/main/java/com/ynxbd/wx/wxfactory/base/auth/models/AuthResultData.java @@ -0,0 +1,65 @@ +package com.ynxbd.wx.wxfactory.base.auth.models; + +import com.ynxbd.common.bean.Patient; +import com.ynxbd.common.helper.common.Base64Helper; +import com.ynxbd.common.helper.common.CodeHelper; +import com.ynxbd.common.helper.common.JsonHelper; +import com.ynxbd.wx.wxfactory.AesWxHelper; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; + +import java.io.Serializable; +import java.net.URLEncoder; +import java.util.Date; +import java.util.List; + +@Slf4j +@Getter +@Setter +@ToString +@NoArgsConstructor +public class AuthResultData implements Serializable { + private static final long serialVersionUID = 20251218170700001L; + private Date date; + private String token; + + private String openid; + private String enOpenId; + private String enUnionId; + private String avatar; + private String nickName; + private String patients; + + private List patientList; + + private String enParams; + + private String authUrl; + + private String enGmcUUID; + private String enGmcOpenId; + + public boolean hasAuthUrl() { + return !ObjectUtils.isEmpty(authUrl); + } + + // 清除无需返回的数据 + public AuthResultData toResultData() { + try { + this.patients = CodeHelper.get28UUID() + Base64Helper.encode(URLEncoder.encode(JsonHelper.toJsonString(this.patientList), "UTF-8")); + } catch (Exception e) { + log.error(e.getMessage()); + } + this.patientList = null; + this.authUrl = null; + if (ObjectUtils.isEmpty(this.enGmcUUID)) { + this.enGmcUUID = AesWxHelper.encode(CodeHelper.get32UUID()); + } + return this; + } + +} diff --git a/src/main/java/com/ynxbd/wx/wxfactory/base/auth/models/AuthData.java b/src/main/java/com/ynxbd/wx/wxfactory/base/auth/models/AuthTokenData.java similarity index 80% rename from src/main/java/com/ynxbd/wx/wxfactory/base/auth/models/AuthData.java rename to src/main/java/com/ynxbd/wx/wxfactory/base/auth/models/AuthTokenData.java index 4c28069..c74b41d 100644 --- a/src/main/java/com/ynxbd/wx/wxfactory/base/auth/models/AuthData.java +++ b/src/main/java/com/ynxbd/wx/wxfactory/base/auth/models/AuthTokenData.java @@ -18,7 +18,7 @@ import java.io.Serializable; @ToString @NoArgsConstructor @Slf4j -public class AuthData implements Serializable { +public class AuthTokenData implements Serializable { private static final long serialVersionUID = 202511101525001L; private String appId; @@ -53,29 +53,29 @@ public class AuthData implements Serializable { if (ObjectUtils.isEmpty(dataJson)) { return null; } - AuthData authData = JsonHelper.parseObject(dataJson, AuthData.class); - if (authData == null) { + AuthTokenData authTokenData = JsonHelper.parseObject(dataJson, AuthTokenData.class); + if (authTokenData == null) { return null; } - String cacheOpenid = authData.getOpenId(); + String cacheOpenid = authTokenData.getOpenId(); if (ObjectUtils.isEmpty(cacheOpenid)) { return null; } - String cacheAppId = authData.getAppId(); + String cacheAppId = authTokenData.getAppId(); if (!cacheAppId.equals(serverAppId)) { log.warn("[微信认证]token中的AppId和配置的不一致"); return null; } - String cacheTime = authData.getCreateTime(); + String cacheTime = authTokenData.getCreateTime(); Boolean hasValidity = DateHelper.inDateRangeByDay(-3, cacheTime); if (hasValidity != null && hasValidity) { // 在有效期内 this.openId = cacheOpenid; - this.unionId = authData.getUnionId(); - this.appId = authData.getAppId(); + this.unionId = authTokenData.getUnionId(); + this.appId = authTokenData.getAppId(); - this.avatar = authData.getAvatar(); - this.nickName = authData.getNickName(); + this.avatar = authTokenData.getAvatar(); + this.nickName = authTokenData.getNickName(); this.createTime = cacheTime; return cacheOpenid; }