|
@@ -0,0 +1,216 @@
|
|
|
+package com.ruoyi.framework.web.service;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.alibaba.fastjson.JSONException;
|
|
|
+import com.ruoyi.common.core.domain.AjaxResult;
|
|
|
+import com.ruoyi.common.core.domain.entity.SysUser;
|
|
|
+import com.ruoyi.common.core.domain.model.LoginBody;
|
|
|
+import com.ruoyi.common.core.domain.model.LoginUser;
|
|
|
+import com.ruoyi.common.core.redis.RedisCache;
|
|
|
+import com.ruoyi.common.utils.StringUtils;
|
|
|
+import com.ruoyi.common.utils.wechat.AESUtils;
|
|
|
+import com.ruoyi.common.utils.wechat.AccessTokenUtils;
|
|
|
+import com.ruoyi.system.service.impl.SysUserServiceImpl;
|
|
|
+import lombok.SneakyThrows;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import okhttp3.*;
|
|
|
+import org.apache.commons.codec.binary.Base64;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.security.authentication.AuthenticationManager;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.io.UnsupportedEncodingException;
|
|
|
+import java.security.InvalidAlgorithmParameterException;
|
|
|
+import java.util.Collection;
|
|
|
+import java.util.Objects;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 登录校验方法
|
|
|
+ *
|
|
|
+ * @author ruoyi
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+public class WechatService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private TokenService tokenService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysUserServiceImpl sysUserService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private AuthenticationManager authenticationManager;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private RedisCache redisCache;
|
|
|
+ //发送模板路径
|
|
|
+ @Value("${wechat.templateMsgUrl}")
|
|
|
+ private String templateMsgUrl;
|
|
|
+ // 模板id
|
|
|
+// @Value("${wechat.templateId}")
|
|
|
+ private String templateId;
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 微信生成token
|
|
|
+ *
|
|
|
+ * @param loginBody code
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public AjaxResult login(LoginBody loginBody) {
|
|
|
+ if (StringUtils.isNotEmpty(loginBody.getToken())) {
|
|
|
+ // 仅仅获取token
|
|
|
+ SysUser sysUser = sysUserService.selectUserByPhone(loginBody);
|
|
|
+ if (StringUtils.isNull(sysUser)) {
|
|
|
+ return AjaxResult.error("未找到用户信息,请确认");
|
|
|
+ }
|
|
|
+ // 生成token
|
|
|
+ LoginUser loginUser = new LoginUser();
|
|
|
+ loginUser.setUser(sysUser);
|
|
|
+ String token = tokenService.wechatCreateToken(loginUser);
|
|
|
+ if (StringUtils.isEmpty(token)) {
|
|
|
+ return AjaxResult.error("生成token失败");
|
|
|
+ }
|
|
|
+ LoginBody body = new LoginBody();
|
|
|
+ body.setToken(token);
|
|
|
+ body.setPhonenumber(sysUser.getPhonenumber());
|
|
|
+ return AjaxResult.success(body);
|
|
|
+ }
|
|
|
+ // 获取openId、sessionKey
|
|
|
+ SysUser user = sysUserService.weChatProgramLogin(loginBody);
|
|
|
+ if (StringUtils.isNull(user)) {
|
|
|
+ return AjaxResult.error("获取OpenId失败");
|
|
|
+ }
|
|
|
+ // 解密获取手机号
|
|
|
+ try {
|
|
|
+ AjaxResult ajaxResult = decodeUserInfo(loginBody.getPhonenumber(), loginBody.getIv(), user.getSessionKey());
|
|
|
+ String code = ajaxResult.get("code").toString();
|
|
|
+ if ("500".equals(code)) {
|
|
|
+ return ajaxResult;
|
|
|
+ }
|
|
|
+ user.setPhonenumber(ajaxResult.get("data").toString());
|
|
|
+ } catch (UnsupportedEncodingException e) {
|
|
|
+ log.info("解析手机号UnsupportedEncodingException异常:" + e);
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (InvalidAlgorithmParameterException e) {
|
|
|
+ log.info("解析手机号InvalidAlgorithmParameterException异常:" + e);
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ LoginUser loginUser = sysUserService.createOrUpdateUser(user);
|
|
|
+ if (StringUtils.isNull(loginUser)) {
|
|
|
+ return AjaxResult.error("未找到用户信息");
|
|
|
+ }
|
|
|
+ // 生成token
|
|
|
+ String token = tokenService.wechatCreateToken(loginUser);
|
|
|
+ if (StringUtils.isEmpty(token)) {
|
|
|
+ return AjaxResult.error("生成token失败");
|
|
|
+ }
|
|
|
+ LoginBody body = new LoginBody();
|
|
|
+ body.setToken(token);
|
|
|
+ body.setPhonenumber(user.getPhonenumber());
|
|
|
+ return AjaxResult.success(body);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解密小程序用户敏感数据(暂时用于解密手机号)
|
|
|
+ * https://blog.csdn.net/weixin_42771651/article/details/107359620
|
|
|
+ *
|
|
|
+ * @param encryptedData 明文
|
|
|
+ * @param iv 加密算法的初始向量
|
|
|
+ * @param sessionKey 用户秘钥
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public AjaxResult decodeUserInfo(String encryptedData, String iv, String sessionKey
|
|
|
+ ) throws UnsupportedEncodingException, InvalidAlgorithmParameterException, JSONException {
|
|
|
+ //AESUtils微信获取手机号解密工具类
|
|
|
+ AESUtils aes = new AESUtils();
|
|
|
+ //调用AESUtils工具类decrypt方法解密获取json串
|
|
|
+ byte[] resultByte = aes.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(sessionKey), Base64.decodeBase64(iv));
|
|
|
+ //判断返回参数是否为空
|
|
|
+ if (null != resultByte && resultByte.length > 0) {
|
|
|
+ String jsons = new String(resultByte, "UTF-8");
|
|
|
+ JSONObject json = JSONObject.parseObject(jsons);
|
|
|
+ //json解析phoneNumber值
|
|
|
+ String phoneNumber = json.getString("phoneNumber");
|
|
|
+ if (StringUtils.isEmpty(phoneNumber)) {
|
|
|
+ log.info("解析手机号异常:" + json.toJSONString());
|
|
|
+ return AjaxResult.error("解析手机号异常");
|
|
|
+ }
|
|
|
+ return AjaxResult.success("操作成功", phoneNumber);
|
|
|
+ }
|
|
|
+ return AjaxResult.error(500, "session_key:失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发送模板消息
|
|
|
+ *
|
|
|
+ * @param fromUser 接收此消息的openId
|
|
|
+ * @param name 接收人姓名
|
|
|
+ * @param mblno 提单号
|
|
|
+ * @param amt 金额
|
|
|
+ * @param corpName 客户名
|
|
|
+ * @param loadDate 装货时间
|
|
|
+ * @param otherNews 其他消息
|
|
|
+ * @param remark 备注
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public Objects newsPush(String fromUser, String name, String mblno, String amt, String corpName, String loadDate, String otherNews, String remark) {
|
|
|
+ System.out.println("开始创建模板");
|
|
|
+ String jsonBody = "{\n" +
|
|
|
+ " \"touser\": \"" + fromUser + "\",\n" +
|
|
|
+ " \"template_id\": \"" + templateId + "\",\n" +
|
|
|
+ " \"data\": {\n" +
|
|
|
+ " \"first\": {\n" +
|
|
|
+ " \"value\": \"" + name + "\",\n" +
|
|
|
+ " \"color\": \"#173177\"\n" +
|
|
|
+ " },\n" +
|
|
|
+ " \"keyword1\": {\n" +
|
|
|
+ " \"value\": \"" + mblno + "\",\n" +
|
|
|
+ " \"color\": \"#173177\"\n" +
|
|
|
+ " },\n" +
|
|
|
+ " \"keyword2\": {\n" +
|
|
|
+ " \"value\": \"" + amt + "元\",\n" +
|
|
|
+ " \"color\": \"#173177\"\n" +
|
|
|
+ " },\n" +
|
|
|
+ " \"keyword3\": {\n" +
|
|
|
+ " \"value\": \"" + corpName + "\",\n" +
|
|
|
+ " \"color\": \"#173177\"\n" +
|
|
|
+ " },\n" +
|
|
|
+ " \"keyword4\": {\n" +
|
|
|
+ " \"value\": \"" + loadDate + "\",\n" +
|
|
|
+ " \"color\": \"#173177\"\n" +
|
|
|
+ " },\n" +
|
|
|
+ " \"keyword5\": {\n" +
|
|
|
+ " \"value\": \"" + otherNews + "\",\n" +
|
|
|
+ " \"color\": \"#173177\"\n" +
|
|
|
+ " },\n" +
|
|
|
+ " \"remark\": {\n" +
|
|
|
+ " \"value\": \"" + remark + "\",\n" +
|
|
|
+ " \"color\": \"#173177\"\n" +
|
|
|
+ " }\n" +
|
|
|
+ " }\n" +
|
|
|
+ "}";
|
|
|
+ try {
|
|
|
+ // 客户端
|
|
|
+ OkHttpClient client = new OkHttpClient();
|
|
|
+ // 构建Request请求对象
|
|
|
+ RequestBody body = RequestBody.create(MediaType.parse("application/xml;charset=utf-8"), jsonBody);
|
|
|
+ Request request = new Request.Builder().url(templateMsgUrl + "?access_token=" + AccessTokenUtils.getToken()).post(body).build();
|
|
|
+ // 请求接口,拿到token信息
|
|
|
+ Response response = client.newCall(request).execute();
|
|
|
+ // 判断成功与否
|
|
|
+ if (response.isSuccessful()) {
|
|
|
+ // 拿到相应结果
|
|
|
+ String string = response.body().string();
|
|
|
+ System.out.println("拿到结果了:" + string);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|