83 lines
3.5 KiB
Java
83 lines
3.5 KiB
Java
package com.yunhai.cms.service.impl;
|
||
|
||
import com.yunhai.cms.model.vo.ThemeVo;
|
||
import com.yunhai.cms.theme.ThemeInfo;
|
||
import com.yunhai.cms.theme.ThemeRegistry;
|
||
import lombok.RequiredArgsConstructor;
|
||
import org.springframework.stereotype.Service;
|
||
|
||
import java.util.ArrayList;
|
||
import java.util.List;
|
||
|
||
/**
|
||
* 主题管理(方案 §5.1/§5.2):主题列表(含参数 schema)供管理端卡片选择与
|
||
* 参数表单动态生成;screenshot 与预览资产经 /api/theme/{name}/asset/** 代理。
|
||
*/
|
||
@Service
|
||
@RequiredArgsConstructor
|
||
public class ThemeService {
|
||
|
||
private final ThemeRegistry themeRegistry;
|
||
private final com.yunhai.cms.repository.CmsSiteRepository siteRepository;
|
||
|
||
/** 可用主题(default 优先,其余按名称排序),管理端建站向导与站点编辑共用。
|
||
* W1(G1/T-W1-14):增 source/inUseCount/editable——来源与删除保护口径同源(findByTheme)。 */
|
||
public List<ThemeVo> list() {
|
||
List<ThemeVo> result = new ArrayList<>();
|
||
for (ThemeInfo info : themeRegistry.list()) {
|
||
result.add(voOf(info));
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/** 单个包 VO 装配(来源/被用数/可编辑随 Registry sourceOf 与站点仓储实时装配) */
|
||
public ThemeVo voOf(ThemeInfo info) {
|
||
ThemeVo vo = ThemeVo.of(info);
|
||
String source = themeRegistry.sourceOf(info.getName()) == null
|
||
? ThemeRegistry.SOURCE_BUILTIN : themeRegistry.sourceOf(info.getName());
|
||
vo.setSource(source);
|
||
java.util.List<com.yunhai.cms.entity.CmsSite> usedBy = siteRepository.findByTheme(info.getName());
|
||
vo.setInUseCount(usedBy.size());
|
||
java.util.List<String> usedNames = new ArrayList<>();
|
||
for (com.yunhai.cms.entity.CmsSite s : usedBy) {
|
||
usedNames.add(s.getName());
|
||
}
|
||
vo.setUsedBySiteNames(usedNames);
|
||
// 任务四:语义改为「可编辑元数据」——内置包亦可改显示名/描述(.meta 覆盖层),内容仍只读
|
||
vo.setEditable(true);
|
||
return vo;
|
||
}
|
||
|
||
/** 未注册主题返回 null(白名单判断用) */
|
||
public ThemeInfo get(String name) {
|
||
return themeRegistry.get(name);
|
||
}
|
||
|
||
/** 未注册主题抛 PARAM_ERROR(预览接口明确 400 语义,不静默回退,方案 §5.5/T27) */
|
||
public ThemeInfo requireRegistered(String name) {
|
||
ThemeInfo info = themeRegistry.get(name);
|
||
if (info == null) {
|
||
throw new com.yunhai.platform.apistd.BizException(
|
||
com.yunhai.platform.utils.exception.ErrorCode.PARAM_ERROR, "皮肤包未注册:" + name);
|
||
}
|
||
return info;
|
||
}
|
||
|
||
/**
|
||
* 提取预览 p_* 前缀参数并按主题 schema 过滤(方案 §5.5):
|
||
* key 为 theme.json 声明过的,# 由前端 URLSearchParams 自动编码为 %23(容器已解码)。
|
||
*/
|
||
public java.util.Map<String, String> extractPreviewParams(ThemeInfo info,
|
||
java.util.Map<String, String[]> parameterMap) {
|
||
java.util.Map<String, Object> raw = new java.util.LinkedHashMap<>();
|
||
if (parameterMap != null) {
|
||
for (java.util.Map.Entry<String, String[]> e : parameterMap.entrySet()) {
|
||
if (e.getKey().startsWith("p_") && e.getValue() != null && e.getValue().length > 0) {
|
||
raw.put(e.getKey().substring(2), e.getValue()[0]);
|
||
}
|
||
}
|
||
}
|
||
return info.filterValidValues(raw);
|
||
}
|
||
}
|