feat(user): 本人联系方式修改端点 POST /{platform}/user/UpdateContact——登录态取 userId(防替改),YschOpenCall Tier0 直调 UserBase /oapi/user/self/contact(服务目录取址+信封异常透传,零新增配置项);业务错误 DException 冒泡原样包信封,UserBase 不可达收口友好提示;成功返回最新 BoaUser 供前端刷新 store(任务B·UserHome 侧)

This commit is contained in:
chenxing
2026-10-02 08:54:45 +08:00
parent f2166c007b
commit a3aa6d917e
@@ -3,6 +3,8 @@ package com.yunhai.userhome.controller.api;
import com.yunhai.platform.apistd.BizException;
import com.yunhai.platform.openapi.base.OpenApiUserClient;
import com.yunhai.platform.openapi.base.YschBaseOpenApi;
import com.yunhai.platform.openapi.core.OpenApiException;
import com.yunhai.platform.openapi.core.YschOpenCall;
import com.yunhai.platform.utils.exception.ErrorCode;
import com.yunhai.platform.utils.model.BoaApp;
import com.yunhai.platform.utils.model.BoaAppType;
@@ -10,6 +12,8 @@ import com.yunhai.platform.utils.model.BoaRoleInfo;
import com.yunhai.platform.utils.model.BoaUser;
import com.yunhai.userhome.config.Config;
import com.yunhai.userhome.service.AppRemoteService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@@ -18,7 +22,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* 用户首页接口(CAS 登录态,路径 {@code /{platform}/user/})。
@@ -28,12 +34,20 @@ import java.util.List;
@RequestMapping(value = Config.API_PATH + "/user/")
public class UserController {
private static final Logger log = LoggerFactory.getLogger(UserController.class);
/** 服务目录目标名:userbase(yh.open.services / 枚举兜底 = base-host + /userbase,与 MsgCenterProxyService 同口径) */
private static final String TARGET_USERBASE = "userbase";
@Autowired
private AppRemoteService appRemoteService;
@Autowired
private OpenApiUserClient openApiUserClient;
@Autowired
private YschOpenCall openCall;
/** 当前登录用户信息(CAS 注入)。 */
@GetMapping("GetUserInfo")
@@ -92,4 +106,43 @@ public class UserController {
}
openApiUserClient.switchIdentity(authUserWithDept.getId(), roleInfo.getRoleId(), roleInfo.getSchId());
}
/**
* 本人联系方式修改(手机号/邮箱):body {phone, email},userId 只取 CAS 会话(无视请求体,防替改他人),
* 经 {@link YschOpenCall} 泛化签名直调(Tier 0)转发 UserBase {@code POST /oapi/user/self/contact}
* (与 MsgCenterProxyService 直调 userbase 同范式:服务目录按名取址 + 信封异常透传,零新增配置项)。
* <ul>
* <li>phone/email 至少一项非空(前端与 UserBase 侧同口径校验,此处仅挡空请求);</li>
* <li>UserBase 业务失败(格式/查重等)以 DException(code,msg) 冒泡,由 GlobalExceptionHandler
* 原样包成信封返回(msg 即「手机号已被其他用户使用」等明确错误);</li>
* <li>UserBase 不可达(ioError/验签失败等 OpenApiException)收口为友好提示,不抛 500 裸栈;</li>
* <li>成功返回 UserBase 更新后的最新 {@link BoaUser}(含新 phone/email/groups),前端以此
* 覆盖 store.userInfo,规避 CAS principal 缓存导致的旧值回显。</li>
* </ul>
*/
@PostMapping("UpdateContact")
public BoaUser updateContact(BoaUser authUserWithDept, @RequestBody Map<String, String> body) {
String phone = body == null ? null : body.get("phone");
String email = body == null ? null : body.get("email");
boolean phoneBlank = phone == null || phone.trim().isEmpty();
boolean emailBlank = email == null || email.trim().isEmpty();
if (phoneBlank && emailBlank) {
throw new BizException(ErrorCode.PARAM_ERROR, "手机号与邮箱至少填写一项");
}
Map<String, String> payload = new LinkedHashMap<>();
payload.put("userId", String.valueOf(authUserWithDept.getId()));
if (!phoneBlank) {
payload.put("phone", phone.trim());
}
if (!emailBlank) {
payload.put("email", email.trim());
}
try {
return openCall.post(TARGET_USERBASE, "/oapi/user/self/contact", null, payload, BoaUser.class);
} catch (OpenApiException e) {
log.warn("[user] UpdateContact 直调 UserBase 失败 userId={}:{}", authUserWithDept.getId(), e.toString());
throw new BizException(ErrorCode.CUSTOM, "用户中心暂不可达,请稍后重试");
}
// DException(UserBase 业务错误,code!=0)刻意冒泡:GlobalExceptionHandler 按原 code/msg 包信封
}
}