1.修改1101(求职者)、1102(招聘者)、1103(网格员)、1104(内部工作者)
2.添加门户认证的类
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import com.ruoyi.cms.domain.query.ESJobSearch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -10,7 +8,8 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class StringUtil {
|
||||
|
||||
public static final Long COMPANY_ADMIN_ROLE_KEY = 100L;
|
||||
/*1101(求职者)、1102(招聘者)、1103(网格员)、1104(内部工作者)*/
|
||||
public static final Long COMPANY_ADMIN_ROLE_KEY = 1002L;
|
||||
|
||||
/**
|
||||
* 企业用户
|
||||
@@ -20,11 +19,11 @@ public class StringUtil {
|
||||
/**
|
||||
* pc端-求职者
|
||||
*/
|
||||
public static final String SYS_QZZ = "2";
|
||||
public static final String SYS_QZZ = "1101";
|
||||
/**
|
||||
* pc端-企业
|
||||
*/
|
||||
public static final String SYS_QY = "100";
|
||||
public static final String SYS_QY = "1102";
|
||||
|
||||
public static Boolean isEmptyOrNull(String s){
|
||||
if(Objects.isNull(s)){return true;}
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
package com.ruoyi.cms.util.oauth;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import okhttp3.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
/**
|
||||
* 简化版 HTTP 客户端工具类(仅保留核心POST功能,保留超时配置)
|
||||
*/
|
||||
public class HttpUtils {
|
||||
private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);
|
||||
|
||||
// 保留默认超时配置
|
||||
private static final int DEFAULT_CONNECT_TIMEOUT = 10;
|
||||
private static final int DEFAULT_READ_TIMEOUT = 30;
|
||||
private static final int DEFAULT_WRITE_TIMEOUT = 30;
|
||||
|
||||
// 媒体类型常量
|
||||
public static final MediaType JSON_MEDIA_TYPE = MediaType.parse("application/json; charset=utf-8");
|
||||
public static final MediaType FORM_MEDIA_TYPE = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");
|
||||
|
||||
// OkHttp 客户端(单例)
|
||||
private static final OkHttpClient OK_HTTP_CLIENT;
|
||||
|
||||
static {
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder()
|
||||
.connectTimeout(DEFAULT_CONNECT_TIMEOUT, TimeUnit.SECONDS)
|
||||
.readTimeout(DEFAULT_READ_TIMEOUT, TimeUnit.SECONDS)
|
||||
.writeTimeout(DEFAULT_WRITE_TIMEOUT, TimeUnit.SECONDS);
|
||||
|
||||
OK_HTTP_CLIENT = builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* POST JSON请求(默认超时)
|
||||
*/
|
||||
public static String doPostJson(String url, Map<String, Object> params) throws TimeoutException, IOException {
|
||||
return doPostJson(url, params, DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT, DEFAULT_WRITE_TIMEOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST JSON请求(自定义超时)
|
||||
*/
|
||||
public static String doPostJson(String url, Map<String, Object> params, int connectTimeout, int readTimeout, int writeTimeout)
|
||||
throws TimeoutException, IOException {
|
||||
String jsonParams = CollectionUtils.isEmpty(params) ? "{}" : JSON.toJSONString(params);
|
||||
return doPost(url, jsonParams, JSON_MEDIA_TYPE, null, connectTimeout, readTimeout, writeTimeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST 表单请求(默认超时)
|
||||
*/
|
||||
public static String doPostForm(String url, Map<String, Object> params) throws TimeoutException, IOException {
|
||||
return doPostForm(url, params, null, DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT, DEFAULT_WRITE_TIMEOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST 表单请求(自定义超时)
|
||||
*/
|
||||
public static String doPostForm(String url, Map<String, Object> params, Map<String, String> headers,
|
||||
int connectTimeout, int readTimeout, int writeTimeout)
|
||||
throws TimeoutException, IOException {
|
||||
FormBody.Builder formBuilder = new FormBody.Builder();
|
||||
if (!CollectionUtils.isEmpty(params)) {
|
||||
params.forEach((key, value) -> {
|
||||
if (value != null) {
|
||||
formBuilder.add(encodeParam(key), value.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
RequestBody requestBody = formBuilder.build();
|
||||
|
||||
Request.Builder requestBuilder = new Request.Builder()
|
||||
.url(url)
|
||||
.post(requestBody)
|
||||
.header("Content-Type", FORM_MEDIA_TYPE.toString());
|
||||
|
||||
addHeaders(requestBuilder, headers);
|
||||
return executeRequest(requestBuilder.build(), connectTimeout, readTimeout, writeTimeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用POST方法
|
||||
*/
|
||||
private static String doPost(String url, String content, MediaType mediaType, Map<String, String> headers,
|
||||
int connectTimeout, int readTimeout, int writeTimeout)
|
||||
throws TimeoutException, IOException {
|
||||
if (mediaType == null) {
|
||||
mediaType = JSON_MEDIA_TYPE;
|
||||
}
|
||||
RequestBody requestBody = RequestBody.create(mediaType,content);
|
||||
|
||||
Request.Builder requestBuilder = new Request.Builder()
|
||||
.url(url)
|
||||
.post(requestBody)
|
||||
.header("Content-Type", mediaType.toString());
|
||||
|
||||
addHeaders(requestBuilder, headers);
|
||||
return executeRequest(requestBuilder.build(), connectTimeout, readTimeout, writeTimeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行请求核心方法
|
||||
*/
|
||||
private static String executeRequest(Request request, int connectTimeout, int readTimeout, int writeTimeout)
|
||||
throws TimeoutException, IOException {
|
||||
// 保留超时配置覆盖能力
|
||||
OkHttpClient tempClient = OK_HTTP_CLIENT.newBuilder()
|
||||
.connectTimeout(connectTimeout, TimeUnit.SECONDS)
|
||||
.readTimeout(readTimeout, TimeUnit.SECONDS)
|
||||
.writeTimeout(writeTimeout, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
try (Response response = tempClient.newCall(request).execute()) {
|
||||
return response.body() != null ? response.body().string() : "";
|
||||
} catch (SocketTimeoutException e) {
|
||||
throw new TimeoutException(String.format("HTTP 请求超时 | URL: %s | 超时配置: 连接%d秒, 读取%d秒, 写入%d秒",
|
||||
request.url(), connectTimeout, readTimeout, writeTimeout));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数编码
|
||||
*/
|
||||
private static String encodeParam(String param) {
|
||||
try {
|
||||
return URLEncoder.encode(param, "UTF-8");
|
||||
} catch (Exception e) {
|
||||
log.warn("参数编码失败 | param: {}", param, e);
|
||||
return param;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加请求头
|
||||
*/
|
||||
private static void addHeaders(Request.Builder requestBuilder, Map<String, String> headers) {
|
||||
if (!CollectionUtils.isEmpty(headers)) {
|
||||
headers.forEach(requestBuilder::header);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
package com.ruoyi.cms.util.oauth;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.TypeReference;
|
||||
import com.ruoyi.common.core.domain.entity.tymh.nwToken.NwTokenResult;
|
||||
import com.ruoyi.common.core.domain.entity.tymh.nwToken.NwUserInfoResult;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.crypto.CryptoUtil;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* OAuth2.0 认证工具类(合并相似方法)
|
||||
*/
|
||||
@Component
|
||||
public class OauthClient {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(OauthClient.class);
|
||||
/*====================== 内网 ======================*/
|
||||
// 网关请求-内网获取token
|
||||
@Value("${oauth.usptnw.nwGatewayGetTokenUrl}")
|
||||
private String nwGatewayGetTokenUrl;
|
||||
// 网关请求-内网获取用户信息
|
||||
@Value("${oauth.usptnw.nwGatewayGetUserInfoUrl}")
|
||||
private String nwGatewayGetUserInfoUrl;
|
||||
|
||||
/*====================== 外网 ======================*/
|
||||
//post-外网注册地址
|
||||
@Value("${oauth.usptww.wwRegisterPostUrl}")
|
||||
private String wwRegisterPostUrl;
|
||||
// post-外网获取token
|
||||
@Value("${oauth.usptww.wwTokenPostUrl}")
|
||||
private String wwTokenPostUrl;
|
||||
//post-外网获取用户信息
|
||||
@Value("${oauth.usptww.wwQueryWebPersonalInfoPostUrl}")
|
||||
private String wwQueryWebPersonalInfoPostUrl;
|
||||
//post-外网获取单位信息
|
||||
@Value("${oauth.usptww.wwQueryWebEnterpriseInfoPostUrl}")
|
||||
private String wwQueryWebEnterpriseInfoPostUrl;
|
||||
|
||||
/*====================== 统一门户 ======================*/
|
||||
//用户新增接口
|
||||
@Value("${oauth.tyAddUserUrl}")
|
||||
private String tyAddUserUrl;
|
||||
//获取当前用户有权系统列表
|
||||
@Value("${oauth.tyQueryUserSysListUrl}")
|
||||
private String tyQueryUserSysListUrl;
|
||||
//获取当前用户有权角色列表
|
||||
@Value("${oauth.tyQueryUserRoleListUrl}")
|
||||
private String tyQueryUserRoleListUrl;
|
||||
//获取角色功能权限信息
|
||||
@Value("${oauth.tyQueryRoleInfoUrl}")
|
||||
private String tyQueryRoleInfoUrl;
|
||||
//获取用户详细信息
|
||||
@Value("${oauth.tyQueryUserInfo}")
|
||||
private String tyQueryUserInfo;
|
||||
//获取机构详细信息
|
||||
@Value("${oauth.tyQueryUnitInfo}")
|
||||
private String tyQueryUnitInfo;
|
||||
//客户端id
|
||||
@Value("${oauth.appid}")
|
||||
private String appid;
|
||||
//授权码
|
||||
@Value("${oauth.clientsecretkey}")
|
||||
private String clientsecretkey;
|
||||
// 超时配置
|
||||
@Value("${oauth.connect-timeout:10}")
|
||||
private int connectTimeout;
|
||||
@Value("${oauth.read-timeout:30}")
|
||||
private int readTimeout;
|
||||
@Value("${oauth.write-timeout:30}")
|
||||
private int writeTimeout;
|
||||
|
||||
/**
|
||||
* 获取经办段token
|
||||
* @return
|
||||
*/
|
||||
public NwTokenResult nwGetToken(String code) throws IOException, TimeoutException {
|
||||
if (StringUtils.isEmpty(code)) {
|
||||
log.error("获取Token失败:授权码code不能为空");
|
||||
throw new IllegalArgumentException("授权码code不能为空");
|
||||
}
|
||||
|
||||
String decryptedCode;
|
||||
try {
|
||||
decryptedCode = CryptoUtil.sm2Decrypt(clientsecretkey, code);
|
||||
if (StringUtils.isEmpty(decryptedCode)) {
|
||||
throw new RuntimeException("授权码解密后为空");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("授权码解密失败 | 原始code: {}", code, e);
|
||||
throw new RuntimeException("授权码解密失败:" + e.getMessage(), e);
|
||||
}
|
||||
|
||||
Map<String, Object> params = new HashMap<>(2);
|
||||
params.put("appid", appid);
|
||||
params.put("code", decryptedCode);
|
||||
|
||||
NwTokenResult result = executePostRequest(
|
||||
nwGatewayGetTokenUrl,
|
||||
params,
|
||||
new TypeReference<Response<NwTokenResult>>() {},
|
||||
"获取Token"
|
||||
);
|
||||
|
||||
if (StringUtils.isEmpty(result.getAccessToken())) {
|
||||
throw new RuntimeException("Token获取失败:返回的accessToken为空");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取经办段用户id
|
||||
* @return
|
||||
*/
|
||||
public NwUserInfoResult nwGetUserInfo(String accessToken) throws IOException, TimeoutException {
|
||||
Map<String, Object> params = new HashMap<>(2);
|
||||
params.put("appid", appid);
|
||||
params.put("access_token", accessToken);
|
||||
|
||||
return executePostRequest(
|
||||
nwGatewayGetUserInfoUrl,
|
||||
params,
|
||||
new TypeReference<Response<NwUserInfoResult>>() {},
|
||||
"获取用户信息"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 公共POST请求执行方法
|
||||
* @param url 请求URL
|
||||
* @param params 请求参数
|
||||
* @param typeReference 响应类型引用
|
||||
* @param operationName 操作名称(用于日志和异常信息)
|
||||
* @return 响应数据对象
|
||||
*/
|
||||
private <T> T executePostRequest(String url, Map<String, Object> params,
|
||||
TypeReference<Response<T>> typeReference, String operationName)
|
||||
throws IOException, TimeoutException {
|
||||
String responseJson = null;
|
||||
try {
|
||||
responseJson = HttpUtils.doPostJson(
|
||||
url,
|
||||
params,
|
||||
connectTimeout,
|
||||
readTimeout,
|
||||
writeTimeout
|
||||
);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return validateResponse(responseJson, operationName, typeReference);
|
||||
}
|
||||
|
||||
/**
|
||||
* 公共响应校验工具方法(网关响应 + 业务 errflag 校验)
|
||||
*/
|
||||
private <T> T validateResponse(String responseJson, String operationName, TypeReference<Response<T>> typeReference) {
|
||||
// 1. 校验响应是否为空
|
||||
if (StringUtils.isEmpty(responseJson)) {
|
||||
String errorMsg = operationName + "失败:接口返回空响应";
|
||||
log.error(errorMsg);
|
||||
throw new BusinessException("EMPTY_RESPONSE", errorMsg);
|
||||
}
|
||||
log.debug("{}接口返回原始数据: {}", operationName, responseJson);
|
||||
|
||||
// 2. 解析网关响应(外层 appcode 校验)
|
||||
Response<T> gatewayResponse = JSON.parseObject(responseJson, typeReference);
|
||||
if (gatewayResponse == null) {
|
||||
String errorMsg = operationName + "失败:网关响应格式异常(无法解析)";
|
||||
log.error("{} | 原始响应: {}", errorMsg, responseJson);
|
||||
throw new BusinessException("GATEWAY_PARSE_ERROR", errorMsg);
|
||||
}
|
||||
|
||||
if (!"0".equals(gatewayResponse.getAppcode())) {
|
||||
String errorMsg = String.format("%s失败:网关响应失败 | appcode: %s, msg: %s",
|
||||
operationName, gatewayResponse.getAppcode(), gatewayResponse.getMsg());
|
||||
log.error("{} | 原始响应: {}", errorMsg, responseJson);
|
||||
throw new BusinessException(gatewayResponse.getAppcode(), errorMsg);
|
||||
}
|
||||
|
||||
T data = gatewayResponse.getData();
|
||||
if (data == null) {
|
||||
String errorMsg = operationName + "失败:响应data字段为空";
|
||||
log.error("{} | 原始响应: {}", errorMsg, responseJson);
|
||||
throw new BusinessException("DATA_EMPTY", errorMsg);
|
||||
}
|
||||
|
||||
if (data instanceof ErrFlagResponse) {
|
||||
ErrFlagResponse errFlagResponse = (ErrFlagResponse) data;
|
||||
if (!errFlagResponse.isSuccess()) {
|
||||
String errorMsg = String.format("%s失败:%s(错误标识:%s)",
|
||||
operationName, errFlagResponse.getErrtext(), errFlagResponse.getErrflag());
|
||||
log.error("{} | 原始响应: {}", errorMsg, responseJson);
|
||||
throw new BusinessException(errFlagResponse.getErrflag(), errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 所有校验通过,返回业务数据
|
||||
return data;
|
||||
}
|
||||
|
||||
public static class Response<T> {
|
||||
private String appcode;
|
||||
private String code;
|
||||
private String msg;
|
||||
private T data;
|
||||
private Object map;
|
||||
|
||||
// Getter(仅保留需要的字段,setter可选)
|
||||
public String getAppcode() { return appcode; }
|
||||
public String getMsg() { return msg; }
|
||||
public T getData() { return data; }
|
||||
}
|
||||
|
||||
public class BusinessException extends RuntimeException {
|
||||
private String code; // 错误码(可关联门户错误码)
|
||||
|
||||
public BusinessException(String message) {
|
||||
super(message);
|
||||
this.code = "BUSINESS_ERROR";
|
||||
}
|
||||
|
||||
public BusinessException(String code, String message) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
// Getter
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
public interface ErrFlagResponse {
|
||||
String getErrflag();
|
||||
String getErrtext();
|
||||
|
||||
// 默认方法:判断是否成功(0=成功,1=失败)
|
||||
default boolean isSuccess() {
|
||||
return "0".equals(getErrflag());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user