提交 | 用户 | age
|
a6a76f
|
1 |
package com.yc.sdk.weixincp.action; |
F |
2 |
|
|
3 |
import com.google.gson.JsonObject; |
|
4 |
import com.yc.action.BaseAction; |
|
5 |
import com.yc.action.login.LoginAction; |
|
6 |
import com.yc.entity.DataSourceEntity; |
|
7 |
import com.yc.entity.UserAccountEntity; |
|
8 |
import com.yc.factory.FactoryBean; |
|
9 |
import com.yc.multiData.MultiDataSource; |
|
10 |
import com.yc.multiData.SpObserver; |
|
11 |
import com.yc.sdk.jedis.KryoUtils; |
|
12 |
import com.yc.sdk.password.action.ChangePassword; |
|
13 |
import com.yc.sdk.shopping.entity.CustomerEntity; |
|
14 |
import com.yc.sdk.shopping.service.register.AccountIfc; |
|
15 |
import com.yc.sdk.shopping.util.SettingKey; |
|
16 |
import com.yc.sdk.weixinmp.entity.WxSessionEntity; |
|
17 |
import com.yc.service.demo.DemoIfc; |
|
18 |
import com.yc.service.user.UserAccountServiceIfc; |
|
19 |
import com.yc.utils.SessionKey; |
ba6749
|
20 |
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo; |
F |
21 |
import me.chanjar.weixin.common.error.WxErrorException; |
|
22 |
import me.chanjar.weixin.cp.api.WxCpService; |
|
23 |
import me.chanjar.weixin.cp.bean.WxCpOauth2UserInfo; |
|
24 |
import me.chanjar.weixin.cp.bean.WxCpUser; |
|
25 |
import me.chanjar.weixin.mp.bean.result.WxMpUser; |
|
26 |
import org.slf4j.Logger; |
|
27 |
import org.slf4j.LoggerFactory; |
|
28 |
import org.springframework.beans.factory.annotation.Autowired; |
|
29 |
import org.springframework.stereotype.Controller; |
|
30 |
import org.springframework.web.bind.annotation.RequestMapping; |
|
31 |
import redis.clients.jedis.Jedis; |
|
32 |
import redis.clients.jedis.JedisPool; |
|
33 |
|
|
34 |
import javax.servlet.http.HttpServletRequest; |
|
35 |
import javax.servlet.http.HttpServletResponse; |
|
36 |
import javax.servlet.http.HttpSession; |
a6a76f
|
37 |
|
F |
38 |
/** |
|
39 |
* |
|
40 |
* @author |
|
41 |
* @updatedBy |
|
42 |
* @updateTime |
|
43 |
*/ |
|
44 |
@Controller("CpAuthSession") |
|
45 |
public class CpAuthSession extends BaseAction implements WxAuthSessionIfc { |
|
46 |
protected final Logger log = LoggerFactory.getLogger(this.getClass()); |
|
47 |
|
|
48 |
@Autowired |
|
49 |
DemoIfc demo; |
|
50 |
@Autowired |
|
51 |
private UserAccountServiceIfc userAccountService; |
|
52 |
@Autowired |
|
53 |
LoginAction loginAction; |
|
54 |
@Autowired |
|
55 |
AccountIfc accountIfc; |
|
56 |
// @Autowired |
|
57 |
// JedisPool jedisPool; |
|
58 |
|
|
59 |
// protected WxCpService wxCpService; |
|
60 |
// protected DataSourceEntity corpEntity ; |
|
61 |
static final JedisPool jedisPool; |
|
62 |
static { |
|
63 |
jedisPool = (JedisPool) FactoryBean.getBean("jedisPool"); |
|
64 |
} |
|
65 |
|
|
66 |
/** |
|
67 |
* 检查企业微信会话是否存在,如果存在,则不用获取 openid (userid ) |
|
68 |
* |
|
69 |
* @param request |
|
70 |
* @param response |
|
71 |
*/ |
|
72 |
@RequestMapping("/wx/CpCheckSession.do") |
|
73 |
public void cpCheckSession(HttpServletRequest request, HttpServletResponse response) { |
|
74 |
String corpId = (request.getSession().getAttribute(SessionKey.WEIXIN_CORPID) == null ? "" |
|
75 |
: (String) request.getSession().getAttribute(SessionKey.WEIXIN_CORPID)); |
|
76 |
JsonObject json = new JsonObject(); |
|
77 |
// JsonObject errJson = new JsonObject(); |
|
78 |
if (corpId != null && !"".equals(corpId)) { |
|
79 |
json.addProperty("state", "success"); |
|
80 |
} else { |
|
81 |
json.addProperty("state", "failed"); |
|
82 |
} |
|
83 |
this.printJson(response, json.toString()); |
|
84 |
return; |
|
85 |
} |
|
86 |
|
|
87 |
/** |
|
88 |
* 获取微信授权URL |
|
89 |
* |
|
90 |
* @param request |
|
91 |
* @return |
|
92 |
* @throws Exception |
|
93 |
*/ |
|
94 |
@Override |
|
95 |
public String getAuthorizationUrl(HttpServletRequest request) throws Exception { |
|
96 |
String corpId = request.getParameter(SessionKey.WEIXIN_CORPID); |
|
97 |
String appCode = request.getParameter(SettingKey.APPCODE); // 如果是第三方托管,则 appCode 一定有值传过来,如 : ai ,boss ... ,此值在 |
|
98 |
// wx-suite-component-setting.xml 文件中设置 |
|
99 |
DataSourceEntity corpEntity = MultiDataSource.getDataSourceMapByCorpId(corpId); |
|
100 |
// SpObserver.setDBtoDemo(); |
|
101 |
|
|
102 |
if (corpEntity == null) { |
|
103 |
new Exception("提供的CorpId无效【" + (corpId == null ? "" : corpId) + "】"); |
|
104 |
} |
|
105 |
WxCpService wxCpService = null; |
|
106 |
try { |
|
107 |
if (appCode != null && !"".equals(appCode)) { |
|
108 |
wxCpService = CpServiceInit.getWxCpService(corpId, appCode); // 第三方托管方式 |
|
109 |
} else { |
|
110 |
wxCpService = CpServiceInit.getWxCpService(corpEntity); // 非第三方托管方式 |
|
111 |
} |
|
112 |
|
|
113 |
String queryString = request.getQueryString(); |
|
114 |
String reqUri = request.getRequestURI(); |
|
115 |
String hostUrl = SettingKey.getHostUrl(request); |
|
116 |
String redirectUri = hostUrl + reqUri |
|
117 |
+ (queryString != null && !"".equals(queryString) ? "?" + queryString : ""); |
|
118 |
|
|
119 |
String wxAuthUrl = wxCpService.getOauth2Service().buildAuthorizationUrl(redirectUri, "123"); |
|
120 |
// System.out.println("getAuthorizationUrl():wxAuthUrl=" + wxAuthUrl); |
|
121 |
return wxAuthUrl; |
|
122 |
} catch (Exception e) { |
|
123 |
throw e; |
|
124 |
} |
|
125 |
} |
|
126 |
|
|
127 |
/** |
|
128 |
* 获取企业号授权用户 |
|
129 |
* |
|
130 |
* @param request |
|
131 |
* @param code |
|
132 |
* @return |
|
133 |
* @throws Exception |
|
134 |
*/ |
|
135 |
@Override |
|
136 |
public WxCpUser getAuthorizationCpUser(HttpServletRequest request, String code) throws Exception { |
|
137 |
WxCpUser wxCpUser = null; |
|
138 |
try (Jedis jedis = jedisPool.getResource()) { |
|
139 |
// 检查此 code 是否拉取过用户信息,如果拉取过,则会存在于 redis 中 (5分钟内有效) |
|
140 |
// 这个程序主要是为了避开微信APP的一个BUG,因为微信APP是内置QQ浏览器,这个QQ浏览器有时候会重复推送同一个链接,所以导致 code 被重复消费造成 |
|
141 |
// 40029 invalid code 错误, https://open.work.weixin.qq.com/devtool/query?e=40029 |
|
142 |
String wxCpUserStr = jedis.get("WxAuthorizeCode:" + code); |
|
143 |
if (wxCpUserStr != null) { |
|
144 |
wxCpUser = KryoUtils.deserializationObject(wxCpUserStr, WxCpUser.class); |
|
145 |
if (wxCpUser != null) { |
|
146 |
// System.out.println(this.getClass()+" 成功从 redis 取到 wxCpUser 信息 userid=" |
|
147 |
// +wxCpUser.getUserId()+" " + wxCpUser.getName()+" code=" + code ); |
|
148 |
return wxCpUser; |
|
149 |
} |
|
150 |
} |
|
151 |
} catch (Exception e) { |
|
152 |
throw e; |
|
153 |
} |
|
154 |
// String code = request.getParameter("code"); //由微信传过来的 userid |
|
155 |
String corpId = request.getParameter(SessionKey.WEIXIN_CORPID); |
|
156 |
String appCode = request.getParameter(SettingKey.APPCODE); // 如果是第三方托管,则 appCode 一定有值传过来,如 : ai ,boss ... ,此值在 |
|
157 |
// wx-suite-component-setting.xml 文件中设置 |
|
158 |
DataSourceEntity corpEntity = MultiDataSource.getDataSourceMapByCorpId(corpId); |
|
159 |
|
|
160 |
WxCpService wxCpService = null; |
|
161 |
try (Jedis jedis = jedisPool.getResource()) { |
|
162 |
if (appCode != null && !"".equals(appCode)) { |
|
163 |
wxCpService = CpServiceInit.getWxCpService(corpId, appCode); // 第三方托管方式 |
|
164 |
} else { |
|
165 |
wxCpService = CpServiceInit.getWxCpService(corpEntity); // 非第三方托管方式 |
|
166 |
} |
|
167 |
|
|
168 |
String userid = null; |
|
169 |
try { |
|
170 |
WxCpOauth2UserInfo userids = wxCpService.getOauth2Service().getUserInfo(code); // wxCpService.getOauth2Service().getUserInfo(code) |
|
171 |
// ; |
|
172 |
userid = userids.getUserId(); |
|
173 |
} catch (WxErrorException e) { |
|
174 |
// if (e.getError().getErrorCode() == 40029) { |
|
175 |
// throw new Exception("在当前页面停留太久了,请刷新重试!"); |
|
176 |
// } else { |
|
177 |
// throw new Exception("非法访问,错误代码:" + e.getError().getErrorCode()+",错误信息:"+e.getError().getErrorMsg()); |
|
178 |
// } |
|
179 |
throw e; |
|
180 |
} catch (Exception e) { |
|
181 |
throw e; |
|
182 |
} |
|
183 |
|
|
184 |
try { |
|
185 |
wxCpUser = wxCpService.getUserService().getById(userid); |
|
186 |
} catch (WxErrorException e) { |
|
187 |
throw new Exception( |
|
188 |
"获取微信用户时失败,错误代码:" + e.getError().getErrorCode() + ",错误描述:" + e.getError().getErrorMsg()); |
|
189 |
} |
|
190 |
if (wxCpUser.getEnable() != null && wxCpUser.getEnable() == 0) { |
|
191 |
// log.error("【" + wxUserInfo.getUserId() +"】【" + |
|
192 |
// wxUserInfo.getName()+"】的微信账号已经被禁用,禁止访问!"); |
|
193 |
throw new Exception("您的微信账号【" + wxCpUser.getName() + "】已经被禁用,禁止访问!"); |
|
194 |
} |
|
195 |
if (wxCpUser.getStatus() != null && wxCpUser.getStatus() == 2) { |
|
196 |
throw new Exception("您的微信账号【" + wxCpUser.getName() + "】已经被冻结,禁止访问!"); |
|
197 |
} |
|
198 |
if (wxCpUser.getStatus() != null && wxCpUser.getStatus() == 4) { |
|
199 |
throw new Exception("您的微信账号【" + wxCpUser.getName() + "】还未关注,禁止访问!"); |
|
200 |
} |
|
201 |
|
|
202 |
// 将 code 获取的对象 wxCpUser 保存到 redis ,避免 code 重复消费造成 40029 invalid code 错误, |
|
203 |
// https://open.work.weixin.qq.com/devtool/query?e=40029 |
|
204 |
// byte[] objStr = KryoUtils.serialize(wxCpUser); |
|
205 |
String objStr = KryoUtils.serializationObject(wxCpUser); |
|
206 |
jedis.set("WxAuthorizeCode:" + code, objStr); |
|
207 |
jedis.expire("WxAuthorizeCode:" + code, 60 * 5); |
|
208 |
|
|
209 |
return wxCpUser; |
|
210 |
} catch (Exception e) { |
|
211 |
throw e; |
|
212 |
} |
|
213 |
} |
|
214 |
|
|
215 |
/** |
|
216 |
* 按企业号 userid 登录系统 |
|
217 |
* |
|
218 |
* @param request |
|
219 |
* @param response |
|
220 |
* @param wxCpUser |
|
221 |
* @return |
|
222 |
* @throws Exception |
|
223 |
*/ |
|
224 |
@Override |
|
225 |
public boolean loginFromWxCpUser(HttpServletRequest request, HttpServletResponse response, WxCpUser wxCpUser) |
|
226 |
throws Exception { |
|
227 |
HttpSession session = request.getSession(); |
|
228 |
if (wxCpUser == null) |
|
229 |
return false; |
|
230 |
String corpId = request.getParameter(SessionKey.WEIXIN_CORPID); |
|
231 |
DataSourceEntity corpEntity = MultiDataSource.getDataSourceMapByCorpId(corpId); |
|
232 |
UserAccountEntity userAccount = null; |
|
233 |
try { |
|
234 |
SpObserver.setDBtoInstance("_" + corpEntity.getDbId());// 切换数据源 |
|
235 |
userAccount = userAccountService.getUserInfoByWeiXinCorpUserId(wxCpUser.getUserId()); |
|
236 |
} finally { |
|
237 |
SpObserver.setDBtoInstance(); |
|
238 |
} |
|
239 |
|
|
240 |
if (userAccount == null) { |
|
241 |
throw new Exception("错误:未找到您的ERP系统账号,请与系统管理员联系,企业微信账号【" + wxCpUser.getUserId() + "】,请在 9901 功能号中维护"); |
|
242 |
} |
|
243 |
|
|
244 |
String password = null; |
|
245 |
try { |
|
246 |
password = ChangePassword.getDecryptPassword(userAccount.getPassword()); |
|
247 |
|
|
248 |
} catch (Exception e) { |
|
249 |
String message = e.getCause() != null ? e.getCause().getMessage() |
|
250 |
: e.getMessage() + " 原因可能是密码未加密,请在9901中为用户【" + userAccount.getUserCode() + "】【" |
|
251 |
+ userAccount.getUserName() + "】预先设置随机密码"; |
|
252 |
this.log.debug(message); |
|
253 |
throw new IllegalArgumentException(message); |
|
254 |
} |
|
255 |
request.setAttribute("pwd", password); // 暂时保存密码,自动登录ERP系统时需要用到 , by johns wang, 2018-11-12 |
|
256 |
|
|
257 |
// 手机设备号(由微信在安装时随机生成,删除重装会改变,升级不受影响),如果重新安装,则需要重新授权 |
|
258 |
// String weiDeviceID = (String) userAccount.get("WeiDeviceID") ; |
|
259 |
// if (weiDeviceID == null || ! deviceid.equals(weiDeviceID)) { |
|
260 |
// String redirectUri = corpEntity.getCorpURL() + "/weixin/reg.jsp?CorpId="+corpId+"&code="+code ; ; |
|
261 |
// String wxAuthUrl = wxCpService.oauth2buildAuthorizationUrl( redirectUri, "123") ; |
|
262 |
// this.print(response, "系统检测到您更换了设备,需要重新验证您的身份!<script>window.location='"+wxAuthUrl+"' ;</script>"); |
|
263 |
// return ; |
|
264 |
// } |
|
265 |
try (Jedis jedis = jedisPool.getResource()) { |
|
266 |
WxSessionEntity wxSessionEntity = new WxSessionEntity(); |
|
267 |
wxSessionEntity.setUserCode(wxCpUser.getUserId()); |
|
268 |
wxSessionEntity.setUserName(wxCpUser.getName()); |
|
269 |
// 如果是客户,则设置客户登录时的选项,适用于 导购 网店模块,added by Johns Wang, 2016-03-01 |
|
270 |
if (userAccount.getLogonType() != null && userAccount.getLogonType().toString().equals("1")) { |
|
271 |
CustomerEntity customerEntity = accountIfc.getLoginInfoByCltCode(wxCpUser.getUserId(), |
|
272 |
wxCpUser.getUserId(), wxCpUser.getUserId()); |
|
273 |
; |
|
274 |
/* |
|
275 |
* session.setAttribute(SessionKey.USERCODE,customerEntity.getCltCode()); |
|
276 |
* session.setAttribute(SessionKey.USERNAME,customerEntity.getCltName()); |
|
277 |
* |
|
278 |
* session.setAttribute(SettingKey.CLTCODE, customerEntity.getCltCode()); |
|
279 |
* session.setAttribute(SettingKey.CLTNAME, customerEntity.getCltName()); |
|
280 |
* session.setAttribute(SettingKey.CLTTEL, customerEntity.getTel()); |
|
281 |
* session.setAttribute(SettingKey.CLTEMAIL, customerEntity.getEmail()); |
|
282 |
* session.setAttribute(SettingKey.COUNTRY, customerEntity.getCountryZoneId()); |
|
283 |
* session.setAttribute(SettingKey.PROVINCE, |
|
284 |
* customerEntity.getProvinceZoneId()); |
|
285 |
* session.setAttribute(SettingKey.POSTCODE, customerEntity.getPostCode()); |
|
286 |
*/ |
|
287 |
wxSessionEntity.setUserCode(customerEntity.getCltCode()); |
|
288 |
wxSessionEntity.setUserName(customerEntity.getCltName()); |
|
289 |
wxSessionEntity.setCltCode(customerEntity.getCltCode()); |
|
290 |
wxSessionEntity.setCltName(customerEntity.getCltName()); |
|
291 |
wxSessionEntity.setCltTel(customerEntity.getTel()); |
|
292 |
wxSessionEntity.setEmail(customerEntity.getEmail()); |
|
293 |
wxSessionEntity.setCountry(customerEntity.getCountryZoneId()); |
|
294 |
wxSessionEntity.setProvince(customerEntity.getProvinceZoneId()); |
|
295 |
wxSessionEntity.setPostCode(customerEntity.getPostCode()); |
|
296 |
|
|
297 |
} |
b0744c
|
298 |
//by danaus 2022/7/26 16:35 |
F |
299 |
session.setAttribute(SessionKey.USER_LOGIN_TYPE, SessionKey.USER_LOGIN_TYPE_MINIAPP);//miniapp 小程序类型 |
ba6749
|
300 |
loginAction.processLoginUserToSessionV2(request.getRemoteAddr(), corpEntity.getDbId() + "", request, |
a6a76f
|
301 |
userAccount); |
b0744c
|
302 |
|
a6a76f
|
303 |
wxSessionEntity.setShoppingDbId(corpEntity.getDbId() + ""); |
F |
304 |
wxSessionEntity.setWx("1"); |
|
305 |
wxSessionEntity.setCorpId(corpId); |
|
306 |
wxSessionEntity.setOpenId(wxCpUser.getUserId()); |
|
307 |
wxSessionEntity.setNickName(wxCpUser.getName()); |
|
308 |
wxSessionEntity.setHeadImgUrl(wxCpUser.getAvatar()); |
|
309 |
WxSessionEntity.updateValueToSession(session, wxSessionEntity); |
|
310 |
|
|
311 |
// 保存会话 session 内容到 redis |
|
312 |
|
|
313 |
// byte[] objStr = KryoUtils.serialize(wxSessionEntity); |
|
314 |
String objStr = KryoUtils.serializationObject(wxSessionEntity); |
|
315 |
jedis.set("wxSession:" + corpEntity.getCorpId() + ":" + session.getId(), objStr); |
|
316 |
jedis.expire("wxSession:" + corpEntity.getCorpId() + ":" + session.getId(), 60 * 60 * 24); |
|
317 |
|
|
318 |
} catch (Exception e) { |
|
319 |
//e.printStackTrace(); |
|
320 |
throw e ; |
|
321 |
} |
|
322 |
return true; |
|
323 |
} |
|
324 |
|
|
325 |
@Override |
bff6b6
|
326 |
public WxOAuth2UserInfo getAuthorizationMpUser(HttpServletRequest request, String code) throws Exception { |
a6a76f
|
327 |
// TODO Auto-generated method stub |
F |
328 |
return null; |
|
329 |
} |
|
330 |
|
|
331 |
@Override |
|
332 |
public boolean loginFromWxMpUser(HttpServletRequest request, HttpServletResponse response, WxMpUser wxMpUser) |
|
333 |
throws Exception { |
|
334 |
// TODO Auto-generated method stub |
|
335 |
return false; |
|
336 |
} |
|
337 |
|
|
338 |
} |