fix:修复内容管理的

This commit is contained in:
llh 2026-03-11 10:54:18 +08:00
parent 2b71ae7bdd
commit dd135a84cb
6 changed files with 124 additions and 1 deletions

2
.gitignore vendored
View File

@ -49,3 +49,5 @@ nbdist/
AGENTS.md
/.claude/
/llm-guard-modules/llm-guard-biz/scripts/
/deploy/
/docs/

View File

@ -1,14 +1,18 @@
package com.llm.guard.common.security.config;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import java.util.Date;
/**
* 系统配置
*
* @author llh
*/
@Configuration
public class ApplicationConfig
{
/**
@ -17,6 +21,12 @@ public class ApplicationConfig
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization()
{
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder
.timeZone(TimeZone.getDefault())
.simpleDateFormat("yyyy-MM-dd HH:mm:ss")
.deserializerByType(Date.class, new JacksonDateDeserializer())
.serializerByType(Date.class,
new com.fasterxml.jackson.databind.ser.std.DateSerializer(false,
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")));
}
}

View File

@ -0,0 +1,60 @@
package com.llm.guard.common.security.config;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.fasterxml.jackson.databind.util.StdDateFormat;
import com.llm.guard.common.core.utils.DateUtils;
import java.io.IOException;
import java.util.Date;
/**
* Global Date deserializer that accepts legacy business formats and ISO-8601.
*/
public class JacksonDateDeserializer extends JsonDeserializer<Date>
{
private static final StdDateFormat ISO_DATE_FORMAT = new StdDateFormat();
@Override
public Date deserialize(JsonParser parser, DeserializationContext context) throws IOException
{
String text = parser.getValueAsString();
if (text == null)
{
return null;
}
String value = text.trim();
if (value.isEmpty())
{
return null;
}
if (value.matches("^\\d{10,13}$"))
{
long timestamp = Long.parseLong(value);
if (value.length() == 10)
{
timestamp = timestamp * 1000;
}
return new Date(timestamp);
}
Date parsed = DateUtils.parseDate(value);
if (parsed != null)
{
return parsed;
}
try
{
return ISO_DATE_FORMAT.parse(value);
}
catch (Exception ex)
{
throw InvalidFormatException.from(parser, "Unsupported date format", value, Date.class);
}
}
}

View File

@ -1,3 +1,4 @@
com.llm.guard.common.security.config.ApplicationConfig
com.llm.guard.common.security.config.WebMvcConfig
com.llm.guard.common.security.service.TokenService
com.llm.guard.common.security.aspect.PreAuthorizeAspect

View File

@ -1,5 +1,6 @@
package com.llm.guard.biz.domain.resp;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -39,6 +40,7 @@ public class AttackRuleResp {
@Schema(description = "版本号")
private String versionNo;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "到期时间")
private Date expireAt;
@ -51,9 +53,11 @@ public class AttackRuleResp {
@Schema(description = "状态")
private String status;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "创建时间")
private Date createdAt;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "更新时间")
private Date updatedAt;
}

View File

@ -33,6 +33,8 @@ import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.Locale;
import java.util.UUID;
@Service
@AllArgsConstructor
@ -112,6 +114,9 @@ public class ConfigAttackBizServiceImpl extends ConfigBizSupport implements Conf
@Override
public AjaxResult addAttackRule(AttackRuleParam param) {
if (param == null) {
return error("请求参数不能为空");
}
AjaxResult validateResult = validateScope(param.getScopeCode());
if (validateResult != null) {
return validateResult;
@ -120,11 +125,15 @@ public class ConfigAttackBizServiceImpl extends ConfigBizSupport implements Conf
if (validateResult != null) {
return validateResult;
}
normalizeAttackRuleParam(param, true);
return toAjax(attackRuleService.save(convert(param, AttackRule::new)));
}
@Override
public AjaxResult editAttackRule(AttackRuleParam param) {
if (param == null) {
return error("请求参数不能为空");
}
AjaxResult validateResult = validateScope(param.getScopeCode());
if (validateResult != null) {
return validateResult;
@ -133,6 +142,7 @@ public class ConfigAttackBizServiceImpl extends ConfigBizSupport implements Conf
if (validateResult != null) {
return validateResult;
}
normalizeAttackRuleParam(param, false);
return toAjax(attackRuleService.updateById(convert(param, AttackRule::new)));
}
@ -298,4 +308,40 @@ public class ConfigAttackBizServiceImpl extends ConfigBizSupport implements Conf
);
return buildPageResp(query.getPageNum(), query.getPageSize(), page.getTotal(), convertList(page.getRecords(), AttackRuleResp::new));
}
private void normalizeAttackRuleParam(AttackRuleParam param, boolean forCreate) {
if (StringUtils.isNotBlank(param.getCategory())) {
param.setCategory(param.getCategory().trim().toUpperCase(Locale.ROOT));
}
if (StringUtils.isNotBlank(param.getSubType())) {
param.setSubType(param.getSubType().trim().toUpperCase(Locale.ROOT));
} else if (StringUtils.isNotBlank(param.getEngineType())) {
param.setSubType(param.getEngineType().trim().toUpperCase(Locale.ROOT));
}
if (forCreate && StringUtils.isBlank(param.getRuleCode())) {
param.setRuleCode(buildRuleCode(param.getCategory(), param.getSubType()));
}
if (forCreate && StringUtils.isBlank(param.getDetectMode())) {
param.setDetectMode("MIXED");
}
if (forCreate && StringUtils.isBlank(param.getRiskLevel())) {
param.setRiskLevel("MEDIUM");
}
if (forCreate && StringUtils.isBlank(param.getAction())) {
param.setAction("BLOCK");
}
if (forCreate && StringUtils.isBlank(param.getStatus())) {
param.setStatus("ENABLED");
}
if (forCreate && StringUtils.isBlank(param.getVersionNo())) {
param.setVersionNo("v1.0.0");
}
}
private String buildRuleCode(String category, String subType) {
String categoryPart = StringUtils.isBlank(category) ? "RULE" : category.trim().toUpperCase(Locale.ROOT);
String subTypePart = StringUtils.isBlank(subType) ? "GEN" : subType.trim().toUpperCase(Locale.ROOT);
String randomPart = UUID.randomUUID().toString().replace("-", "").substring(0, 8).toUpperCase(Locale.ROOT);
return categoryPart + "_" + subTypePart + "_" + randomPart;
}
}