build / build-push (push) Successful in 3m18s
- 新增 controller/oapi/OapiAppearanceController:userId 入参,出参 {theme, avatar, logoUrl} 当前用户生效值
(个人→学校→平台级联合成,层级知识不外露);出参裸 payload,Map 禁 String
- readThemeWithFallback/readAvatarWithFallback 从 SchSettingsController 下沉 ISchSettingsService(行为等价),
供 schTheme 读端点与 oapi 合成共享——顺带修复「appearance 无学校→平台级联」审计缺陷 C
- OpenApiAuthEnforceConfiguration:/oapi/* 强制应用签名(无签名 401,对齐 UserMsg/UserBase 同名配置)
- oapi schId 解析走本地 user_current_role(不引 identity 跨仓);超管临时切校角色场景与 /api 版有差,登记偏差
- 单测:生效值合成 3 例(个人优先不触级联/级联命中/脏值+无角色落平台层),60/60 绿
115 lines
4.2 KiB
Java
115 lines
4.2 KiB
Java
package com.yunhai.userhome.service.impl;
|
|
|
|
import com.yunhai.platform.utils.model.BoaUser;
|
|
import com.yunhai.userhome.entity.SchSettings;
|
|
import com.yunhai.userhome.entity.UserCurrentRole;
|
|
import com.yunhai.userhome.repository.SchSettingsRepository;
|
|
import com.yunhai.userhome.service.ISchSettingsService;
|
|
import com.yunhai.userhome.service.IUserCurrentRoleService;
|
|
import com.yunhai.userhome.utils.ThemeCodec;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import java.util.Optional;
|
|
|
|
/**
|
|
* 学校设置服务:学校设置完全本地化(sch_settings 表),不再依赖跨仓 schConfig。
|
|
* <p>findBySchId 直接查本地表,查不到兜底默认主题;saveSchTheme/saveSchLogo 写本地表即可闭环。</p>
|
|
*/
|
|
@Service
|
|
public class SchSettingsServiceImpl implements ISchSettingsService {
|
|
|
|
@Autowired
|
|
private SchSettingsRepository schSettingsRepository;
|
|
|
|
@Autowired
|
|
private IUserCurrentRoleService userCurrentRoleService;
|
|
|
|
@Override
|
|
public void save(SchSettings schSettings) {
|
|
schSettingsRepository.save(schSettings);
|
|
}
|
|
|
|
@Override
|
|
public Optional<SchSettings> findBySchIdRaw(Integer schId) {
|
|
return schSettingsRepository.findFirstBySchId(schId);
|
|
}
|
|
|
|
@Override
|
|
public Optional<SchSettings> findBySchId(Integer schId) {
|
|
Optional<SchSettings> local = schSettingsRepository.findFirstBySchId(schId);
|
|
if (local.isPresent()) {
|
|
return local;
|
|
}
|
|
SchSettings def = new SchSettings();
|
|
def.setSchId(schId);
|
|
def.setThemeName("default-theme");
|
|
def.setAppBgUrl("");
|
|
def.setLogoUrl("");
|
|
return Optional.of(def);
|
|
}
|
|
|
|
@Override
|
|
public java.util.List<SchSettings> findBySchIds(java.util.List<Integer> schId) {
|
|
return schSettingsRepository.getSchSettingList(schId);
|
|
}
|
|
|
|
@Override
|
|
public Integer resolveSchId(BoaUser user) {
|
|
if (user.getSchool() != null) {
|
|
return user.getSchool().getId();
|
|
}
|
|
if (user.getBureau() != null) {
|
|
return user.getBureau().getId();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public Integer resolveThemeSchId(BoaUser user, Integer explicitSchId) {
|
|
if (user.getType() != null && user.getType() == 1) {
|
|
return explicitSchId == null ? 0 : explicitSchId;
|
|
}
|
|
return userCurrentRoleService.findById(user.getId())
|
|
.map(UserCurrentRole::getSchId)
|
|
.filter(schId -> schId != null && schId > 0)
|
|
.orElseGet(() -> resolveSchId(user));
|
|
}
|
|
|
|
@Override
|
|
public ISchSettingsService.LayerValue readThemeWithFallback(Integer schId) {
|
|
String themeState = decodeTheme(schId);
|
|
if (themeState != null || schId == null || schId == ISchSettingsService.PLATFORM_SCH_ID) {
|
|
return new ISchSettingsService.LayerValue(themeState, schId);
|
|
}
|
|
return new ISchSettingsService.LayerValue(decodeTheme(ISchSettingsService.PLATFORM_SCH_ID),
|
|
ISchSettingsService.PLATFORM_SCH_ID);
|
|
}
|
|
|
|
@Override
|
|
public ISchSettingsService.LayerValue readAvatarWithFallback(Integer schId) {
|
|
String avatarStyle = readAvatarAt(schId);
|
|
if (avatarStyle != null || schId == null || schId == ISchSettingsService.PLATFORM_SCH_ID) {
|
|
return new ISchSettingsService.LayerValue(avatarStyle, schId);
|
|
}
|
|
return new ISchSettingsService.LayerValue(readAvatarAt(ISchSettingsService.PLATFORM_SCH_ID),
|
|
ISchSettingsService.PLATFORM_SCH_ID);
|
|
}
|
|
|
|
/** 原样读某层主题档并解码(查无行/旧格式/脏值 → null) */
|
|
private String decodeTheme(Integer schId) {
|
|
return schSettingsRepository.findFirstBySchId(schId)
|
|
.map(SchSettings::getThemeName)
|
|
.map(ThemeCodec::decodeThemeState)
|
|
.orElse(null);
|
|
}
|
|
|
|
/** 原样读某层头像样式(查无行/非法值 → null) */
|
|
private String readAvatarAt(Integer schId) {
|
|
return schSettingsRepository.findFirstBySchId(schId)
|
|
.map(SchSettings::getAvatarStyle)
|
|
.filter(ThemeCodec::isAvatarStyle)
|
|
.orElse(null);
|
|
}
|
|
}
|