zhanglin8526
2023-05-09 dc6726ba2b5d01c643d249e94624831f031369af
企业微信授权网页功能
4个文件已修改
1个文件已添加
170 ■■■■■ 已修改文件
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/AgentConfigVo.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/java/com/ruoyi/auth/controller/QwH5Controller.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/java/com/ruoyi/auth/service/QywxInnerService.java 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/resources/bootstrap.yml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/AgentConfigVo.java
New file
@@ -0,0 +1,20 @@
package com.ruoyi.system.api.model;
import lombok.Data;
/**
 * {"agentid":"1000024","corpid":"ww11400938eb1b91bc","signature":"fb52026ab2dc4b604037dfd411f17772657a19a8","nonceStr":"Wm3WZYTPz0wzccnW","timestamp":1683622343}
 */
@Data
public class AgentConfigVo {
    private String agentid;
    private String corpid;
    private String signature;
    private String nonceStr;
    private String timestamp;
}
ruoyi-auth/src/main/java/com/ruoyi/auth/controller/QwH5Controller.java
@@ -5,10 +5,7 @@
import com.ruoyi.auth.service.SysLoginService;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.system.api.model.OauthUrlVo;
import com.ruoyi.system.api.model.OauthUserVo;
import com.ruoyi.system.api.model.QwH5LoginVo;
import com.ruoyi.system.api.model.QwUserDetailDto;
import com.ruoyi.system.api.model.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
@@ -66,4 +63,13 @@
        // 2、生成Token
       return R.ok(tokenService.createQwH5Token(qwH5LoginVo));
    }
    @GetMapping("/h5/getAgentConfig")
    @ApiOperation("通过code获取访问用户登录")
    public R<AgentConfigVo> getAgentConfig(@ApiParam(value = "url", required = true) String url) throws IOException {
        AgentConfigVo agentConfigVo = qywxInnerService.getAgentConfig(url);
        return R.ok(agentConfigVo);
    }
}
ruoyi-auth/src/main/java/com/ruoyi/auth/service/QywxInnerService.java
@@ -1,14 +1,29 @@
package com.ruoyi.auth.service;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.A;
import com.ruoyi.auth.config.QywxInnerConfig;
import com.ruoyi.auth.utils.RestUtils;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.system.api.model.AgentConfigVo;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Service
public class QywxInnerService {
@@ -18,21 +33,34 @@
    @Autowired
    private QywxInnerConfig qywxInnerConfig;
    @Autowired
    private StringRedisTemplate redisTemplate;
    public String getAccessToken(){
        String accessToken = redisTemplate.opsForValue().get(Constants.QY_WX_ACCESS_TOKEN_KEY);
        if(!StringUtils.isEmpty(accessToken)){
            return accessToken;
        }
        String corpId = qywxInnerConfig.getCorpId();
        String agentSecret = qywxInnerConfig.getAgentSecret();
        String  accessTokenUrl = String.format(qywxInnerConfig.getAccessTokenUrl(), corpId, agentSecret);
        JSONObject response = RestUtils.get(accessTokenUrl);
        // 获取错误日志
        if(response.containsKey(Constants.QY_WX_ERR_CODE) && response.getInteger(Constants.QY_WX_ERR_CODE) != 0){
            logger.error(response.toString());
            throw new ServiceException("获取企业微信ACCESS_TOKEN异常");
        }
        return response.getString(Constants.QY_WX_ACCESS_TOKEN);
        accessToken = response.getString(Constants.QY_WX_ACCESS_TOKEN);
        Long expiresIn = response.getLong(Constants.QY_WX_EXPIRES_IN);
        expiresIn = expiresIn - 100;
        redisTemplate.opsForValue().set(Constants.QY_WX_ACCESS_TOKEN_KEY, accessToken, expiresIn, TimeUnit.SECONDS);
        return accessToken;
    }
@@ -96,4 +124,79 @@
        return detailResponse;
    }
    public AgentConfigVo getAgentConfig(String url) {
        AgentConfigVo agentConfigVo = new AgentConfigVo();
        agentConfigVo.setAgentid(qywxInnerConfig.getAgentId());
        agentConfigVo.setCorpid(qywxInnerConfig.getCorpId());
        //临时票据
        String ticket = getJsApiTicket();
        if (StringUtils.isEmpty(ticket)) {
           throw new ServiceException("获取票据异常");
        }
        //当前时间戳 转成秒
        long timestamp = System.currentTimeMillis() / 1000;
        //随机字符串
        String nonceStr = Constants.QY_WX_NONCE_STR;
        String signature = getSignature(ticket, nonceStr, timestamp, url);
        agentConfigVo.setTimestamp(String.valueOf(timestamp));
        agentConfigVo.setNonceStr(nonceStr);
        agentConfigVo.setSignature(signature);
        return agentConfigVo;
    }
    private String getSignature(String ticket, String nonceStr, long timestamp, String url) {
        String unEncryptStrBase = "jsapi_ticket=%s&noncestr=%s&timestamp=%s&url=%s";
        try {
            String unEncryptStr = String.format(unEncryptStrBase, ticket, nonceStr, timestamp, url);
            logger.info("----------------unEncryptStrBase-------------");
            logger.info(unEncryptStrBase);
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            // 调用digest方法,进行加密操作
            byte[] cipherBytes = digest.digest(unEncryptStr.getBytes());
            String encryptStr = Hex.encodeHexString(cipherBytes);
            logger.info("----------------getSignature-------------");
            logger.info(encryptStr);
            return encryptStr;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 获取ticket
     * @paran type
     * @return
     */
    public String getJsApiTicket() {
        String accessToken = getAccessToken();
        String ticket = redisTemplate.opsForValue().get(Constants.QY_WX_TICKET_KEY);
        if(!StringUtils.isEmpty(ticket)){
            return ticket;
        }
        String url = String.format(qywxInnerConfig.getJsapiTicketAgentUrl(), accessToken);
        JSONObject response = RestUtils.get(url);
        if(response.containsKey(Constants.QY_WX_ERR_CODE) && response.getInteger(Constants.QY_WX_ERR_CODE) != 0){
            logger.error(response.toString());
            throw new ServiceException("获取企业微信信息异常");
        }
        ticket = response.getString(Constants.QY_WX_TICKET);
        Long expiresIn = response.getLong(Constants.QY_WX_EXPIRES_IN);
        expiresIn = expiresIn - 100;
        redisTemplate.opsForValue().set(Constants.QY_WX_TICKET_KEY, ticket, expiresIn, TimeUnit.SECONDS);
        return ticket;
    }
}
ruoyi-auth/src/main/resources/bootstrap.yml
@@ -24,11 +24,10 @@
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
#自建应用配置 非代开发不需要 具体自建应用配置大家写表里就行
qywx-inner:
  corpId: ww78cbcfad600119af
  agentId: 1000005
  agentSecret: 2xMP3DaamA4-zTu6KtsF_y83OSJRXK5UspB8hWKkXmI
  corpId: ww11400938eb1b91bc
  agentId: 1000024
  agentSecret: -wuQ2EBxNT9BJa40LdpFqyxI_8RqrZTCUNiabzBasi8
  authorizeState: HONGRUITANG
  suiteSecret: ""
  token: ""
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/Constants.java
@@ -117,11 +117,35 @@
     */
    public static final String QY_WX_ERR_CODE = "errcode";
    public static final String QY_WX_NONCE_STR = "Wm3WZYTPz0wzccnW";
    /**
     * 企业微信返回码 调用接口凭证KEY
     */
    public static final String QY_WX_ACCESS_TOKEN_KEY = "qy_wx_access_token";
    /**
     * 企业微信返回码 调用接口ticket KEY
     */
    public static final String QY_WX_TICKET_KEY = "qy_wx_ticket_token";
    /**
     * 企业微信返回码 调用接口凭证
     */
    public static final String QY_WX_ACCESS_TOKEN = "access_token";
    /**
     * 企业微信返回码 调用接口凭证
     */
    public static final String QY_WX_EXPIRES_IN = "expires_in";
    public static final String QY_WX_TICKET = "ticket";
    /**
     * 成员UserID