Files
UserhomeService/src/main/java/com/yunhai/userhome/service/impl/SchSettingsServiceImpl.java
T
chenxing 0ac521f286
build / build-push (push) Successful in 3m18s
feat(appearance): 开放接口 GET /oapi/appearance(生效值合成)+ 级联下沉 service(oapi 代理轮)
- 新增 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 绿
2026-10-08 23:28:40 +08:00

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);
}
}