From 47f9e3f751cc7ce69f089bd60d634781d0bacd03 Mon Sep 17 00:00:00 2001 From: chenxing Date: Fri, 9 Oct 2026 17:08:00 +0800 Subject: [PATCH] =?UTF-8?q?feat(appearance):=20/oapi/appearance=20?= =?UTF-8?q?=E5=87=BA=E5=8F=82=E6=91=98=E9=99=A4=20logoText=EF=BC=88?= =?UTF-8?q?=E5=AD=90=E5=BA=94=E7=94=A8=20header=20=E5=AE=9A=E7=A8=BF?= =?UTF-8?q?=E5=8F=AA=E5=87=BA=20logo=20=E5=9B=BE=EF=BC=8C=E9=97=A8?= =?UTF-8?q?=E6=88=B7=E6=96=87=E5=AD=97=E8=B5=B0=20/api/schLogoText=20?= =?UTF-8?q?=E8=87=AA=E6=9C=89=E9=93=BE=EF=BC=9Binit=20=E4=BE=A7=E7=BC=BA?= =?UTF-8?q?=E5=A4=B1=E5=AD=97=E6=AE=B5=E8=87=AA=E5=8A=A8=E6=B8=85=20yh-log?= =?UTF-8?q?o-text=EF=BC=89=E2=80=94=E2=80=94=E5=87=BA=E5=8F=82=E6=81=B0?= =?UTF-8?q?=E4=B8=89=E5=AD=97=E6=AE=B5=20{theme,avatar,logoUrl}=EF=BC=8C?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=AF=B9=E9=BD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oapi/OapiAppearanceController.java | 3 ++- .../service/impl/AppearanceServiceImpl.java | 12 +++++------ .../service/AppearanceServiceTest.java | 20 +++++++------------ 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/yunhai/userhome/controller/oapi/OapiAppearanceController.java b/src/main/java/com/yunhai/userhome/controller/oapi/OapiAppearanceController.java index 82e9ea1..2077ec2 100644 --- a/src/main/java/com/yunhai/userhome/controller/oapi/OapiAppearanceController.java +++ b/src/main/java/com/yunhai/userhome/controller/oapi/OapiAppearanceController.java @@ -16,7 +16,8 @@ import java.util.Map; * 强制(/oapi/* 无签名 401);appKey 准入归网关台账/限流管,本应用不维护 per-app 白名单。 * *

出参 = 当前用户【生效值】{@code {theme, avatar, logoUrl}}(个人 → 学校 → 平台级联合成, - * 层级知识留在 UserHome 内部不外露;null=未配置,消费端 init 侧清对应本地键回落默认观感)。 + * 层级知识留在 UserHome 内部不外露;null=未配置,消费端 init 侧清对应本地键回落默认观感; + * logoText 已于 2026-10-09 定稿摘除——子应用不再消费 LOGO 文字,门户走 /api/schLogoText 自有链)。 * 返回裸 payload(平台 oapi 无信封包装),消费端整体透传给浏览器。

*/ @RestController diff --git a/src/main/java/com/yunhai/userhome/service/impl/AppearanceServiceImpl.java b/src/main/java/com/yunhai/userhome/service/impl/AppearanceServiceImpl.java index ec8c460..f9e81c3 100644 --- a/src/main/java/com/yunhai/userhome/service/impl/AppearanceServiceImpl.java +++ b/src/main/java/com/yunhai/userhome/service/impl/AppearanceServiceImpl.java @@ -89,9 +89,11 @@ public class AppearanceServiceImpl implements IAppearanceService { } /** - * 当前用户生效外观(oapi 代理轮 2026-10-08,{@code /oapi/appearance} 出参真源;2026-10-09 JSON 化+LOGO 文字): - * {@code {theme, avatar, logoText, logoUrl}}——theme 为【JSON 对象】(个人自选 → 学校默认 → 平台默认(schId=0) - * 级联,层级知识留在 UserHome 内部,对外不拆 my/sch);avatar 为生效样式;logoText 本校→平台级联; + * 当前用户生效外观(oapi 代理轮 2026-10-08,{@code /oapi/appearance} 出参真源;2026-10-09 JSON 化; + * 同日定稿摘除 logoText——子应用 header 定稿只出 logo 图,文字仅门户消费且走 /api/schLogoText 自有链, + * init 侧对缺失字段按 null 语义自动清 yh-logo-text 本地键): + * {@code {theme, avatar, logoUrl}}——theme 为【JSON 对象】(个人自选 → 学校默认 → 平台默认(schId=0) + * 级联,层级知识留在 UserHome 内部,对外不拆 my/sch);avatar 为生效样式; * logoUrl 为本校 type=1 → 平台 type=0 择优。 * *

schId 解析走本地 user_current_role(oapi 入参只有 userId,不引 identity 跨仓):roleId 当前角色学校, @@ -103,7 +105,6 @@ public class AppearanceServiceImpl implements IAppearanceService { Map out = new HashMap<>(); out.put("theme", null); out.put("avatar", null); - out.put("logoText", null); out.put("logoUrl", null); if (userId == null) { return out; @@ -132,10 +133,9 @@ public class AppearanceServiceImpl implements IAppearanceService { if (avatar == null) { avatar = schSettingsService.readAvatarWithFallback(schId).getValue(); } - out.put("logoText", schSettingsService.readLogoTextWithFallback(schId).getValue()); out.put("logoUrl", resolveLogoUrl(schId)); } catch (Exception e) { - // 学校/平台段降级:theme/avatar/logoText/logoUrl 保持已得值或 null + // 学校/平台段降级:theme/avatar/logoUrl 保持已得值或 null } // theme 出 JSON 对象(2026-10-09 契约);值已过 decodeThemeState 校验,解析失败按 null 降级 out.put("theme", theme == null ? null : ThemeCodec.toJsonNode(theme)); diff --git a/src/test/java/com/yunhai/userhome/service/AppearanceServiceTest.java b/src/test/java/com/yunhai/userhome/service/AppearanceServiceTest.java index 634113d..69d2350 100644 --- a/src/test/java/com/yunhai/userhome/service/AppearanceServiceTest.java +++ b/src/test/java/com/yunhai/userhome/service/AppearanceServiceTest.java @@ -257,14 +257,15 @@ class AppearanceServiceTest { assertTrue(theme.get("sideDeep").asBoolean()); assertFalse(theme.get("gradOn").asBoolean()); assertEquals("silhouette", out.get("avatar")); - assertNull(out.get("logoText")); + assertFalse(out.containsKey("logoText"), "logoText 已定稿摘除(子应用不消费 LOGO 文字)"); assertNull(out.get("logoUrl")); verify(schSettingsService, never()).readThemeWithFallback(any()); verify(schSettingsService, never()).readAvatarWithFallback(any()); + verify(schSettingsService, never()).readLogoTextWithFallback(any()); } @Test - @DisplayName("生效值:个人未设 → 学校/平台级联(theme 出 JSON 对象)+ logoText 本校→平台级联") + @DisplayName("生效值:个人未设 → 学校/平台级联(theme 出 JSON 对象),出参恰三字段") void effective_fallsToCascade() { stubCurrentRole(3); when(userAppearanceRepository.findByUserId(10133)).thenReturn(Optional.empty()); @@ -272,8 +273,6 @@ class AppearanceServiceTest { .thenReturn(new ISchSettingsService.LayerValue("{\"theme\":\"ink\",\"sideDeep\":false,\"gradOn\":true,\"sideFollow\":false}", 0)); when(schSettingsService.readAvatarWithFallback(3)) .thenReturn(new ISchSettingsService.LayerValue("text", 3)); - when(schSettingsService.readLogoTextWithFallback(3)) - .thenReturn(new ISchSettingsService.LayerValue("云海教育平台", 0)); when(logoRepository.findBySchIdAndType(any(), any())).thenReturn(Collections.emptyList()); Map out = service.getEffectiveAppearance(10133); @@ -282,11 +281,9 @@ class AppearanceServiceTest { assertFalse(theme.get("sideDeep").asBoolean()); assertTrue(theme.get("gradOn").asBoolean()); assertEquals("text", out.get("avatar"), "本校已配直接生效(hitSchId=本校)"); - assertEquals("云海教育平台", out.get("logoText"), "logoText 本校空→平台层"); - // 出参只四字段,不外露 my/sch 拆分 - assertEquals(4, out.size()); - assertTrue(out.containsKey("theme") && out.containsKey("avatar") - && out.containsKey("logoText") && out.containsKey("logoUrl")); + // 出参只三字段(logoText 已摘),不外露 my/sch 拆分 + assertEquals(3, out.size()); + assertTrue(out.containsKey("theme") && out.containsKey("avatar") && out.containsKey("logoUrl")); } @Test @@ -301,16 +298,13 @@ class AppearanceServiceTest { .thenReturn(new ISchSettingsService.LayerValue(null, 0)); when(schSettingsService.readAvatarWithFallback(0)) .thenReturn(new ISchSettingsService.LayerValue(null, 0)); - when(schSettingsService.readLogoTextWithFallback(0)) - .thenReturn(new ISchSettingsService.LayerValue(null, 0)); when(logoRepository.findBySchIdAndType(any(), any())).thenReturn(Collections.emptyList()); Map out = service.getEffectiveAppearance(10133); assertNull(out.get("theme"), "脏值落级联且两级皆无 → null"); assertNull(out.get("avatar")); - assertNull(out.get("logoText")); assertNull(out.get("logoUrl")); - assertEquals(4, out.size()); + assertEquals(3, out.size()); verify(schSettingsService).readThemeWithFallback(0); verify(schSettingsService).readAvatarWithFallback(0); }