fs-danaus
2022-07-26 b0744c82dbb0bb2a15763dbbd83a924f54312821
提交 | 用户 | 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 }