马良AI写作初始化仓库

This commit is contained in:
邓滨杰
2025-09-10 00:07:52 +08:00
parent 3c06bb1a03
commit 39c0f8840f
1309 changed files with 318528 additions and 0 deletions

View File

@@ -0,0 +1,203 @@
package com.ainovel.server.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
import org.springframework.data.mongodb.ReactiveMongoTransactionManager;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.data.mongodb.core.SimpleReactiveMongoDatabaseFactory;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.reactivestreams.client.MongoClient;
import com.mongodb.reactivestreams.client.MongoClients;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
// import java.util.Map; // 移除通用Map转换后不再需要
/**
* MongoDB配置类
* 配置MongoDB连接、响应式支持、日志和统计功能
*/
@Configuration
@EnableReactiveMongoRepositories(basePackages = "com.ainovel.server.repository")
@EnableMongoRepositories(basePackages = "com.ainovel.server.repository")
public class MongoConfig {
private static final Logger logger = LoggerFactory.getLogger(MongoConfig.class);
@Value("${spring.data.mongodb.uri}")
private String mongoUri;
@Value("${spring.data.mongodb.database}")
private String database;
// 注意:这里不注入全局 ObjectMapper 以避免误用于通用 Map 转换
public MongoConfig() {}
/**
* 创建MongoDB事件监听器用于记录MongoDB操作日志
* 注释掉以减少日志输出
*/
// @Bean
// public LoggingEventListener mongoEventListener() {
// return new LoggingEventListener();
// }
/**
* 创建MongoDB映射调试监听器
* 注释掉以减少日志输出
*/
// @Bean
// public AbstractMongoEventListener<Object> mongoMappingDebugListener() {
// return new AbstractMongoEventListener<Object>() {
// @Override
// public void onAfterLoad(AfterLoadEvent<Object> event) {
// if (logger.isTraceEnabled()) {
// logger.trace("📥 MongoDB加载文档: collection={}, document={}",
// event.getCollectionName(), event.getDocument().keySet());
// }
// }
// };
// }
/**
* 自定义ReactiveMongoTemplate添加查询统计和日志功能
* @param factory MongoDB数据库工厂
* @param mappingMongoConverter 自定义的映射转换器(包含点号替换配置)
* @return 自定义的ReactiveMongoTemplate
*/
@Bean
public ReactiveMongoTemplate reactiveMongoTemplate(ReactiveMongoDatabaseFactory factory,
MappingMongoConverter mappingMongoConverter) {
// 使用构造函数直接传入自定义的MappingMongoConverter
ReactiveMongoTemplate template = new ReactiveMongoTemplate(factory, mappingMongoConverter);
// 启用日志记录
logger.info("✅ 已配置ReactiveMongoTemplate使用自定义MappingMongoConverter支持点号替换");
return template;
}
/**
* 创建MongoDB客户端添加性能监控
* @return MongoDB客户端
*/
@Bean
public MongoClient reactiveMongoClient() {
ConnectionString connectionString = new ConnectionString(mongoUri);
MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.applicationName("AINovalWriter")
.build();
logger.info("创建MongoDB客户端连接到: {}", database);
return MongoClients.create(settings);
}
/**
* 创建MongoDB数据库工厂
* @param mongoClient MongoDB客户端
* @return MongoDB数据库工厂
*/
@Bean
public ReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory(MongoClient mongoClient) {
return new SimpleReactiveMongoDatabaseFactory(mongoClient, database);
}
/**
* 创建MongoDB事务管理器
* @param dbFactory MongoDB数据库工厂
* @return MongoDB事务管理器
*/
@Bean
public ReactiveMongoTransactionManager transactionManager(ReactiveMongoDatabaseFactory dbFactory) {
return new ReactiveMongoTransactionManager(dbFactory);
}
/**
* 配置自定义MongoDB转换器
* @return 自定义转换器配置
*/
@Bean
public MongoCustomConversions mongoCustomConversions(SafeMapConverter safeMapConverter) {
List<Converter<?, ?>> converters = new ArrayList<>();
// 日期/时间转换器
converters.add(new DateToInstantConverter());
converters.add(new InstantToDateConverter());
// 仅保留安全的Map读取与时间类型转换避免过于宽泛的 Map<->Object 转换导致的Spring Data WARN
// 安全的Map转换器 - 处理类型不匹配问题
converters.add(safeMapConverter);
logger.info("MongoDB自定义转换器配置完成总计 {} 个转换器", converters.size());
return new MongoCustomConversions(converters);
}
/**
* 配置专门的MongoDB ObjectMapper来处理序列化/反序列化
* 确保与JsonCreator注解配合工作解决复杂嵌套对象映射问题
*/
@Bean("mongoObjectMapper")
public ObjectMapper mongoObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
// 注册JavaTime模块
mapper.registerModule(new JavaTimeModule());
// 配置反序列化行为
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
logger.info("MongoDB ObjectMapper配置完成支持JsonCreator构造函数映射");
return mapper;
}
/**
* Date到Instant的转换器
*/
@ReadingConverter
public static class DateToInstantConverter implements Converter<Date, Instant> {
@Override
public Instant convert(Date source) {
return source == null ? null : source.toInstant();
}
}
/**
* Instant到Date的转换器
*/
@WritingConverter
public static class InstantToDateConverter implements Converter<Instant, Date> {
@Override
public Date convert(Instant source) {
return source == null ? null : Date.from(source);
}
}
// 注意:通用的 Map<->Object 转换改由业务层的 TaskConversionConfig 控制,
// 避免在全局转换器中过于宽泛导致Spring Data发出非存储类型转换的警告。
}