外观偏好异步补齐D:设置页选择端双写服务端真源(fire-and-forget,本地体验不变)

- BaseApi 加三方法:getAppearance / saveMyTheme(紧凑编码,null=跟随)/ saveMyAvatarStyle
- Settings.vue 五个写键分支旁挂双写:pickMyTheme / followSchoolTheme(置 NULL) / pickMyAvatarStyle / followSchoolAvatar(置 NULL) / pickSide(写 yh-theme 的全部分支)
- 双写失败 console.warn 不弹错不回滚本地(本地体验与改造前逐字节一致)
- App.vue loadSchThemeDefault/loadSchAvatarDefault 保留不动(与 init 异步补齐幂等收敛)
- sync 件:UserAvatar.vue 监听 yh-appearance-updated + theme.ts 版本戳 20261008-1831-d9db725
- 注:本仓工作区另有并行会话 WIP(harness/命令面板),本提交只含本案文件与 hunks
This commit is contained in:
chenxing
2026-10-08 18:58:30 +08:00
parent b2307f583f
commit 4f36ff9ceb
4 changed files with 65 additions and 8 deletions
+29
View File
@@ -249,6 +249,35 @@ class Base extends Abstract {
return this.postRequest({ url });
}
// ===== 用户外观偏好(外观偏好服务端化 2026-10-08;后端契约见 AppearanceController)=====
/**
* 读当前用户外观偏好聚合:{myTheme, schTheme, avatarMy, avatarSch, logoUrl}(紧凑编码/绝对 URL,查不到为 null)。
* 各子应用 yh-theme-init 异步补齐段的同源数据源;选择端预留(本轮设置页双写用不到)。
*/
getAppearance() {
const url = path + "/appearance";
return this.getRequest<{
myTheme: string | null;
schTheme: string | null;
avatarMy: string | null;
avatarSch: string | null;
logoUrl: string | null;
}>({ url });
}
/** 保存用户自选主题档(紧凑编码 theme|sideDeep01|gradOn01|sideFollow01);null=跟随学校默认。设置页 fire-and-forget 双写:成功不提示、失败不回滚本地 */
saveMyTheme(themeState: string | null) {
const url = path + "/saveMyTheme";
return this.postRequest({ url, data: { themeState } as any });
}
/** 保存用户自选头像样式("text"|"silhouette");null=跟随学校默认。双写语义同 saveMyTheme */
saveMyAvatarStyle(avatarStyle: string | null) {
const url = path + "/saveMyAvatarStyle";
return this.postRequest({ url, data: { avatarStyle } as any });
}
savUserRole(info: any) {
const url = path + "/user/savUserRole";
return this.postRequest({ url, data: info as any });