Commit 82141c7e by zhangxingmin

push

parent b1b8fd85
...@@ -14,7 +14,6 @@ import com.yd.notice.service.model.NotificationTemplate; ...@@ -14,7 +14,6 @@ import com.yd.notice.service.model.NotificationTemplate;
import com.yd.notice.service.model.SubscribeRecord; import com.yd.notice.service.model.SubscribeRecord;
import com.yd.notice.service.service.INotificationTemplateService; import com.yd.notice.service.service.INotificationTemplateService;
import com.yd.notice.service.service.ISubscribeRecordService; import com.yd.notice.service.service.ISubscribeRecordService;
import com.yd.notice.service.utils.SfpTokenUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
...@@ -32,7 +31,9 @@ import javax.annotation.Resource; ...@@ -32,7 +31,9 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 小程序订阅记录 API 服务实现类 * 小程序订阅记录 API 服务实现类
...@@ -57,26 +58,28 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService ...@@ -57,26 +58,28 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
private Environment env; private Environment env;
/** /**
* 根据当前环境获取 SFP API 基础地址 * 根据当前环境获取 ajb 服务基础地址
*/ */
private String getSfpApiBaseUrl() { private String getAjbBaseUrl() {
String activeProfile = env.getProperty("spring.profiles.active", "dev"); String activeProfile = env.getProperty("spring.profiles.active", "dev");
log.info("当前环境: {}, 获取 SFP API 地址", activeProfile); log.info("当前环境: {}, 获取 ajb 服务地址", activeProfile);
if ("prod".equalsIgnoreCase(activeProfile)) { if ("prod".equalsIgnoreCase(activeProfile) || "production".equalsIgnoreCase(activeProfile)) {
return "https://hoservice.ydhomeoffice.cn/hoserviceApi"; // 生产环境 // 生产环境 ajb 服务地址(请根据实际部署确认)
return "https://hoservice.ydhomeoffice.cn/hoserviceApi";
} else { } else {
return "https://mdev.anjibao.cn/sfpApi"; // 测试/开发环境 // 测试/开发环境
return "https://mdev.anjibao.cn/sfpApi";
} }
} }
/** /**
* 从请求头中获取 Token,解析出 SFP 用户 ID,再调用 SFP 接口获取用户的 wxOpenId * 从请求头中获取 Token,通过远程解析获取用户的完整信息(包含 openid 和 userId)
* *
* @return 用户的 openid * @return QuerySfpUserResponse 用户信息
* @throws RuntimeException 如果获取失败 * @throws RuntimeException 如果获取失败
*/ */
private String getOpenidFromToken() { private QuerySfpUserResponse getUserInfoFromToken() {
// 从请求上下文中获取当前请求 // 获取当前请求上下文
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes == null) { if (attributes == null) {
log.error("无法获取当前请求上下文"); log.error("无法获取当前请求上下文");
...@@ -89,63 +92,44 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService ...@@ -89,63 +92,44 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
throw new RuntimeException("未提供认证 Token"); throw new RuntimeException("未提供认证 Token");
} }
// ----- 通用提取逻辑:取最后一个空格之后的部分,兼容任意前缀(如 "zuihuibi "、"Bearer " 等)----- // 直接使用原始 authorization 值,不做任何处理,远程接口会自动剥离前缀
String token = authorization; String token = authorization;
int lastSpaceIndex = authorization.lastIndexOf(" "); log.info("调用远程解析 Token 接口,原始 authorization: {}", authorization);
if (lastSpaceIndex != -1) {
token = authorization.substring(lastSpaceIndex + 1);
log.info("认证头包含前缀,已自动提取 Token 部分(原头:{})", authorization);
}
// ----------------------------------------------------------------------------------------
// 1. 解析 Token 获取用户 ID
String userIdStr = SfpTokenUtil.getUserIdFromToken(token);
if (!StringUtils.hasText(userIdStr)) {
log.error("Token 解析失败,未获取到用户 ID");
throw new RuntimeException("Token 无效");
}
Long sfpUserId;
try {
sfpUserId = Long.valueOf(userIdStr);
} catch (NumberFormatException e) {
log.error("用户 ID 格式错误: {}", userIdStr);
throw new RuntimeException("Token 中的用户 ID 格式错误");
}
// 2. 根据环境获取 SFP API 基础地址并调用接口 // 根据环境获取 ajb 服务地址
String sfpApiBaseUrl = getSfpApiBaseUrl(); String ajbBaseUrl = getAjbBaseUrl();
String url = sfpApiBaseUrl + "/user/query/sfpUser"; String parseUrl = ajbBaseUrl + "/user/parse/token";
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON); headers.setContentType(MediaType.APPLICATION_JSON);
String requestBody = String.format("{\"sfpUserId\":%d}", sfpUserId); Map<String, String> requestBody = new HashMap<>();
HttpEntity<String> entity = new HttpEntity<>(requestBody, headers); requestBody.put("token", token);
HttpEntity<Map<String, String>> entity = new HttpEntity<>(requestBody, headers);
log.info("调用 SFP 查询用户信息, url={}, requestBody={}", url, requestBody); log.info("调用远程解析 Token 接口, url={}, token前50字符: {}", parseUrl,
token.substring(0, Math.min(50, token.length())) + "...");
try { try {
ResponseEntity<JsonResult> responseEntity = restTemplate.postForEntity(url, entity, JsonResult.class); ResponseEntity<JsonResult> responseEntity = restTemplate.postForEntity(parseUrl, entity, JsonResult.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) { if (responseEntity.getStatusCode().is2xxSuccessful()) {
JsonResult body = responseEntity.getBody(); JsonResult body = responseEntity.getBody();
if (body != null && body.isSuccess()) { if (body != null && body.isSuccess()) {
Object data = body.getData(); Object data = body.getData();
if (data != null) { if (data != null) {
QuerySfpUserResponse userInfo = JSON.parseObject(JSON.toJSONString(data), QuerySfpUserResponse.class); QuerySfpUserResponse userInfo = JSON.parseObject(JSON.toJSONString(data), QuerySfpUserResponse.class);
String wxOpenId = userInfo.getWxOpenId(); if (userInfo.getId() == null) {
if (StringUtils.hasText(wxOpenId)) { log.error("远程解析返回的用户ID为空");
log.info("获取到用户 openid: {}", wxOpenId); throw new RuntimeException("用户信息不完整");
return wxOpenId;
} else {
log.error("用户信息中 wxOpenId 为空, sfpUserId={}", sfpUserId);
throw new RuntimeException("用户未绑定小程序 openid");
} }
log.info("远程解析 Token 成功,用户ID: {}, openid: {}", userInfo.getId(), userInfo.getWxOpenId());
return userInfo;
} }
} }
} }
log.error("调用 SFP 接口失败, response={}", responseEntity); log.error("远程解析 Token 失败, response={}", responseEntity);
throw new RuntimeException("获取用户信息失败"); throw new RuntimeException("获取用户信息失败");
} catch (Exception e) { } catch (Exception e) {
log.error("调用 SFP 查询用户接口异常", e); log.error("调用远程解析 Token 接口异常", e);
throw new RuntimeException("获取用户信息异常: " + e.getMessage()); throw new RuntimeException("获取用户信息异常: " + e.getMessage());
} }
} }
...@@ -159,15 +143,18 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService ...@@ -159,15 +143,18 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
return Result.fail("订阅记录列表为空"); return Result.fail("订阅记录列表为空");
} }
// 从 Token 中获取当前用户的 openid(所有记录共用同一个用户) // 从 Token 中获取当前用户的完整信息(所有记录共用同一个用户)
String openid; QuerySfpUserResponse userInfo;
try { try {
openid = getOpenidFromToken(); userInfo = getUserInfoFromToken();
} catch (Exception e) { } catch (Exception e) {
log.error("获取用户 openid 失败", e); log.error("获取用户信息失败", e);
return Result.fail("获取用户信息失败:" + e.getMessage()); return Result.fail("获取用户信息失败:" + e.getMessage());
} }
String openid = userInfo.getWxOpenId();
String userId = userInfo.getId().toString(); // Long -> String
List<SubscribeRecord> records = new ArrayList<>(); List<SubscribeRecord> records = new ArrayList<>();
for (SubscribeRecordDTO dto : dtoList) { for (SubscribeRecordDTO dto : dtoList) {
// 1. 根据 wxTemplateId 查询模板信息 // 1. 根据 wxTemplateId 查询模板信息
...@@ -188,6 +175,7 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService ...@@ -188,6 +175,7 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
record.setProjectType(dto.getProjectType()); record.setProjectType(dto.getProjectType());
record.setWxTemplateId(dto.getWxTemplateId()); record.setWxTemplateId(dto.getWxTemplateId());
record.setOpenid(openid); record.setOpenid(openid);
record.setUserId(userId); // 设置用户ID
record.setTemplateBizId(template.getTemplateBizId()); record.setTemplateBizId(template.getTemplateBizId());
record.setChannelBizId(template.getChannelBizId()); record.setChannelBizId(template.getChannelBizId());
...@@ -201,7 +189,7 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService ...@@ -201,7 +189,7 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
boolean success = subscribeRecordService.batchSave(records); boolean success = subscribeRecordService.batchSave(records);
if (success) { if (success) {
log.info("批量保存订阅记录成功, 数量={}", records.size()); log.info("批量保存订阅记录成功, 数量={}, 用户ID={}", records.size(), userId);
return Result.success(); return Result.success();
} else { } else {
log.error("批量保存订阅记录失败"); log.error("批量保存订阅记录失败");
...@@ -216,7 +204,8 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService ...@@ -216,7 +204,8 @@ public class ApiSubscribeRecordServiceImpl implements ApiSubscribeRecordService
// 从 Token 中获取当前用户的 openid // 从 Token 中获取当前用户的 openid
String openid; String openid;
try { try {
openid = getOpenidFromToken(); QuerySfpUserResponse userInfo = getUserInfoFromToken();
openid = userInfo.getWxOpenId();
} catch (Exception e) { } catch (Exception e) {
log.error("获取用户 openid 失败", e); log.error("获取用户 openid 失败", e);
return Result.fail("获取用户信息失败:" + e.getMessage()); return Result.fail("获取用户信息失败:" + e.getMessage());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment