From 977b5c90a428e849fc1cd6be773a9edbeef7d238 Mon Sep 17 00:00:00 2001 From: chenxing Date: Fri, 9 Oct 2026 14:53:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E5=A3=81=E7=BA=B8):=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E9=80=89=E4=B8=AD=E5=A3=81=E7=BA=B8=E5=90=8E=E7=99=BD=E6=9D=BF?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E2=80=94=E2=80=94=E5=88=A0=E9=99=A4=E6=B8=85?= =?UTF-8?q?=E7=90=86=E6=8C=89=20raw+=E5=B1=95=E7=A4=BA=E5=8F=8C=E5=BD=A2?= =?UTF-8?q?=E6=80=81=E5=8C=B9=E9=85=8D=E3=80=81getUserSettings=20=E6=82=AC?= =?UTF-8?q?=E7=A9=BA=E5=BC=95=E7=94=A8=E8=87=AA=E6=84=88=E5=9B=9E=E8=90=BD?= =?UTF-8?q?=E5=85=9C=E5=BA=95=E9=93=BE=E3=80=81=E7=AE=A1=E7=90=86=E5=91=98?= =?UTF-8?q?=E9=80=89=E5=AE=9A=E9=BB=98=E8=AE=A4=E8=A2=AB=E5=88=A0=E6=B1=A0?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=B7=B3=E8=BF=87=E3=80=81=E6=B1=A0=E5=85=9C?= =?UTF-8?q?=E5=BA=95=E6=94=B9=E5=8F=96=E7=AC=AC=E4=B8=80=E5=BC=A0=EF=BC=88?= =?UTF-8?q?min=20id=EF=BC=8C=E4=B8=8E=E7=94=A8=E6=88=B7=E5=8F=A3=E5=BE=84?= =?UTF-8?q?=E5=8F=8A=E5=8E=9F=E6=B3=A8=E9=87=8A=E4=B8=80=E8=87=B4=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/UserSettingsController.java | 32 ++++++++++++------- .../repository/UserSettingsRepository.java | 7 ++-- .../service/impl/UserSettingsServiceImpl.java | 11 +++++-- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/yunhai/userhome/controller/api/UserSettingsController.java b/src/main/java/com/yunhai/userhome/controller/api/UserSettingsController.java index 1a69959..57db3bb 100644 --- a/src/main/java/com/yunhai/userhome/controller/api/UserSettingsController.java +++ b/src/main/java/com/yunhai/userhome/controller/api/UserSettingsController.java @@ -292,8 +292,16 @@ public class UserSettingsController { // List appPageList = bschBaseOpenApi.getPcGrzxPage(authUserWithDept.getId(), schId); List appPageList = Collections.emptyList(); if (optional.isPresent()) model = optional.get(); + // 壁纸池一次取全:悬空自愈判定与兜底选择共用 + List wallList = userSettingsService.findWallList(authUserWithDept.getId()); + // 悬空引用自愈:自选壁纸已被删除(删除清理修复前的存量脏数据)时视为未自选,避免返回死 URL 白板 + String chosenUrl = normalizeWallpaperUrl(model.getWallpaperUrl()); + if (model.getWallpaperUrl() != null && !model.getWallpaperUrl().isEmpty() + && wallList.stream().noneMatch(w -> chosenUrl != null && chosenUrl.equals(w.getWallpaperUrl()))) { + model.setWallpaperUrl(null); + } if (model.getWallpaperUrl() == null || model.getWallpaperUrl().isEmpty()) { - model.setWallpaperUrl(resolveFallbackWallpaper(authUserWithDept, schId)); + model.setWallpaperUrl(resolveFallbackWallpaper(authUserWithDept, schId, wallList)); } List mapList = appPageList.stream().map(boaApp -> { Map map = new HashMap<>(); @@ -310,31 +318,33 @@ public class UserSettingsController { /** * 兜底壁纸(用户未自选时,壁纸三级默认轮 2026-10-09):本校默认(sch_settings.wallpaper_url,管理员选定) - * → 平台默认(schId=0 行)→ 本地学校壁纸池最新一张 → 平台池最新一张(历史兜底,两级皆未配置时保持原体验)。 - *

学校壁纸完全本地管理(wallpaper 表 type=1),不再依赖跨仓 schConfig。

+ * → 平台默认(schId=0 行)→ 本地学校壁纸池第一张 → 平台池第一张(历史兜底,两级皆未配置时保持原体验)。 + *

学校壁纸完全本地管理(wallpaper 表 type=1),不再依赖跨仓 schConfig。 + * 管理员选定默认返回前校验其仍在壁纸池中——被删池视为未配置继续下落,避免兜底本身返回死 URL(2026-10-09 白板修复)。

*/ - private String resolveFallbackWallpaper(BoaUser authUserWithDept, Integer schId) { + private String resolveFallbackWallpaper(BoaUser authUserWithDept, Integer schId, List wallList) { + Set poolUrls = new HashSet<>(); + wallList.forEach(w -> poolUrls.add(w.getWallpaperUrl())); // 1/2. 管理员选定的默认壁纸(本校 → 平台 级联,读侧 LayerValue) ISchSettingsService.LayerValue wallHit = schSettingsService.readWallpaperWithFallback(schId); - if (wallHit.getValue() != null) { + if (wallHit.getValue() != null && poolUrls.contains(normalizeWallpaperUrl(wallHit.getValue()))) { return wallHit.getValue(); } - // 3/4. 历史兜底:壁纸池最新(校 type=1 → 平台 type=0) - List wallList = userSettingsService.findWallList(authUserWithDept.getId()); + // 3/4. 历史兜底:壁纸池第一张(校 type=1 → 平台 type=0,最早上传者优先) if (schId != null) { - // 3. 本地学校壁纸第一张(type=1,取最新) + // 3. 本地学校壁纸第一张(type=1) Optional schWall = wallList.stream() .filter(w -> w.getType() != null && w.getType() == 1 && w.getSchId() != null && w.getSchId().equals(schId)) - .max(Comparator.comparing(Wallpaper::getId)); + .min(Comparator.comparing(Wallpaper::getId)); if (schWall.isPresent()) { return FILE_WEB_PATH + schWall.get().getWallpaperUrl().replace("/upload", ""); } } - // 4. 超管全局壁纸第一张(type=0,取最新) + // 4. 超管全局壁纸第一张(type=0) Optional sysWall = wallList.stream() .filter(w -> w.getType() != null && w.getType() == 0) - .max(Comparator.comparing(Wallpaper::getId)); + .min(Comparator.comparing(Wallpaper::getId)); if (sysWall.isPresent()) { return FILE_WEB_PATH + sysWall.get().getWallpaperUrl().replace("/upload", ""); } diff --git a/src/main/java/com/yunhai/userhome/repository/UserSettingsRepository.java b/src/main/java/com/yunhai/userhome/repository/UserSettingsRepository.java index 79cf4df..d6aabac 100644 --- a/src/main/java/com/yunhai/userhome/repository/UserSettingsRepository.java +++ b/src/main/java/com/yunhai/userhome/repository/UserSettingsRepository.java @@ -8,6 +8,7 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import java.util.Collection; import java.util.Optional; public interface UserSettingsRepository extends JpaRepository, JpaSpecificationExecutor { @@ -21,8 +22,10 @@ public interface UserSettingsRepository extends JpaRepository urls); } diff --git a/src/main/java/com/yunhai/userhome/service/impl/UserSettingsServiceImpl.java b/src/main/java/com/yunhai/userhome/service/impl/UserSettingsServiceImpl.java index f39dd37..08bd653 100644 --- a/src/main/java/com/yunhai/userhome/service/impl/UserSettingsServiceImpl.java +++ b/src/main/java/com/yunhai/userhome/service/impl/UserSettingsServiceImpl.java @@ -53,6 +53,10 @@ public class UserSettingsServiceImpl implements IUserSettingsService { @Value("${FILE_PATH:./upload/}") private String FILE_PATH; + /** 与 UserSettingsController 同源:展示形态 = 该前缀 + 去掉 /upload 的池内原始路径 */ + @Value("${FILE_WEB_PATH:}") + private String FILE_WEB_PATH; + @Override public List findWallList(Integer userId) { Optional currentRoleOpt = userCurrentRoleService.findById(userId); @@ -136,8 +140,11 @@ public class UserSettingsServiceImpl implements IUserSettingsService { if (!(superAdmin || ownPersonal || schAdminOwn)) { throw new BizException(ErrorCode.FORBIDDEN); } - // 使用中清理:被删壁纸被用户设置引用时置空,避免裂图 - userSettingsRepository.clearWallpaperUrl(wallpaper.getWallpaperUrl()); + // 使用中清理:被删壁纸被用户设置引用时置空,避免裂图。 + // user_settings 存展示形态(FILE_WEB_PATH 前缀 + 去 /upload),与 wall 表原始形态不同,两种都清 + String rawUrl = wallpaper.getWallpaperUrl(); + String displayUrl = (FILE_WEB_PATH == null ? "" : FILE_WEB_PATH) + rawUrl.replace("/upload", ""); + userSettingsRepository.clearWallpaperUrl(java.util.Arrays.asList(rawUrl, displayUrl)); // 清理物理文件(非本地上传的跨仓地址静默跳过) FileUtil.deleteFile(FILE_PATH, wallpaper.getWallpaperUrl()); wallpaperRepository.delete(wallpaper);