1
This commit is contained in:
@@ -117,8 +117,13 @@ public class TencentDocServiceImpl implements ITencentDocService {
|
||||
}
|
||||
|
||||
// 获取用户信息(包含Open-Id)
|
||||
// 官方响应格式:{ "ret": 0, "msg": "Succeed", "data": { "openID": "xxx", ... } }
|
||||
JSONObject userInfo = TencentDocApiUtil.getUserInfo(accessToken);
|
||||
String openId = userInfo.getString("openId");
|
||||
JSONObject data = userInfo.getJSONObject("data");
|
||||
if (data == null) {
|
||||
throw new RuntimeException("无法获取用户数据,请检查Access Token是否有效");
|
||||
}
|
||||
String openId = data.getString("openID"); // 注意:官方返回的字段名是 openID(大写ID)
|
||||
if (openId == null || openId.isEmpty()) {
|
||||
throw new RuntimeException("无法获取Open-Id,请检查Access Token是否有效");
|
||||
}
|
||||
@@ -169,8 +174,13 @@ public class TencentDocServiceImpl implements ITencentDocService {
|
||||
}
|
||||
|
||||
// 获取用户信息(包含Open-Id)
|
||||
// 官方响应格式:{ "ret": 0, "msg": "Succeed", "data": { "openID": "xxx", ... } }
|
||||
JSONObject userInfo = TencentDocApiUtil.getUserInfo(accessToken);
|
||||
String openId = userInfo.getString("openId");
|
||||
JSONObject data = userInfo.getJSONObject("data");
|
||||
if (data == null) {
|
||||
throw new RuntimeException("无法获取用户数据,请检查Access Token是否有效");
|
||||
}
|
||||
String openId = data.getString("openID"); // 注意:官方返回的字段名是 openID(大写ID)
|
||||
if (openId == null || openId.isEmpty()) {
|
||||
throw new RuntimeException("无法获取Open-Id,请检查Access Token是否有效");
|
||||
}
|
||||
@@ -214,8 +224,13 @@ public class TencentDocServiceImpl implements ITencentDocService {
|
||||
public JSONObject readSheetData(String accessToken, String fileId, String sheetId, String range) {
|
||||
try {
|
||||
// 获取用户信息(包含Open-Id)
|
||||
// 官方响应格式:{ "ret": 0, "msg": "Succeed", "data": { "openID": "xxx", ... } }
|
||||
JSONObject userInfo = TencentDocApiUtil.getUserInfo(accessToken);
|
||||
String openId = userInfo.getString("openId");
|
||||
JSONObject data = userInfo.getJSONObject("data");
|
||||
if (data == null) {
|
||||
throw new RuntimeException("无法获取用户数据,请检查Access Token是否有效");
|
||||
}
|
||||
String openId = data.getString("openID"); // 注意:官方返回的字段名是 openID(大写ID)
|
||||
if (openId == null || openId.isEmpty()) {
|
||||
throw new RuntimeException("无法获取Open-Id,请检查Access Token是否有效");
|
||||
}
|
||||
@@ -239,8 +254,13 @@ public class TencentDocServiceImpl implements ITencentDocService {
|
||||
public JSONObject writeSheetData(String accessToken, String fileId, String sheetId, String range, Object values) {
|
||||
try {
|
||||
// 获取用户信息(包含Open-Id)
|
||||
// 官方响应格式:{ "ret": 0, "msg": "Succeed", "data": { "openID": "xxx", ... } }
|
||||
JSONObject userInfo = TencentDocApiUtil.getUserInfo(accessToken);
|
||||
String openId = userInfo.getString("openId");
|
||||
JSONObject data = userInfo.getJSONObject("data");
|
||||
if (data == null) {
|
||||
throw new RuntimeException("无法获取用户数据,请检查Access Token是否有效");
|
||||
}
|
||||
String openId = data.getString("openID"); // 注意:官方返回的字段名是 openID(大写ID)
|
||||
if (openId == null || openId.isEmpty()) {
|
||||
throw new RuntimeException("无法获取Open-Id,请检查Access Token是否有效");
|
||||
}
|
||||
@@ -265,8 +285,13 @@ public class TencentDocServiceImpl implements ITencentDocService {
|
||||
public JSONObject getFileInfo(String accessToken, String fileId) {
|
||||
try {
|
||||
// 获取用户信息(包含Open-Id)
|
||||
// 官方响应格式:{ "ret": 0, "msg": "Succeed", "data": { "openID": "xxx", ... } }
|
||||
JSONObject userInfo = TencentDocApiUtil.getUserInfo(accessToken);
|
||||
String openId = userInfo.getString("openId");
|
||||
JSONObject data = userInfo.getJSONObject("data");
|
||||
if (data == null) {
|
||||
throw new RuntimeException("无法获取用户数据,请检查Access Token是否有效");
|
||||
}
|
||||
String openId = data.getString("openID"); // 注意:官方返回的字段名是 openID(大写ID)
|
||||
if (openId == null || openId.isEmpty()) {
|
||||
throw new RuntimeException("无法获取Open-Id,请检查Access Token是否有效");
|
||||
}
|
||||
@@ -288,8 +313,13 @@ public class TencentDocServiceImpl implements ITencentDocService {
|
||||
public JSONObject getSheetList(String accessToken, String fileId) {
|
||||
try {
|
||||
// 获取用户信息(包含Open-Id)
|
||||
// 官方响应格式:{ "ret": 0, "msg": "Succeed", "data": { "openID": "xxx", ... } }
|
||||
JSONObject userInfo = TencentDocApiUtil.getUserInfo(accessToken);
|
||||
String openId = userInfo.getString("openId");
|
||||
JSONObject data = userInfo.getJSONObject("data");
|
||||
if (data == null) {
|
||||
throw new RuntimeException("无法获取用户数据,请检查Access Token是否有效");
|
||||
}
|
||||
String openId = data.getString("openID"); // 注意:官方返回的字段名是 openID(大写ID)
|
||||
if (openId == null || openId.isEmpty()) {
|
||||
throw new RuntimeException("无法获取Open-Id,请检查Access Token是否有效");
|
||||
}
|
||||
|
||||
@@ -476,66 +476,63 @@ public class TencentDocApiUtil {
|
||||
|
||||
/**
|
||||
* 获取用户信息(包含Open-Id)
|
||||
* 根据官方文档:https://docs.qq.com/open/document/app/oauth2/user_info.html
|
||||
*
|
||||
* @param accessToken 访问令牌
|
||||
* @return 用户信息,包含 openId、nickname 等字段
|
||||
* @return 用户信息
|
||||
* 响应格式:{ "ret": 0, "msg": "Succeed", "data": { "openID": "xxx", "nick": "xxx", "avatar": "xxx", "source": "wx", "unionID": "xxx" } }
|
||||
*/
|
||||
public static JSONObject getUserInfo(String accessToken) {
|
||||
// 腾讯文档用户信息接口:https://docs.qq.com/open/document/app/oauth2/userinfo.html
|
||||
// 注意:此接口使用不同的鉴权方式(Authorization: Bearer)
|
||||
String apiUrl = "https://docs.qq.com/oauth/v2/userinfo";
|
||||
return callApiLegacy(accessToken, apiUrl, "GET", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用腾讯文档API(旧版鉴权方式,用于OAuth接口)
|
||||
* 某些接口(如 userinfo)使用 Authorization: Bearer 方式
|
||||
*
|
||||
* @param accessToken 访问令牌
|
||||
* @param apiUrl API地址
|
||||
* @param method 请求方法
|
||||
* @param body 请求体
|
||||
* @return API响应
|
||||
*/
|
||||
private static JSONObject callApiLegacy(String accessToken, String apiUrl, String method, String body) {
|
||||
try {
|
||||
// 官方文档要求使用查询参数传递 access_token,而不是请求头
|
||||
String apiUrl = "https://docs.qq.com/oauth/v2/userinfo?access_token=" + accessToken;
|
||||
log.info("调用获取用户信息API: url={}", apiUrl);
|
||||
|
||||
URL url = new URL(apiUrl);
|
||||
java.net.Proxy proxy = java.net.Proxy.NO_PROXY;
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
|
||||
|
||||
conn.setRequestMethod(method);
|
||||
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
|
||||
conn.setRequestProperty("Content-Type", "application/json");
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setRequestProperty("Accept", "application/json");
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
conn.setConnectTimeout(10000);
|
||||
conn.setReadTimeout(30000);
|
||||
|
||||
if (body != null && !body.isEmpty()) {
|
||||
try (OutputStream os = conn.getOutputStream();
|
||||
OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8)) {
|
||||
osw.write(body);
|
||||
osw.flush();
|
||||
// 读取响应
|
||||
int responseCode = conn.getResponseCode();
|
||||
log.info("获取用户信息API响应状态码: {}", responseCode);
|
||||
|
||||
java.io.InputStream inputStream = (responseCode >= 200 && responseCode < 300)
|
||||
? conn.getInputStream()
|
||||
: conn.getErrorStream();
|
||||
|
||||
StringBuilder response = new StringBuilder();
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
}
|
||||
}
|
||||
|
||||
int statusCode = conn.getResponseCode();
|
||||
BufferedReader reader = statusCode >= 200 && statusCode < 300
|
||||
? new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))
|
||||
: new BufferedReader(new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8));
|
||||
String responseBody = response.toString();
|
||||
log.debug("获取用户信息API响应: {}", responseBody);
|
||||
|
||||
StringBuilder response = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
if (responseCode >= 200 && responseCode < 300) {
|
||||
JSONObject result = JSONObject.parseObject(responseBody);
|
||||
// 检查业务返回码
|
||||
Integer ret = result.getInteger("ret");
|
||||
if (ret != null && ret == 0) {
|
||||
return result;
|
||||
} else {
|
||||
String msg = result.getString("msg");
|
||||
throw new RuntimeException("获取用户信息失败: " + msg);
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("获取用户信息失败,HTTP状态码: " + responseCode + ", 响应: " + responseBody);
|
||||
}
|
||||
reader.close();
|
||||
|
||||
return JSON.parseObject(response.toString());
|
||||
} catch (Exception e) {
|
||||
log.error("调用腾讯文档API(旧版鉴权)失败: url={}, method={}", apiUrl, method, e);
|
||||
throw new RuntimeException("调用API失败: " + e.getMessage(), e);
|
||||
log.error("获取用户信息失败", e);
|
||||
throw new RuntimeException("获取用户信息失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,9 +548,14 @@ public class TencentDocApiUtil {
|
||||
*/
|
||||
public static JSONObject callApiSimple(String accessToken, String appId, String apiUrl, String method, String body) {
|
||||
// 获取用户信息以获得 openId
|
||||
// 官方响应格式:{ "ret": 0, "msg": "Succeed", "data": { "openID": "xxx", ... } }
|
||||
JSONObject userInfo = getUserInfo(accessToken);
|
||||
String openId = userInfo.getString("openId");
|
||||
JSONObject data = userInfo.getJSONObject("data");
|
||||
if (data == null) {
|
||||
throw new RuntimeException("无法获取用户数据,请检查 Access Token 是否有效");
|
||||
}
|
||||
|
||||
String openId = data.getString("openID"); // 注意:官方返回的字段名是 openID(大写ID)
|
||||
if (openId == null || openId.isEmpty()) {
|
||||
throw new RuntimeException("无法获取 Open-Id,请检查 Access Token 是否有效");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user