feat(theme): S5 学院蓝主题改造——home-blocks/service/guide页+区块CSS+ThemeRegistry增强
build / build-push (push) Successful in 53s
build / build-push (push) Successful in 53s
This commit is contained in:
@@ -9,9 +9,12 @@ import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@@ -113,8 +116,9 @@ public class ThemeRegistry {
|
||||
String dirName = dirNameOf(resource);
|
||||
try {
|
||||
ThemeInfo info = MAPPER.readValue(resource.getInputStream(), ThemeInfo.class);
|
||||
ThemePackageValidator.validate(info, dirName, rel ->
|
||||
new ClassPathResource("templates/themes/" + dirName + "/" + rel).exists());
|
||||
ThemePackageValidator.validate(info, dirName,
|
||||
rel -> new ClassPathResource("templates/themes/" + dirName + "/" + rel).exists(),
|
||||
rel -> readClasspath("templates/themes/" + dirName + "/" + rel));
|
||||
applyMetaOverride(info);
|
||||
loaded.put(info.getName(), info);
|
||||
loadedSources.put(info.getName(), SOURCE_BUILTIN);
|
||||
@@ -130,7 +134,9 @@ public class ThemeRegistry {
|
||||
Path json = pkg.resolve("theme.json");
|
||||
try {
|
||||
ThemeInfo info = MAPPER.readValue(json.toFile(), ThemeInfo.class);
|
||||
ThemePackageValidator.validate(info, dirName, rel -> Files.exists(pkg.resolve(rel)));
|
||||
ThemePackageValidator.validate(info, dirName,
|
||||
rel -> Files.exists(pkg.resolve(rel)),
|
||||
rel -> readTextFile(pkg.resolve(rel)));
|
||||
if (loaded.containsKey(info.getName())) {
|
||||
log.warn("外部主题包 {} 与内置包同名,忽略外部包(内置只读、优先,D1)", dirName);
|
||||
continue;
|
||||
@@ -222,6 +228,24 @@ public class ThemeRegistry {
|
||||
return REQUIRED_TEMPLATES;
|
||||
}
|
||||
|
||||
/** 读 classpath 包内文本(UTF-8);读不到返回 null(区块门禁据此跳过,不臆断) */
|
||||
private static String readClasspath(String location) {
|
||||
try (InputStream in = new ClassPathResource(location).getInputStream()) {
|
||||
return StreamUtils.copyToString(in, StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** 读外部包内文本(UTF-8);读不到返回 null */
|
||||
private static String readTextFile(Path file) {
|
||||
try {
|
||||
return new String(Files.readAllBytes(file), StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 资源定位 =====
|
||||
|
||||
/** classpath 内置包扫描(protected:测试可屏蔽以构造外部-only 场景,T-W1-04) */
|
||||
@@ -235,8 +259,8 @@ public class ThemeRegistry {
|
||||
}
|
||||
|
||||
/**
|
||||
* 元数据覆盖层(任务四):包加载后读 {themeDir}/.meta/{name}.json 覆写 title/description——
|
||||
* 内置包 theme.json 在 jar 内只读,显示名/描述改名走此通道;损坏的覆盖层忽略(按原始元数据注册)。
|
||||
* 元数据覆盖层(任务四):包加载后读 {themeDir}/.meta/{name}.json 覆写 title/description/paramValues——
|
||||
* 内置包 theme.json 在 jar 内只读,显示名/描述改名与包级参数值均走此通道;损坏的覆盖层忽略(按原始元数据注册)。
|
||||
*/
|
||||
private void applyMetaOverride(ThemeInfo info) {
|
||||
if (themeDir == null || themeDir.isEmpty() || info.getName() == null) {
|
||||
@@ -254,11 +278,26 @@ public class ThemeRegistry {
|
||||
if (meta.getDescription() != null) {
|
||||
info.setDescription(meta.getDescription());
|
||||
}
|
||||
if (meta.getParamValues() != null && !meta.getParamValues().isEmpty()) {
|
||||
info.setParamValues(new LinkedHashMap<>(meta.getParamValues()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("元数据覆盖层 {} 读取失败,按原始元数据注册:{}", overrideFile, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 包级参数值(工作项 T):主题不存在返回空 Map(调用方免判空)。
|
||||
* 返回不可变视图——参数值的唯一写入口是 {@code ThemePackageService.updateMeta}。
|
||||
*/
|
||||
public Map<String, String> paramValuesOf(String name) {
|
||||
ThemeInfo info = name == null ? null : themes.get(name);
|
||||
if (info == null || info.getParamValues() == null) {
|
||||
return java.util.Collections.emptyMap();
|
||||
}
|
||||
return java.util.Collections.unmodifiableMap(info.getParamValues());
|
||||
}
|
||||
|
||||
/** W1:外部目录包扫描(themeDir 下各包的 theme.json;目录不存在视为空) */
|
||||
protected List<Path> scanExternalPackages() { List<Path> packages = new ArrayList<>();
|
||||
if (themeDir == null || themeDir.isEmpty()) {
|
||||
|
||||
Reference in New Issue
Block a user