refactor(svcitem): 目录键归一 svchall→svc-hall(D1)——服务目录键/legacy 私有键 yh.svchall.base-url→yh.svc-hall.base-url(值域=部署名锚点),javadoc/测试/测试 yml 同步;Java 包名 com.yunhai.svchall 按惯例保留
build / build-push (push) Successful in 1m18s

This commit is contained in:
chenxing
2026-09-28 17:32:31 +08:00
parent da39bb5066
commit f591d06c35
5 changed files with 22 additions and 22 deletions
@@ -15,7 +15,7 @@ import java.util.Map;
/**
* 办事大厅开放接口客户端(V2.0 Part C.3):经 SDK {@link YschOpenCall} 命名目标
* {@code svchall}(服务目录 {@code yh.open.services.svchall})调 svc-hall {@code /oapi/svc/**};
* {@code svc-hall}(服务目录 {@code yh.open.services.svc-hall})调 svc-hall {@code /oapi/svc/**};
* 出站签名/信封解包/错误映射全部由 SDK 承载——本应用零专属地址配置
* (《子应用配置优化方案》§4.2)。<br><br>
* <b>为何不能再用共享 {@code IDHttp}</b>:svc-hall 带 context-path {@code /svc-hall},而共享
@@ -26,7 +26,7 @@ import java.util.Map;
* <b>错误语义</b>:业务失败信封 {@code code!=0} → {@code DException}(携带 OpenApiErrorCode,
* 办事大厅"不存在/未发布"= code 2);传输/HTTP 失败 → {@code OpenApiException};401/403 →
* {@code DException("验签失败")}。降级判定见 {@code SvcItemRemoteQuery}。<br><br>
* 目录未显式配置时回落 legacy {@code yh.svchall.base-url}(迁移期兼容);两者皆无则构造期
* 目录未显式配置时回落 legacy {@code yh.svc-hall.base-url}(迁移期兼容);两者皆无则构造期
* fail-fast——不给"沉默连不上 localhost"的假象。
*/
@Component
@@ -35,9 +35,9 @@ public class SvcHallClient {
private static final Logger log = LoggerFactory.getLogger(SvcHallClient.class);
/** 服务目录命名目标(svc-hall 未晋升 PlatformService 枚举,按名直调) */
static final String DIRECTORY_KEY = "svchall";
static final String DIRECTORY_KEY = "svc-hall";
private static final String LEGACY_KEY = "yh.svchall.base-url";
private static final String LEGACY_KEY = "yh.svc-hall.base-url";
private final YschOpenCall openCall;
private final IDHttp http;
@@ -46,7 +46,7 @@ public class SvcHallClient {
public SvcHallClient(YschOpenCall openCall,
IDHttp http,
@Value("${yh.svchall.base-url:}") String baseUrl) {
@Value("${yh.svc-hall.base-url:}") String baseUrl) {
this.openCall = openCall;
this.http = http;
this.directoryResolved = openCall != null && openCall.hasTarget(DIRECTORY_KEY);
+3 -3
View File
@@ -74,11 +74,11 @@ yh:
# per-target base-path 与提供方 context-path 对齐 → 签名天然一致)。
# 容器直连形态(生产):http://svc-hall-service:10007/svc-hall(网关无 /oapi 路由)。
services:
svchall: http://localhost:8086
svc-hall: http://localhost:8086
# 办事大厅(svc-hall)对接(V2.0 Part C.3):门户 service/guide 数据源。
# 双向信任:CMS 出站签名用 yh.app-auth 身份(appKey=100005,办事大厅侧须在 UserBase
# 注册表内可用);入站收 svc-hall 站点目录调用(appKey=100018,见上方 trusted-apps)。
# 地址不再单独配置:见上方 yh.open.services.svchall(原 yh.svchall.base-url 已删)。
# 地址不再单独配置:见上方 yh.open.services.svc-hall(私有 legacy 回落键已随 D1 目录键归一同步改名)。
# env-config 管理端运行时配置(免登录 GET /api/env-config?target=admin,数据源见
# config/PropertyEnvConfigSource:聚合 starter 自动装配,有 bean 即注册端点)。
# 本地无需配值(前端 dev 走 .env.dev);线上值经环境变量 YH_ENV_CONFIG_SOURCE_ADMIN
@@ -104,7 +104,7 @@ cms:
item:
# 【V2.0 拆分遗留说明】事项库已迁独立"办事大厅"应用(svc-hall),CMS 侧 SvcItemQuery
# 由 SvcItemRemoteQuery 经 oapi 调办事大厅;本配置已废弃(部门口径归办事大厅
# svchall.item.dept-group-type)。保留注释防误解。
# svc-hall.item.dept-group-type)。保留注释防误解。
dept-group-type: 7
@@ -224,7 +224,7 @@ class SiteServiceIT extends CmsIntegrationTestBase {
@DisplayName("事项库 svc_hall_base:非完整 http(s) URL 拒绝、合法 URL 放行(§3.7 显式 case)")
void save_svcHallBaseUrlValidation() {
SiteSaveRequest base = new SiteSaveRequest();
base.setCode("svchall");
base.setCode("svc-hall");
base.setSchId(1);
base.setName("服务大厅配置站");
@@ -26,20 +26,20 @@ import static org.mockito.Mockito.when;
/**
* CMS → 办事大厅(svc-hall)出站契约测试:跨服务调用统一走 SDK {@link YschOpenCall} 命名目标
* {@code svchall}(服务目录 {@code yh.open.services.svchall}),应用内不再保留专属地址键
* {@code yh.svchall.base-url}(《子应用配置优化方案》§4.2 零专属地址配置)。<br><br>
* {@code svc-hall}(服务目录 {@code yh.open.services.svc-hall}),应用内不再保留专属地址键
* {@code yh.svc-hall.base-url}(《子应用配置优化方案》§4.2 零专属地址配置)。<br><br>
* 迁移动机(此前是四个服务里唯一手搓 URL 的跨服务主链路):共享 {@code IDHttp} 的签名拦截器只剥
* {@code yh.open.base-path}(本应用=/userbase),而 svc-hall 部署带 context-path
* {@code /svc-hall}——手工拼出的 URL 会被签成 {@code /svc-hall/oapi/...},服务端剥掉 ctx 后
* 两侧 target 不一致,**必然 401**。{@link YschOpenCall} 的 per-target base-path 与提供方
* context-path 对齐(同 svc-hall {@code CmsSiteDirectoryImpl} 的既有范式)。<br><br>
* 目录未显式配置时回落 legacy {@code yh.svchall.base-url}(迁移期兼容);两者皆无则构造期
* 目录未显式配置时回落 legacy {@code yh.svc-hall.base-url}(迁移期兼容);两者皆无则构造期
* fail-fast,不给"沉默连不上 localhost"的假象。
*/
@DisplayName("SvcHallClient - 走 SDK 服务目录(svchall)与 legacy 回落")
@DisplayName("SvcHallClient - 走 SDK 服务目录(svc-hall)与 legacy 回落")
class SvcHallClientTest {
private static final String TARGET = "svchall";
private static final String TARGET = "svc-hall";
private static final String LEGACY_BASE = "http://svc-hall-service:10007/svc-hall";
private final ObjectMapper objectMapper = new ObjectMapper();
@@ -65,7 +65,7 @@ class SvcHallClientTest {
}
@Test
@DisplayName("目录已配 svchall:items 走命名目标 + 查询参数齐全,IDHttp 零交互")
@DisplayName("目录已配 svc-hall:items 走命名目标 + 查询参数齐全,IDHttp 零交互")
void items_usesDirectoryTarget() {
when(openCall.hasTarget(TARGET)).thenReturn(true);
when(openCall.get(eq(TARGET), eq("/oapi/svc/items"), anyMap(), eq(JsonNode.class)))
@@ -90,7 +90,7 @@ class SvcHallClientTest {
}
@Test
@DisplayName("目录已配 svchall:空参数不下发(保持原 append 语义)")
@DisplayName("目录已配 svc-hall:空参数不下发(保持原 append 语义)")
void items_omitsBlankOptionalParams() {
when(openCall.hasTarget(TARGET)).thenReturn(true);
when(openCall.get(eq(TARGET), eq("/oapi/svc/items"), anyMap(), eq(JsonNode.class)))
@@ -110,7 +110,7 @@ class SvcHallClientTest {
}
@Test
@DisplayName("目录已配 svchall:detail 走命名目标(itemId 口径)")
@DisplayName("目录已配 svc-hall:detail 走命名目标(itemId 口径)")
void detail_usesDirectoryTarget() {
when(openCall.hasTarget(TARGET)).thenReturn(true);
when(openCall.get(eq(TARGET), eq("/oapi/svc/item/detail"), anyMap(), eq(JsonNode.class)))
@@ -126,7 +126,7 @@ class SvcHallClientTest {
}
@Test
@DisplayName("目录已配 svchall:浏览量累加 fire-and-forget(出站失败不得冒泡)")
@DisplayName("目录已配 svc-hall:浏览量累加 fire-and-forget(出站失败不得冒泡)")
void view_isFireAndForget() {
when(openCall.hasTarget(TARGET)).thenReturn(true);
when(openCall.post(eq(TARGET), eq("/oapi/svc/item/view"), anyMap(), eq(null), eq(JsonNode.class)))
@@ -151,7 +151,7 @@ class SvcHallClientTest {
}
@Test
@DisplayName("目录未配:回落 legacy yh.svchall.base-url(迁移期兼容)")
@DisplayName("目录未配:回落 legacy yh.svc-hall.base-url(迁移期兼容)")
void fallsBackToLegacyBaseUrl() {
when(openCall.hasTarget(TARGET)).thenReturn(false);
when(http.get(anyString(), eq(JsonNode.class))).thenReturn(payload());
@@ -176,7 +176,7 @@ class SvcHallClientTest {
IllegalStateException e = assertThrows(IllegalStateException.class,
() -> new SvcHallClient(openCall, http, ""));
assertTrue(e.getMessage().contains("yh.open.services." + TARGET), e.getMessage());
assertTrue(e.getMessage().contains("yh.svchall.base-url"), e.getMessage());
assertTrue(e.getMessage().contains("yh.svc-hall.base-url"), e.getMessage());
}
@Test
+2 -2
View File
@@ -63,10 +63,10 @@ yh:
open:
base-host: http://base.yunhaixingtong.com
base-path: /userbase
# 服务目录:SvcHallClient 构造期要求「目录键 或 legacy yh.svchall.base-url」至少一个
# 服务目录:SvcHallClient 构造期要求「目录键 或 legacy yh.svc-hall.base-url」至少一个
# (两者都缺即 fail-fast)——IT 起 Spring 上下文时必须有值。
services:
svchall: http://localhost:8086
svc-hall: http://localhost:8086
cms:
# 超管判定:BoaUser.type == 1(夹具 TestUsers.superAdmin 已对齐);校级角色经 BoaRoleInfo.schId 匹配