feat(壁纸): 三级默认壁纸——sch_settings.wallpaper_url 两级配置 + getUserSettings 兜底链(个人未自选:本校默认→平台默认→池内最新)(LOGO文字与主题JSON化增补)
build / build-push (push) Successful in 1m13s

This commit is contained in:
chenxing
2026-10-09 11:53:18 +08:00
parent f9282574e2
commit 1f352214f7
6 changed files with 166 additions and 3 deletions
@@ -181,6 +181,38 @@ public class SchSettingsController {
schSettingsService.save(schSettings);
}
// ===== 默认壁纸(平台/学校两级,壁纸三级默认轮 2026-10-09):与 LOGO 文字同模式 =====
/** 默认壁纸读(已登录可读):{wallpaperUrl: string|null, schId=实际命中层}。本校空 → 平台层 → null。 */
@GetMapping("schWallpaper")
public Map<String, Object> schWallpaper(BoaUser authUserWithDept) {
ISchSettingsService.LayerValue hit =
schSettingsService.readWallpaperWithFallback(schSettingsService.resolveThemeSchId(authUserWithDept, null));
Map<String, Object> out = new HashMap<>();
out.put("wallpaperUrl", hit.getValue());
out.put("schId", hit.getHitSchId());
return out;
}
/** 保存默认壁纸(仅学校管理员/超管):trim 后落本级(超管=平台层 0,校管=本校);空串存 null(=清空)。
* URL 为管理池返回的绝对地址原样存(与 user_settings.wallpaper_url 同口径),≤255。 */
@PostMapping("saveSchWallpaper")
public void saveSchWallpaper(BoaUser authUserWithDept,
@RequestParam("wallpaperUrl") String wallpaperUrl) {
requireThemeAdmin(authUserWithDept);
String url = wallpaperUrl == null ? "" : wallpaperUrl.trim();
if (url.length() > 255) {
throw new DException("壁纸地址不能超过 255 个字符");
}
Integer targetSchId = schSettingsService.resolveThemeSchId(authUserWithDept, null);
SchSettings schSettings = schSettingsService.findBySchIdRaw(targetSchId).orElseGet(SchSettings::new);
schSettings.setCDate(new Date());
schSettings.setSchId(targetSchId);
schSettings.setCId(authUserWithDept.getId());
schSettings.setWallpaperUrl(url.isEmpty() ? null : url);
schSettingsService.save(schSettings);
}
@PostMapping("saveSchTheme")
public void saveSchTheme(BoaUser authUserWithDept, String themeName, @RequestParam(name = "schId", defaultValue = "0") Integer schId) {
if (schId == null || schId == 0) {
@@ -16,6 +16,7 @@ import com.yunhai.userhome.enums.LightAppGroup;
import com.yunhai.userhome.enums.LinkOpenType;
import com.yunhai.userhome.model.AppIconEntryVo;
import com.yunhai.userhome.service.AppIconKeyService;
import com.yunhai.userhome.service.ISchSettingsService;
import com.yunhai.userhome.service.IUserCurrentRoleService;
import com.yunhai.userhome.service.IUserSettingsService;
import com.yunhai.userhome.service.UsedAppService;
@@ -52,6 +53,9 @@ public class UserSettingsController {
@Autowired
private IUserSettingsService userSettingsService;
@Autowired
private ISchSettingsService schSettingsService;
@Autowired
private IUserCurrentRoleService userCurrentRoleService;
@@ -305,13 +309,20 @@ public class UserSettingsController {
}
/**
* 兜底壁纸(用户未设置时):本地学校壁纸第一张 → 超管全局壁纸第一张。
* 兜底壁纸(用户未自选时,壁纸三级默认轮 2026-10-09):本校默认(sch_settings.wallpaper_url,管理员选定)
* → 平台默认(schId=0 行)→ 本地学校壁纸池最新一张 → 平台池最新一张(历史兜底,两级皆未配置时保持原体验)。
* <p>学校壁纸完全本地管理(wallpaper 表 type=1),不再依赖跨仓 schConfig。</p>
*/
private String resolveFallbackWallpaper(BoaUser authUserWithDept, Integer schId) {
// 1/2. 管理员选定的默认壁纸(本校 → 平台 级联,读侧 LayerValue)
ISchSettingsService.LayerValue wallHit = schSettingsService.readWallpaperWithFallback(schId);
if (wallHit.getValue() != null) {
return wallHit.getValue();
}
// 3/4. 历史兜底:壁纸池最新(校 type=1 → 平台 type=0)
List<Wallpaper> wallList = userSettingsService.findWallList(authUserWithDept.getId());
if (schId != null) {
// 1. 本地学校壁纸第一张(type=1,取最新)
// 3. 本地学校壁纸第一张(type=1,取最新)
Optional<Wallpaper> schWall = wallList.stream()
.filter(w -> w.getType() != null && w.getType() == 1
&& w.getSchId() != null && w.getSchId().equals(schId))
@@ -320,7 +331,7 @@ public class UserSettingsController {
return FILE_WEB_PATH + schWall.get().getWallpaperUrl().replace("/upload", "");
}
}
// 2. 超管全局壁纸第一张(type=0,取最新)
// 4. 超管全局壁纸第一张(type=0,取最新)
Optional<Wallpaper> sysWall = wallList.stream()
.filter(w -> w.getType() != null && w.getType() == 0)
.max(Comparator.comparing(Wallpaper::getId));
@@ -41,6 +41,11 @@ public class SchSettings {
@Column(name = "logo_text")
private String logoText;
/** 默认壁纸(壁纸三级默认轮 2026-10-09;绝对 URL,管理员从本级壁纸池选定;NULL=未配置回落上级。
* 个人未自选时生效链:本校默认 → 平台默认(schId=0 行)→ 壁纸池最新一张(历史兜底) */
@Column(name = "wallpaper_url")
private String wallpaperUrl;
@Column(name = "home_img_url")
private String homeImgUrl;
@@ -41,6 +41,9 @@ public interface ISchSettingsService {
/** LOGO 文字读侧级联(LOGO 文字轮 2026-10-09):本校空 → 平台层 → null。 */
LayerValue readLogoTextWithFallback(Integer schId);
/** 默认壁纸读侧级联(壁纸三级默认轮 2026-10-09):本校空 → 平台层 → null。 */
LayerValue readWallpaperWithFallback(Integer schId);
/** 级联读命中结果:{@code value}=命中的档位值(两级都无则 null),{@code hitSchId}=实际命中层的 schId
* (回落发生时是 0,不是解析出的本校 schId)。设置中心读端点的响应体 schId 即此语义——
* 前端据此区分「本校已配置」与「本校未配置、正在回落平台默认」。 */
@@ -115,6 +115,25 @@ public class SchSettingsServiceImpl implements ISchSettingsService {
.orElse(null);
}
@Override
public ISchSettingsService.LayerValue readWallpaperWithFallback(Integer schId) {
String url = readWallpaperAt(schId);
if (url != null || schId == null || schId == ISchSettingsService.PLATFORM_SCH_ID) {
return new ISchSettingsService.LayerValue(url, schId);
}
return new ISchSettingsService.LayerValue(readWallpaperAt(ISchSettingsService.PLATFORM_SCH_ID),
ISchSettingsService.PLATFORM_SCH_ID);
}
/** 原样读某层默认壁纸(查无行/空白 → null;trim 后存储口径,URL 为管理员从池中选定的原值) */
private String readWallpaperAt(Integer schId) {
return schSettingsRepository.findFirstBySchId(schId)
.map(SchSettings::getWallpaperUrl)
.map(String::trim)
.filter(s -> !s.isEmpty())
.orElse(null);
}
/** 原样读某层主题档并解码(查无行/旧格式/脏值 → null) */
private String decodeTheme(Integer schId) {
return schSettingsRepository.findFirstBySchId(schId)