记得上下班打卡 | git大法好,push需谨慎

Commit a40e7afb authored by 姜秀龙's avatar 姜秀龙

Merge branch 'jxl-xiaoshitou' into test

parents 3abea99a f61a4b1f
package com.liquidnet.service.sweet.param;
import com.liquidnet.service.sweet.dto.SweetManualPosterTemplateDto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
@ApiModel("草莓音乐节手册扩展配置参数")
......@@ -24,4 +26,10 @@ public class SweetManualExtConfigParam implements Serializable {
@ApiModelProperty("地图GeoJSON数据")
private Object mapGeojson;
@ApiModelProperty(value = "主题色 #xxxxxx", example = "#FF6600")
private String themeColor;
@ApiModelProperty("按天海报模版")
private List<SweetManualPosterTemplateDto> posterTemplates;
}
......@@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
@ApiModel("草莓音乐节手册扩展配置")
......@@ -24,4 +25,10 @@ public class SweetManualExtConfigDto implements Serializable {
@ApiModelProperty("地图GeoJSON数据")
private Object mapGeojson;
@ApiModelProperty(value = "主题色", example = "#FF6600")
private String themeColor;
@ApiModelProperty("按天海报模版")
private List<SweetManualPosterTemplateDto> posterTemplates;
}
package com.liquidnet.service.sweet.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel("手册按天海报模版")
public class SweetManualPosterTemplateDto implements Serializable {
@ApiModelProperty(value = "日期 yyyy-MM-dd", example = "2026-09-12")
private String date;
@ApiModelProperty("海报图片地址")
private String posterUrl;
}
......@@ -70,6 +70,16 @@ public class SweetManual implements Serializable,Cloneable {
*/
private String mapGeojson;
/**
* 主题色 #xxxxxx
*/
private String themeColor;
/**
* 按天海报模版 JSON [{date,posterUrl}]
*/
private String posterTemplates;
/**
* 创建时间
*/
......
use ln_scene;
ALTER TABLE `sweet_manual`
ADD COLUMN `theme_color` varchar(16) NOT NULL DEFAULT '' COMMENT '主题色 #xxxxxx' AFTER `map_geojson`,
ADD COLUMN `poster_templates` text NULL COMMENT '按天海报模版 JSON [{date,posterUrl}]' AFTER `theme_color`;
......@@ -230,7 +230,7 @@ public class SweetAppletController {
}
@GetMapping("manualExt")
@ApiOperation("草莓音乐节手册扩展配置")
@ApiOperation("草莓音乐节手册扩展配置(含主题色、按天海报模版)")
@ApiImplicitParams({
@ApiImplicitParam(type = "query", dataType = "String", name = "manualId", value = "电子手册id", required = true),
})
......
package com.liquidnet.service.sweet.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.core.type.TypeReference;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.commons.lang.util.StringUtil;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.sweet.dto.SweetManualExtConfigDto;
import com.liquidnet.service.sweet.dto.SweetManualPosterTemplateDto;
import com.liquidnet.service.sweet.entity.SweetManual;
import com.liquidnet.service.sweet.mapper.SweetManualMapper;
import com.liquidnet.service.sweet.param.SweetManualExtConfigParam;
......@@ -15,10 +17,16 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
@Service
public class SweetManualExtConfigServiceImpl implements ISweetManualExtConfigService {
private static final Pattern THEME_COLOR_PATTERN = Pattern.compile("^#[0-9A-Fa-f]{6}$");
private static final Pattern POSTER_DATE_PATTERN = Pattern.compile("^\\d{4}-\\d{2}-\\d{2}$");
@Autowired
private SweetManualMapper sweetManualMapper;
......@@ -40,6 +48,14 @@ public class SweetManualExtConfigServiceImpl implements ISweetManualExtConfigSer
if (StringUtil.isBlank(param.getManualId())) {
return ResponseDto.failure("手册id不能为空");
}
String themeColorError = validateThemeColor(param.getThemeColor());
if (themeColorError != null) {
return ResponseDto.failure(themeColorError);
}
String posterError = validatePosterTemplates(param.getPosterTemplates());
if (posterError != null) {
return ResponseDto.failure(posterError);
}
SweetManual exist = sweetManualMapper.selectOne(
Wrappers.lambdaQuery(SweetManual.class).eq(SweetManual::getManualId, param.getManualId()));
if (exist == null) {
......@@ -52,6 +68,12 @@ public class SweetManualExtConfigServiceImpl implements ISweetManualExtConfigSer
if (param.getMapGeojson() != null) {
update.setMapGeojson(serializeGeojson(param.getMapGeojson()));
}
if (param.getThemeColor() != null) {
update.setThemeColor(normalizeThemeColor(param.getThemeColor()));
}
if (param.getPosterTemplates() != null) {
update.setPosterTemplates(serializePosterTemplates(param.getPosterTemplates()));
}
update.setUpdatedAt(LocalDateTime.now());
sweetManualMapper.update(update, Wrappers.lambdaUpdate(SweetManual.class)
.eq(SweetManual::getManualId, param.getManualId()));
......@@ -101,6 +123,8 @@ public class SweetManualExtConfigServiceImpl implements ISweetManualExtConfigSer
dto.setAlbumUrl(manual.getAlbumUrl());
dto.setLostFoundWjxId(manual.getLostFoundWjxId());
dto.setMapGeojson(parseGeojson(manual.getMapGeojson()));
dto.setThemeColor(nullToEmpty(manual.getThemeColor()));
dto.setPosterTemplates(parsePosterTemplates(manual.getPosterTemplates()));
return dto;
}
......@@ -115,6 +139,16 @@ public class SweetManualExtConfigServiceImpl implements ISweetManualExtConfigSer
} else {
dto.setMapGeojson(parseGeojson(exist.getMapGeojson()));
}
if (param.getThemeColor() != null) {
dto.setThemeColor(normalizeThemeColor(param.getThemeColor()));
} else {
dto.setThemeColor(nullToEmpty(exist.getThemeColor()));
}
if (param.getPosterTemplates() != null) {
dto.setPosterTemplates(normalizePosterTemplates(param.getPosterTemplates()));
} else {
dto.setPosterTemplates(parsePosterTemplates(exist.getPosterTemplates()));
}
return dto;
}
......@@ -136,6 +170,73 @@ public class SweetManualExtConfigServiceImpl implements ISweetManualExtConfigSer
return JsonUtils.toJson(geojson);
}
private List<SweetManualPosterTemplateDto> parsePosterTemplates(String json) {
if (StringUtil.isBlank(json)) {
return new ArrayList<>();
}
try {
List<SweetManualPosterTemplateDto> list = JsonUtils.fromJson(json,
new TypeReference<List<SweetManualPosterTemplateDto>>() {
});
return list == null ? new ArrayList<>() : list;
} catch (Exception e) {
return new ArrayList<>();
}
}
private String serializePosterTemplates(List<SweetManualPosterTemplateDto> posters) {
return JsonUtils.toJson(normalizePosterTemplates(posters));
}
private List<SweetManualPosterTemplateDto> normalizePosterTemplates(List<SweetManualPosterTemplateDto> posters) {
List<SweetManualPosterTemplateDto> result = new ArrayList<>();
if (posters == null) {
return result;
}
for (SweetManualPosterTemplateDto item : posters) {
if (item == null || StringUtil.isBlank(item.getDate())) {
continue;
}
SweetManualPosterTemplateDto dto = new SweetManualPosterTemplateDto();
dto.setDate(item.getDate().trim());
dto.setPosterUrl(nullToEmpty(item.getPosterUrl()).trim());
result.add(dto);
}
return result;
}
private String validateThemeColor(String themeColor) {
if (StringUtil.isBlank(themeColor)) {
return null;
}
if (!THEME_COLOR_PATTERN.matcher(themeColor.trim()).matches()) {
return "主题色格式不正确,需为 #xxxxxx";
}
return null;
}
private String normalizeThemeColor(String themeColor) {
if (StringUtil.isBlank(themeColor)) {
return "";
}
return themeColor.trim().toUpperCase();
}
private String validatePosterTemplates(List<SweetManualPosterTemplateDto> posters) {
if (posters == null) {
return null;
}
for (SweetManualPosterTemplateDto item : posters) {
if (item == null || StringUtil.isBlank(item.getDate())) {
return "海报模版日期不能为空";
}
if (!POSTER_DATE_PATTERN.matcher(item.getDate().trim()).matches()) {
return "海报模版日期格式不正确,需为 yyyy-MM-dd";
}
}
return null;
}
private String nullToEmpty(String value) {
return value == null ? "" : value;
}
......
package com.liquidnet.service.sweet.utils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
......@@ -187,7 +188,7 @@ public class RedisDataUtils {
String redisKey = SweetConstant.REDIS_KEY_SWEET_MANUAL_EXT_CONFIG.concat(manualId);
SweetManualExtConfigDto configDto;
if (content != null) {
configDto = content;
configDto = normalizeExtConfigDto(content);
} else {
SweetManual manual = sweetManualMapper.selectOne(
Wrappers.lambdaQuery(SweetManual.class).eq(SweetManual::getManualId, manualId));
......@@ -198,7 +199,10 @@ public class RedisDataUtils {
configDto.setAlbumUrl(manual.getAlbumUrl());
configDto.setLostFoundWjxId(manual.getLostFoundWjxId());
configDto.setMapGeojson(parseManualMapGeojson(manual.getMapGeojson()));
configDto.setThemeColor(manual.getThemeColor() == null ? "" : manual.getThemeColor());
configDto.setPosterTemplates(parseManualPosterTemplates(manual.getPosterTemplates()));
}
configDto = normalizeExtConfigDto(configDto);
}
redisUtil.set(redisKey, configDto);
return configDto;
......@@ -207,16 +211,34 @@ public class RedisDataUtils {
public SweetManualExtConfigDto getManualExtConfigRedisData(String manualId) {
String redisKey = SweetConstant.REDIS_KEY_SWEET_MANUAL_EXT_CONFIG.concat(manualId);
Object obj = redisUtil.get(redisKey);
if (obj == null) {
if (!(obj instanceof SweetManualExtConfigDto)) {
return setManualExtConfigRedisData(manualId, null);
}
SweetManualExtConfigDto dto = (SweetManualExtConfigDto) obj;
// 旧缓存没有 posterTemplates:回源 DB,兼容升级前后数据
if (dto.getPosterTemplates() == null) {
return setManualExtConfigRedisData(manualId, null);
}
return (SweetManualExtConfigDto) obj;
return normalizeExtConfigDto(dto);
}
public void deleteManualExtConfigRedisData(String manualId) {
redisUtil.del(SweetConstant.REDIS_KEY_SWEET_MANUAL_EXT_CONFIG.concat(manualId));
}
private SweetManualExtConfigDto normalizeExtConfigDto(SweetManualExtConfigDto dto) {
if (dto == null) {
dto = new SweetManualExtConfigDto();
}
if (dto.getThemeColor() == null) {
dto.setThemeColor("");
}
if (dto.getPosterTemplates() == null) {
dto.setPosterTemplates(new ArrayList<>());
}
return dto;
}
private Object parseManualMapGeojson(String geojson) {
if (StringUtil.isBlank(geojson)) {
return null;
......@@ -224,6 +246,21 @@ public class RedisDataUtils {
return JsonUtils.fromJson(geojson, Object.class);
}
private List<SweetManualPosterTemplateDto> parseManualPosterTemplates(String json) {
if (StringUtil.isBlank(json)) {
return new ArrayList<>();
}
try {
List<SweetManualPosterTemplateDto> list = JsonUtils.fromJson(json,
new TypeReference<List<SweetManualPosterTemplateDto>>() {
});
return list == null ? new ArrayList<>() : list;
} catch (Exception e) {
log.warn("解析手册海报模版失败, json={}", json, e);
return new ArrayList<>();
}
}
public List<String> setTagRedisData(String manualId) {
String redisKey = SweetConstant.REDIS_KEY_SWEET_MANUAL_SORT.concat(manualId);
SweetManualSort data = sweetManualSortMapper.selectOne(Wrappers.lambdaQuery(SweetManualSort.class).eq(SweetManualSort::getManualId, manualId));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment