feat(content): 标签增加语义码并随卡片下发
backend-ci / test (push) Canceled after 0s

标签名称会随语言和运营文案变化,客户端按名称判断板块(如推荐页「上新」
横滑)一改名就失效。content_tag 新增 code 列并在后台维护,
卡片与详情以 tagCode 下发,已有「上新 / 热剧 / 新剧 / 热播」一并回填。
This commit is contained in:
jianghaifeng authored and trae-solo-agent committed 2026-10-29 15:45:34 +08:00
1 parent 4d796089a0
commit 0d4d510aee
9 files changed
+73

No files matched your search

@@ -24,6 +24,8 @@ public class ContentTag {
private String nameLocales;
/** 角标背景色,#RRGGBB。 */
private String bgColor;
/** 语义码,如 NEW_ARRIVAL;客户端按码判断板块,不解析文案。空表示未配置。 */
private String code;
private Integer sort;
private Integer status;
private LocalDateTime createdAt;
@@ -49,9 +49,12 @@ public class ContentTagService {
public Long create(ContentTagSaveReqVO req) {
Map<String, String> locales = namesOf(req);
ensureNameAvailable(locales.get(ContentLocaleTexts.ZH), null);
String code = normalizeCode(req.getCode());
ensureCodeAvailable(code, null);
ContentTag entity = new ContentTag();
writeNames(entity, locales);
entity.setBgColor(normalizeColor(req.getBgColor()));
entity.setCode(code);
Long count = tagMapper.selectCount(null);
entity.setSort(req.getSort() == null
? (count == null ? 0 : count.intValue()) + 1
@@ -69,6 +72,11 @@ public class ContentTagService {
if (req.getBgColor() != null) {
entity.setBgColor(normalizeColor(req.getBgColor()));
}
if (req.getCode() != null) {
String code = normalizeCode(req.getCode());
ensureCodeAvailable(code, id);
entity.setCode(code);
}
if (req.getSort() != null) {
entity.setSort(req.getSort());
}
@@ -115,6 +123,23 @@ public class ContentTagService {
return color.trim().toUpperCase();
}
/** 语义码统一大写;空字符串表示不配置。 */
private String normalizeCode(String code) {
return code == null ? "" : code.trim().toUpperCase();
}
private void ensureCodeAvailable(String code, Long excludeId) {
if (code.isEmpty()) {
return;
}
Long count = tagMapper.selectCount(Wrappers.<ContentTag>lambdaQuery()
.eq(ContentTag::getCode, code)
.ne(excludeId != null, ContentTag::getId, excludeId));
if (count != null && count > 0) {
throw new ServiceException(ErrorCode.DATA_EXISTS, "语义码已存在");
}
}
private ContentTag getExisting(Long id) {
ContentTag entity = id == null ? null : tagMapper.selectById(id);
if (entity == null) {
@@ -142,6 +167,7 @@ public class ContentTagService {
vo.setNameId(ContentLocaleTexts.value(locales, ContentLocaleTexts.ID));
vo.setLocales(locales);
vo.setBgColor(tag.getBgColor() == null || tag.getBgColor().isBlank() ? "#E5484D" : tag.getBgColor());
vo.setCode(tag.getCode() == null ? "" : tag.getCode());
vo.setSort(tag.getSort());
vo.setStatus(tag.getStatus());
return vo;
@@ -14,6 +14,8 @@ public class ContentTagRespVO {
private String nameId;
private java.util.Map<String, String> locales;
private String bgColor;
/** 语义码,如 NEW_ARRIVAL;空表示未配置。 */
private String code;
private Integer sort;
private Integer status;
}
@@ -21,6 +21,10 @@ public class ContentTagSaveReqVO {
@Pattern(regexp = "^$|^#[0-9A-Fa-f]{6}$", message = "背景色格式应为 #RRGGBB")
private String bgColor;
/** 语义码,如 NEW_ARRIVAL;客户端按码判断板块,留空表示按文案兜底。 */
@Pattern(regexp = "^$|^[A-Z][A-Z0-9_]{0,31}$", message = "语义码需为大写字母、数字或下划线")
private String code;
private Integer sort;
private Integer status;
}