马良AI写作初始化仓库
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
|
||||
import com.ainovel.server.domain.model.AIChatMessage;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public interface AIChatMessageRepository extends ReactiveMongoRepository<AIChatMessage, String> {
|
||||
|
||||
Flux<AIChatMessage> findBySessionIdOrderByCreatedAtDesc(String sessionId, int limit);
|
||||
|
||||
Mono<AIChatMessage> findByIdAndUserId(String id, String userId);
|
||||
|
||||
Mono<Void> deleteByIdAndUserId(String id, String userId);
|
||||
|
||||
Mono<Long> countBySessionId(String sessionId);
|
||||
|
||||
Mono<Void> deleteBySessionId(String sessionId);
|
||||
|
||||
/**
|
||||
* 统计指定时间范围内的消息数量
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return 消息数量
|
||||
*/
|
||||
Mono<Long> countByCreatedAtBetween(LocalDateTime startTime, LocalDateTime endTime);
|
||||
|
||||
/**
|
||||
* 统计指定时间之后的消息数量
|
||||
* @param createdAfter 创建时间之后
|
||||
* @return 消息数量
|
||||
*/
|
||||
Mono<Long> countByCreatedAtAfter(LocalDateTime createdAfter);
|
||||
|
||||
/**
|
||||
* 查找最近的消息用于活动统计
|
||||
* @param limit 数量限制
|
||||
* @return 消息列表
|
||||
*/
|
||||
Flux<AIChatMessage> findTop20ByOrderByCreatedAtDesc();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
|
||||
import com.ainovel.server.domain.model.AIChatSession;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface AIChatSessionRepository extends ReactiveMongoRepository<AIChatSession, String> {
|
||||
|
||||
Mono<AIChatSession> findByUserIdAndSessionId(String userId, String sessionId);
|
||||
|
||||
Flux<AIChatSession> findByUserId(String userId, Pageable pageable);
|
||||
|
||||
Mono<Void> deleteByUserIdAndSessionId(String userId, String sessionId);
|
||||
|
||||
Mono<Long> countByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 根据用户ID、小说ID和会话ID查找会话
|
||||
*/
|
||||
Mono<AIChatSession> findByUserIdAndNovelIdAndSessionId(String userId, String novelId, String sessionId);
|
||||
|
||||
/**
|
||||
* 根据用户ID和小说ID查找会话列表
|
||||
*/
|
||||
Flux<AIChatSession> findByUserIdAndNovelId(String userId, String novelId, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据用户ID、小说ID删除会话
|
||||
*/
|
||||
Mono<Void> deleteByUserIdAndNovelIdAndSessionId(String userId, String novelId, String sessionId);
|
||||
|
||||
/**
|
||||
* 根据用户ID和小说ID统计会话数量
|
||||
*/
|
||||
Mono<Long> countByUserIdAndNovelId(String userId, String novelId);
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import com.ainovel.server.domain.model.AIPromptPreset;
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.data.mongodb.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AI提示词预设数据访问接口
|
||||
*/
|
||||
@Repository
|
||||
public interface AIPromptPresetRepository extends ReactiveMongoRepository<AIPromptPreset, String> {
|
||||
|
||||
/**
|
||||
* 根据预设ID查找
|
||||
*/
|
||||
Mono<AIPromptPreset> findByPresetId(String presetId);
|
||||
|
||||
/**
|
||||
* 根据用户ID和哈希查找(用于查重)
|
||||
*/
|
||||
Mono<AIPromptPreset> findByUserIdAndPresetHash(String userId, String presetHash);
|
||||
|
||||
/**
|
||||
* 根据用户ID查找所有预设
|
||||
*/
|
||||
Flux<AIPromptPreset> findByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 根据用户ID和功能类型查找
|
||||
*/
|
||||
Flux<AIPromptPreset> findByUserIdAndAiFeatureType(String userId, String aiFeatureType);
|
||||
|
||||
/**
|
||||
* 删除用户的所有预设
|
||||
*/
|
||||
Mono<Void> deleteByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 根据预设ID删除
|
||||
*/
|
||||
Mono<Void> deleteByPresetId(String presetId);
|
||||
|
||||
/**
|
||||
* 根据用户ID查找所有预设,按最后使用时间倒序
|
||||
*/
|
||||
Flux<AIPromptPreset> findByUserIdOrderByLastUsedAtDesc(String userId);
|
||||
|
||||
/**
|
||||
* 根据用户ID查找所有预设,按创建时间倒序
|
||||
*/
|
||||
Flux<AIPromptPreset> findByUserIdOrderByCreatedAtDesc(String userId);
|
||||
|
||||
/**
|
||||
* 根据用户ID查找收藏的预设
|
||||
*/
|
||||
Flux<AIPromptPreset> findByUserIdAndIsFavoriteTrue(String userId);
|
||||
|
||||
/**
|
||||
* 根据用户ID和小说ID查找所有预设,按最后使用时间倒序
|
||||
* 包含全局预设(novelId为null)
|
||||
*/
|
||||
@Query("{ 'userId': ?0, $or: [ { 'novelId': ?1 }, { 'novelId': null } ] }")
|
||||
Flux<AIPromptPreset> findByUserIdAndNovelIdOrderByLastUsedAtDesc(String userId, String novelId);
|
||||
|
||||
/**
|
||||
* 根据用户ID、小说ID和功能类型查找预设
|
||||
* 包含全局预设(novelId为null)
|
||||
*/
|
||||
@Query("{ 'userId': ?0, 'aiFeatureType': ?1, $or: [ { 'novelId': ?2 }, { 'novelId': null } ] }")
|
||||
Flux<AIPromptPreset> findByUserIdAndAiFeatureTypeAndNovelId(String userId, String aiFeatureType, String novelId);
|
||||
|
||||
/**
|
||||
* 根据用户ID和小说ID查找收藏的预设
|
||||
* 包含全局预设(novelId为null)
|
||||
*/
|
||||
@Query("{ 'userId': ?0, 'isFavorite': true, $or: [ { 'novelId': ?1 }, { 'novelId': null } ] }")
|
||||
Flux<AIPromptPreset> findByUserIdAndIsFavoriteTrueAndNovelId(String userId, String novelId);
|
||||
|
||||
/**
|
||||
* 根据用户ID和预设名称查找(模糊搜索)
|
||||
*/
|
||||
@Query("{ 'userId': ?0, 'presetName': { $regex: ?1, $options: 'i' } }")
|
||||
Flux<AIPromptPreset> findByUserIdAndPresetNameContainingIgnoreCase(String userId, String presetName);
|
||||
|
||||
/**
|
||||
* 根据用户ID和标签查找
|
||||
*/
|
||||
Flux<AIPromptPreset> findByUserIdAndPresetTagsIn(String userId, List<String> tags);
|
||||
|
||||
/**
|
||||
* 复合搜索:根据用户ID、关键词(名称或描述)、标签、功能类型查找
|
||||
*/
|
||||
@Query("{ " +
|
||||
"'userId': ?0, " +
|
||||
"$and: [" +
|
||||
" { $or: [ " +
|
||||
" { 'presetName': { $regex: ?1, $options: 'i' } }, " +
|
||||
" { 'presetDescription': { $regex: ?1, $options: 'i' } } " +
|
||||
" ] }, " +
|
||||
" { $or: [ " +
|
||||
" { $expr: { $eq: [?2, null] } }, " +
|
||||
" { 'presetTags': { $in: ?2 } } " +
|
||||
" ] }, " +
|
||||
" { $or: [ " +
|
||||
" { $expr: { $eq: [?3, null] } }, " +
|
||||
" { 'aiFeatureType': ?3 } " +
|
||||
" ] } " +
|
||||
"] " +
|
||||
"}")
|
||||
Flux<AIPromptPreset> searchPresets(String userId, String keyword, List<String> tags, String featureType);
|
||||
|
||||
/**
|
||||
* 根据小说ID复合搜索:根据用户ID、关键词(名称或描述)、标签、功能类型、小说ID查找
|
||||
* 包含全局预设(novelId为null)
|
||||
*/
|
||||
@Query("{ " +
|
||||
"'userId': ?0, " +
|
||||
"$and: [" +
|
||||
" { $or: [ " +
|
||||
" { 'presetName': { $regex: ?1, $options: 'i' } }, " +
|
||||
" { 'presetDescription': { $regex: ?1, $options: 'i' } } " +
|
||||
" ] }, " +
|
||||
" { $or: [ " +
|
||||
" { $expr: { $eq: [?2, null] } }, " +
|
||||
" { 'presetTags': { $in: ?2 } } " +
|
||||
" ] }, " +
|
||||
" { $or: [ " +
|
||||
" { $expr: { $eq: [?3, null] } }, " +
|
||||
" { 'aiFeatureType': ?3 } " +
|
||||
" ] }, " +
|
||||
" { $or: [ " +
|
||||
" { 'novelId': ?4 }, " +
|
||||
" { 'novelId': null } " +
|
||||
" ] } " +
|
||||
"] " +
|
||||
"}")
|
||||
Flux<AIPromptPreset> searchPresetsByNovelId(String userId, String keyword, List<String> tags, String featureType, String novelId);
|
||||
|
||||
/**
|
||||
* 获取用户最近使用的预设(最近30天)
|
||||
*/
|
||||
@Query("{ 'userId': ?0, 'lastUsedAt': { $gte: ?1 } }")
|
||||
Flux<AIPromptPreset> findRecentlyUsedPresets(String userId, LocalDateTime since);
|
||||
|
||||
/**
|
||||
* 统计用户预设数量
|
||||
*/
|
||||
Mono<Long> countByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 统计用户收藏预设数量
|
||||
*/
|
||||
Mono<Long> countByUserIdAndIsFavoriteTrue(String userId);
|
||||
|
||||
/**
|
||||
* 根据小说ID统计用户预设数量(包含全局预设)
|
||||
*/
|
||||
@Query(value = "{ 'userId': ?0, $or: [ { 'novelId': ?1 }, { 'novelId': null } ] }", count = true)
|
||||
Mono<Long> countByUserIdAndNovelId(String userId, String novelId);
|
||||
|
||||
/**
|
||||
* 根据小说ID统计用户收藏预设数量(包含全局预设)
|
||||
*/
|
||||
@Query(value = "{ 'userId': ?0, 'isFavorite': true, $or: [ { 'novelId': ?1 }, { 'novelId': null } ] }", count = true)
|
||||
Mono<Long> countByUserIdAndIsFavoriteTrueAndNovelId(String userId, String novelId);
|
||||
|
||||
/**
|
||||
* 统计用户各功能类型的预设数量
|
||||
*/
|
||||
@Query(value = "{ 'userId': ?0 }", count = true)
|
||||
Flux<Object> countByUserIdGroupByAiFeatureType(String userId);
|
||||
|
||||
/**
|
||||
* 获取用户所有预设的标签(去重)
|
||||
*/
|
||||
@Query("{ 'userId': ?0 }")
|
||||
Flux<String> findDistinctTagsByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 检查预设名称是否已存在(同一用户)
|
||||
*/
|
||||
Mono<Boolean> existsByUserIdAndPresetName(String userId, String presetName);
|
||||
|
||||
// ==================== 🚀 新增:系统预设和快捷访问相关查询 ====================
|
||||
|
||||
/**
|
||||
* 获取所有系统预设
|
||||
*/
|
||||
Flux<AIPromptPreset> findByIsSystemTrue();
|
||||
|
||||
/**
|
||||
* 根据功能类型获取系统预设
|
||||
*/
|
||||
Flux<AIPromptPreset> findByIsSystemTrueAndAiFeatureType(String aiFeatureType);
|
||||
|
||||
/**
|
||||
* 获取所有快捷访问预设(包括用户和系统)
|
||||
*/
|
||||
Flux<AIPromptPreset> findByShowInQuickAccessTrue();
|
||||
|
||||
/**
|
||||
* 根据功能类型获取快捷访问预设
|
||||
*/
|
||||
Flux<AIPromptPreset> findByShowInQuickAccessTrueAndAiFeatureType(String aiFeatureType);
|
||||
|
||||
/**
|
||||
* 获取系统预设中显示在快捷访问的预设
|
||||
*/
|
||||
Flux<AIPromptPreset> findByIsSystemTrueAndShowInQuickAccessTrue();
|
||||
|
||||
/**
|
||||
* 获取用户的快捷访问预设
|
||||
*/
|
||||
Flux<AIPromptPreset> findByUserIdAndShowInQuickAccessTrue(String userId);
|
||||
|
||||
/**
|
||||
* 根据用户ID和功能类型获取快捷访问预设
|
||||
*/
|
||||
Flux<AIPromptPreset> findByUserIdAndShowInQuickAccessTrueAndAiFeatureType(String userId, String aiFeatureType);
|
||||
|
||||
/**
|
||||
* 联合查询:获取用户预设 + 系统预设(按功能类型)
|
||||
* 用于获取用户可见的所有预设
|
||||
*/
|
||||
@Query("{ $or: [ { 'userId': ?0 }, { 'isSystem': true } ], 'aiFeatureType': ?1 }")
|
||||
Flux<AIPromptPreset> findUserAndSystemPresetsByFeatureType(String userId, String aiFeatureType);
|
||||
|
||||
/**
|
||||
* 联合查询:获取用户快捷访问预设 + 系统快捷访问预设(按功能类型)
|
||||
*/
|
||||
@Query("{ $or: [ { 'userId': ?0, 'showInQuickAccess': true }, { 'isSystem': true, 'showInQuickAccess': true } ], 'aiFeatureType': ?1 }")
|
||||
Flux<AIPromptPreset> findQuickAccessPresetsByUserAndFeatureType(String userId, String aiFeatureType);
|
||||
|
||||
/**
|
||||
* 根据模板ID查找使用该模板的预设
|
||||
*/
|
||||
Flux<AIPromptPreset> findByTemplateId(String templateId);
|
||||
|
||||
/**
|
||||
* 检查系统预设是否已存在(通过预设ID)
|
||||
*/
|
||||
Mono<Boolean> existsByPresetIdAndIsSystemTrue(String presetId);
|
||||
|
||||
/**
|
||||
* 批量获取多个功能类型的用户和系统预设
|
||||
*/
|
||||
@Query("{ $or: [ { 'userId': ?0 }, { 'isSystem': true } ], 'aiFeatureType': { $in: ?1 } }")
|
||||
Flux<AIPromptPreset> findUserAndSystemPresetsByFeatureTypes(String userId, List<String> aiFeatureTypes);
|
||||
|
||||
/**
|
||||
* 批量获取多个功能类型的快捷访问预设
|
||||
*/
|
||||
@Query("{ $or: [ { 'userId': ?0, 'showInQuickAccess': true }, { 'isSystem': true, 'showInQuickAccess': true } ], 'aiFeatureType': { $in: ?1 } }")
|
||||
Flux<AIPromptPreset> findQuickAccessPresetsByUserAndFeatureTypes(String userId, List<String> aiFeatureTypes);
|
||||
|
||||
/**
|
||||
* 根据预设ID列表查找预设
|
||||
*
|
||||
* @param presetIds 预设ID列表
|
||||
* @return 预设列表
|
||||
*/
|
||||
Flux<AIPromptPreset> findByPresetIdIn(List<String> presetIds);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.task.model.BackgroundTask;
|
||||
import com.ainovel.server.task.model.TaskStatus;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 后台任务的响应式MongoDB存储库
|
||||
*/
|
||||
@Repository
|
||||
public interface BackgroundTaskRepository extends ReactiveMongoRepository<BackgroundTask, String> {
|
||||
|
||||
/**
|
||||
* 根据用户ID查找任务,支持分页
|
||||
* @param userId 用户ID
|
||||
* @param pageable 分页参数
|
||||
* @return 该用户的任务流
|
||||
*/
|
||||
Flux<BackgroundTask> findByUserId(String userId, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据ID和用户ID查找任务(用于权限验证)
|
||||
* @param id 任务ID
|
||||
* @param userId 用户ID
|
||||
* @return 任务的Mono
|
||||
*/
|
||||
Mono<BackgroundTask> findByIdAndUserId(String id, String userId);
|
||||
|
||||
/**
|
||||
* 根据父任务ID查找子任务
|
||||
* @param parentTaskId 父任务ID
|
||||
* @return 子任务流
|
||||
*/
|
||||
Flux<BackgroundTask> findByParentTaskId(String parentTaskId);
|
||||
|
||||
/**
|
||||
* 查找指定用户的指定状态的任务,支持分页
|
||||
* @param userId 用户ID
|
||||
* @param status 任务状态
|
||||
* @param pageable 分页参数
|
||||
* @return 符合条件的任务流
|
||||
*/
|
||||
Flux<BackgroundTask> findByUserIdAndStatus(String userId, TaskStatus status, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 查找指定类型的任务,支持分页
|
||||
* @param taskType 任务类型
|
||||
* @param pageable 分页参数
|
||||
* @return 符合条件的任务流
|
||||
*/
|
||||
Flux<BackgroundTask> findByTaskType(String taskType, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 计算指定用户的待处理任务数量
|
||||
* @param userId 用户ID
|
||||
* @return 待处理任务数量的Mono
|
||||
*/
|
||||
Mono<Long> countByUserIdAndStatusIn(String userId, TaskStatus... statuses);
|
||||
|
||||
/**
|
||||
* 根据状态和执行节点查找任务
|
||||
* @param status 任务状态
|
||||
* @param executionNodeId 执行节点ID
|
||||
* @return 符合条件的任务流
|
||||
*/
|
||||
Flux<BackgroundTask> findByStatusAndExecutionNodeId(TaskStatus status, String executionNodeId);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.CreditPack;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
@Repository
|
||||
public interface CreditPackRepository extends ReactiveMongoRepository<CreditPack, String> {
|
||||
Flux<CreditPack> findByActiveTrueOrderByPriceAsc();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.billing.CreditTransaction;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.publisher.Flux;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
@Repository
|
||||
public interface CreditTransactionRepository extends ReactiveMongoRepository<CreditTransaction, String> {
|
||||
Mono<Boolean> existsByTraceId(String traceId);
|
||||
Mono<CreditTransaction> findByTraceId(String traceId);
|
||||
|
||||
// 按条件分页查询
|
||||
Flux<CreditTransaction> findByStatusOrderByCreatedAtDesc(String status, Pageable pageable);
|
||||
Flux<CreditTransaction> findByUserIdOrderByCreatedAtDesc(String userId, Pageable pageable);
|
||||
Flux<CreditTransaction> findByUserIdAndStatusOrderByCreatedAtDesc(String userId, String status, Pageable pageable);
|
||||
Flux<CreditTransaction> findAllByOrderByCreatedAtDesc(Pageable pageable);
|
||||
Mono<Long> countByStatus(String status);
|
||||
Mono<Long> countByUserId(String userId);
|
||||
Mono<Long> countByUserIdAndStatus(String userId, String status);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mongodb.repository.Query;
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.AIFeatureType;
|
||||
import com.ainovel.server.domain.model.EnhancedUserPromptTemplate;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 增强用户提示词模板Repository
|
||||
*/
|
||||
@Repository
|
||||
public interface EnhancedUserPromptTemplateRepository extends ReactiveMongoRepository<EnhancedUserPromptTemplate, String> {
|
||||
|
||||
/**
|
||||
* 根据用户ID查找模板
|
||||
*/
|
||||
Flux<EnhancedUserPromptTemplate> findByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 根据用户ID和功能类型查找模板
|
||||
*/
|
||||
Flux<EnhancedUserPromptTemplate> findByUserIdAndFeatureType(String userId, AIFeatureType featureType);
|
||||
|
||||
/**
|
||||
* 根据用户ID和功能类型查找默认模板
|
||||
*/
|
||||
Mono<EnhancedUserPromptTemplate> findByUserIdAndFeatureTypeAndIsDefaultTrue(String userId, AIFeatureType featureType);
|
||||
|
||||
/**
|
||||
* 根据用户ID和功能类型查找所有默认模板(用于清除默认状态)
|
||||
*/
|
||||
Flux<EnhancedUserPromptTemplate> findAllByUserIdAndFeatureTypeAndIsDefaultTrue(String userId, AIFeatureType featureType);
|
||||
|
||||
/**
|
||||
* 根据用户ID查找收藏的模板
|
||||
*/
|
||||
Flux<EnhancedUserPromptTemplate> findByUserIdAndIsFavoriteTrue(String userId);
|
||||
|
||||
/**
|
||||
* 根据分享码查找模板
|
||||
*/
|
||||
Mono<EnhancedUserPromptTemplate> findByShareCode(String shareCode);
|
||||
|
||||
/**
|
||||
* 查找公开模板
|
||||
*/
|
||||
@Query("{ 'isPublic': true, 'featureType': ?0 }")
|
||||
Flux<EnhancedUserPromptTemplate> findPublicTemplatesByFeatureType(AIFeatureType featureType);
|
||||
|
||||
/**
|
||||
* 查找所有公开模板
|
||||
*/
|
||||
Flux<EnhancedUserPromptTemplate> findByIsPublicTrue();
|
||||
|
||||
/**
|
||||
* 根据标签搜索用户模板
|
||||
*/
|
||||
@Query("{ 'userId': ?0, 'tags': { '$in': ?1 } }")
|
||||
Flux<EnhancedUserPromptTemplate> findByUserIdAndTagsIn(String userId, List<String> tags);
|
||||
|
||||
/**
|
||||
* 根据关键词搜索用户模板(名称和描述)
|
||||
*/
|
||||
@Query("{ 'userId': ?0, '$or': [ " +
|
||||
"{ 'name': { '$regex': ?1, '$options': 'i' } }, " +
|
||||
"{ 'description': { '$regex': ?1, '$options': 'i' } } ] }")
|
||||
Flux<EnhancedUserPromptTemplate> findByUserIdAndKeyword(String userId, String keyword);
|
||||
|
||||
/**
|
||||
* 获取最近使用的模板
|
||||
*/
|
||||
@Query("{ 'userId': ?0, 'lastUsedAt': { '$ne': null } }")
|
||||
Flux<EnhancedUserPromptTemplate> findByUserIdOrderByLastUsedAtDesc(String userId);
|
||||
|
||||
/**
|
||||
* 获取热门公开模板(按使用次数和评分排序)
|
||||
*/
|
||||
@Query("{ 'isPublic': true, 'featureType': ?0 }")
|
||||
Flux<EnhancedUserPromptTemplate> findPopularPublicTemplatesByFeatureType(AIFeatureType featureType);
|
||||
|
||||
/**
|
||||
* 删除用户的模板
|
||||
*/
|
||||
Mono<Void> deleteByUserIdAndId(String userId, String id);
|
||||
|
||||
/**
|
||||
* 统计用户模板数量
|
||||
*/
|
||||
Mono<Long> countByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 统计用户指定功能类型的模板数量
|
||||
*/
|
||||
Mono<Long> countByUserIdAndFeatureType(String userId, AIFeatureType featureType);
|
||||
|
||||
/**
|
||||
* 统计用户公开模板数量
|
||||
*/
|
||||
Mono<Long> countByUserIdAndIsPublicTrue(String userId);
|
||||
|
||||
/**
|
||||
* 统计用户收藏模板数量
|
||||
*/
|
||||
Mono<Long> countByUserIdAndIsFavoriteTrue(String userId);
|
||||
|
||||
/**
|
||||
* 获取用户所有标签
|
||||
*/
|
||||
@Query(value = "{ 'userId': ?0 }", fields = "{ 'tags': 1 }")
|
||||
Flux<EnhancedUserPromptTemplate> findTagsByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 根据名称或描述搜索所有模板(管理员用)
|
||||
*/
|
||||
@Query("{ '$or': [ " +
|
||||
"{ 'name': { '$regex': ?0, '$options': 'i' } }, " +
|
||||
"{ 'description': { '$regex': ?1, '$options': 'i' } } ] }")
|
||||
Flux<EnhancedUserPromptTemplate> findByNameContainingIgnoreCaseOrDescriptionContainingIgnoreCase(String name, String description);
|
||||
|
||||
/**
|
||||
* 根据ID和用户ID查找模板
|
||||
*/
|
||||
Mono<EnhancedUserPromptTemplate> findByIdAndUserId(String id, String userId);
|
||||
|
||||
/**
|
||||
* 根据功能类型查找公开模板
|
||||
*/
|
||||
Flux<EnhancedUserPromptTemplate> findByFeatureTypeAndIsPublicTrue(AIFeatureType featureType);
|
||||
|
||||
/**
|
||||
* 根据功能类型查找所有模板
|
||||
*/
|
||||
Flux<EnhancedUserPromptTemplate> findByFeatureType(AIFeatureType featureType);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.KnowledgeChunk;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 知识块仓库接口
|
||||
*/
|
||||
@Repository
|
||||
public interface KnowledgeChunkRepository extends ReactiveMongoRepository<KnowledgeChunk, String> {
|
||||
|
||||
/**
|
||||
* 根据小说ID查找知识块
|
||||
* @param novelId 小说ID
|
||||
* @return 知识块流
|
||||
*/
|
||||
Flux<KnowledgeChunk> findByNovelId(String novelId);
|
||||
|
||||
/**
|
||||
* 根据小说ID和源类型查找知识块
|
||||
* @param novelId 小说ID
|
||||
* @param sourceType 源类型
|
||||
* @return 知识块流
|
||||
*/
|
||||
Flux<KnowledgeChunk> findByNovelIdAndSourceType(String novelId, String sourceType);
|
||||
|
||||
/**
|
||||
* 根据小说ID、源类型和源ID查找知识块
|
||||
* @param novelId 小说ID
|
||||
* @param sourceType 源类型
|
||||
* @param sourceId 源ID
|
||||
* @return 知识块流
|
||||
*/
|
||||
Flux<KnowledgeChunk> findByNovelIdAndSourceTypeAndSourceId(String novelId, String sourceType, String sourceId);
|
||||
|
||||
/**
|
||||
* 根据小说ID删除知识块
|
||||
* @param novelId 小说ID
|
||||
* @return 操作结果
|
||||
*/
|
||||
Mono<Void> deleteByNovelId(String novelId);
|
||||
|
||||
/**
|
||||
* 根据小说ID和源类型删除知识块
|
||||
* @param novelId 小说ID
|
||||
* @param sourceType 源类型
|
||||
* @return 操作结果
|
||||
*/
|
||||
Mono<Void> deleteByNovelIdAndSourceType(String novelId, String sourceType);
|
||||
|
||||
/**
|
||||
* 根据小说ID、源类型和源ID删除知识块
|
||||
* @param novelId 小说ID
|
||||
* @param sourceType 源类型
|
||||
* @param sourceId 源ID
|
||||
* @return 操作结果
|
||||
*/
|
||||
Mono<Void> deleteByNovelIdAndSourceTypeAndSourceId(String novelId, String sourceType, String sourceId);
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import com.ainovel.server.domain.model.observability.LLMTrace;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.mongodb.repository.Query;
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* LLM链路追踪数据访问层
|
||||
*/
|
||||
@Repository
|
||||
public interface LLMTraceRepository extends ReactiveMongoRepository<LLMTrace, String> {
|
||||
|
||||
/**
|
||||
* 根据用户ID查找追踪记录
|
||||
*/
|
||||
Flux<LLMTrace> findByUserIdOrderByCreatedAtDesc(String userId, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据会话ID查找追踪记录
|
||||
*/
|
||||
Flux<LLMTrace> findBySessionIdOrderByCreatedAtDesc(String sessionId);
|
||||
|
||||
/**
|
||||
* 根据提供商和模型查找追踪记录
|
||||
*/
|
||||
Flux<LLMTrace> findByProviderAndModelOrderByCreatedAtDesc(String provider, String model, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 查找指定时间范围内的追踪记录
|
||||
*/
|
||||
@Query("{'createdAt': {$gte: ?0, $lte: ?1}}")
|
||||
Flux<LLMTrace> findByCreatedAtBetweenOrderByCreatedAtDesc(Instant start, Instant end, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 统计用户的调用次数
|
||||
*/
|
||||
Mono<Long> countByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 统计错误调用次数
|
||||
*/
|
||||
@Query(value = "{'error': {$ne: null}}", count = true)
|
||||
Mono<Long> countErrorTraces();
|
||||
|
||||
/**
|
||||
* 根据完成原因统计
|
||||
*/
|
||||
@Query(value = "{'response.metadata.finishReason': ?0}", count = true)
|
||||
Mono<Long> countByFinishReason(String finishReason);
|
||||
|
||||
/**
|
||||
* 查找性能较差的调用(耗时超过阈值)
|
||||
*/
|
||||
@Query("{'performance.totalDurationMs': {$gt: ?0}}")
|
||||
Flux<LLMTrace> findSlowTraces(Long thresholdMs, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据关联ID查找相关的所有调用
|
||||
*/
|
||||
Flux<LLMTrace> findByCorrelationIdOrderByCreatedAtAsc(String correlationId);
|
||||
|
||||
/**
|
||||
* 查找所有追踪记录(分页,按创建时间倒序)
|
||||
*/
|
||||
Flux<LLMTrace> findAllByOrderByCreatedAtDesc(Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据提供商查找追踪记录(分页,按创建时间倒序)
|
||||
*/
|
||||
Flux<LLMTrace> findByProviderOrderByCreatedAtDesc(String provider, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据模型查找追踪记录(分页,按创建时间倒序)
|
||||
*/
|
||||
Flux<LLMTrace> findByModelOrderByCreatedAtDesc(String model, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据traceId查找追踪记录
|
||||
*/
|
||||
Mono<LLMTrace> findByTraceId(String traceId);
|
||||
|
||||
/**
|
||||
* 幂等支持:根据 traceId 查找第一条记录
|
||||
*/
|
||||
Mono<LLMTrace> findFirstByTraceId(String traceId);
|
||||
|
||||
/**
|
||||
* 删除指定时间之前的记录
|
||||
*/
|
||||
@Query(value = "{'createdAt': {$lt: ?0}}", delete = true)
|
||||
Mono<Long> deleteByCreatedAtBefore(Instant before);
|
||||
|
||||
// ==================== 管理后台分页支持方法 ====================
|
||||
|
||||
/**
|
||||
* 统计根据提供商的记录数
|
||||
*/
|
||||
Mono<Long> countByProvider(String provider);
|
||||
|
||||
/**
|
||||
* 统计根据模型的记录数
|
||||
*/
|
||||
Mono<Long> countByModel(String model);
|
||||
|
||||
/**
|
||||
* 统计时间范围内的记录数
|
||||
*/
|
||||
@Query(value = "{'createdAt': {$gte: ?0, $lte: ?1}}", count = true)
|
||||
Mono<Long> countByCreatedAtBetween(Instant start, Instant end);
|
||||
|
||||
/**
|
||||
* 统计会话ID的记录数
|
||||
*/
|
||||
Mono<Long> countBySessionId(String sessionId);
|
||||
|
||||
/**
|
||||
* 统计有错误的记录数(根据用户ID)
|
||||
*/
|
||||
@Query(value = "{'userId': ?0, 'error': {$ne: null}}", count = true)
|
||||
Mono<Long> countByUserIdAndErrorIsNotNull(String userId);
|
||||
|
||||
/**
|
||||
* 统计无错误的记录数(根据用户ID)
|
||||
*/
|
||||
@Query(value = "{'userId': ?0, 'error': {$eq: null}}", count = true)
|
||||
Mono<Long> countByUserIdAndErrorIsNull(String userId);
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.data.mongodb.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.ModelPricing;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 模型定价数据仓库
|
||||
*/
|
||||
@Repository
|
||||
public interface ModelPricingRepository extends ReactiveMongoRepository<ModelPricing, String> {
|
||||
|
||||
/**
|
||||
* 根据提供商查找所有激活的定价信息
|
||||
*
|
||||
* @param provider 提供商名称
|
||||
* @return 定价信息列表
|
||||
*/
|
||||
Flux<ModelPricing> findByProviderAndActiveTrue(String provider);
|
||||
|
||||
/**
|
||||
* 根据提供商和模型ID查找定价信息
|
||||
*
|
||||
* @param provider 提供商名称
|
||||
* @param modelId 模型ID
|
||||
* @return 定价信息
|
||||
*/
|
||||
Mono<ModelPricing> findByProviderAndModelIdAndActiveTrue(String provider, String modelId);
|
||||
|
||||
/**
|
||||
* 根据提供商和模型ID查找定价信息(包含非激活的)
|
||||
*
|
||||
* @param provider 提供商名称
|
||||
* @param modelId 模型ID
|
||||
* @return 定价信息
|
||||
*/
|
||||
Mono<ModelPricing> findByProviderAndModelId(String provider, String modelId);
|
||||
|
||||
/**
|
||||
* 查找所有激活的定价信息
|
||||
*
|
||||
* @return 定价信息列表
|
||||
*/
|
||||
Flux<ModelPricing> findByActiveTrue();
|
||||
|
||||
/**
|
||||
* 根据定价来源查找定价信息
|
||||
*
|
||||
* @param source 定价来源
|
||||
* @return 定价信息列表
|
||||
*/
|
||||
Flux<ModelPricing> findBySourceAndActiveTrue(ModelPricing.PricingSource source);
|
||||
|
||||
/**
|
||||
* 根据提供商和定价来源查找定价信息
|
||||
*
|
||||
* @param provider 提供商名称
|
||||
* @param source 定价来源
|
||||
* @return 定价信息列表
|
||||
*/
|
||||
Flux<ModelPricing> findByProviderAndSourceAndActiveTrue(String provider, ModelPricing.PricingSource source);
|
||||
|
||||
/**
|
||||
* 检查指定提供商和模型是否存在定价信息
|
||||
*
|
||||
* @param provider 提供商名称
|
||||
* @param modelId 模型ID
|
||||
* @return 是否存在
|
||||
*/
|
||||
Mono<Boolean> existsByProviderAndModelIdAndActiveTrue(String provider, String modelId);
|
||||
|
||||
/**
|
||||
* 根据提供商删除所有定价信息(软删除)
|
||||
*
|
||||
* @param provider 提供商名称
|
||||
* @return 更新数量
|
||||
*/
|
||||
@Query("{ 'provider': ?0 }")
|
||||
Mono<Long> deactivateByProvider(String provider);
|
||||
|
||||
/**
|
||||
* 获取所有支持的提供商列表
|
||||
*
|
||||
* @return 提供商列表
|
||||
*/
|
||||
@Query(value = "{ 'active': true }", fields = "{ 'provider': 1, '_id': 0 }")
|
||||
Flux<String> findDistinctProviders();
|
||||
|
||||
/**
|
||||
* 根据价格范围查找模型
|
||||
*
|
||||
* @param minPrice 最小价格
|
||||
* @param maxPrice 最大价格
|
||||
* @return 定价信息列表
|
||||
*/
|
||||
@Query("{ 'active': true, $or: [ " +
|
||||
"{ 'inputPricePerThousandTokens': { $gte: ?0, $lte: ?1 } }, " +
|
||||
"{ 'outputPricePerThousandTokens': { $gte: ?0, $lte: ?1 } }, " +
|
||||
"{ 'unifiedPricePerThousandTokens': { $gte: ?0, $lte: ?1 } } ] }")
|
||||
Flux<ModelPricing> findByPriceRange(Double minPrice, Double maxPrice);
|
||||
|
||||
/**
|
||||
* 根据最大token数范围查找模型
|
||||
*
|
||||
* @param minTokens 最小token数
|
||||
* @param maxTokens 最大token数
|
||||
* @return 定价信息列表
|
||||
*/
|
||||
@Query("{ 'active': true, 'maxContextTokens': { $gte: ?0, $lte: ?1 } }")
|
||||
Flux<ModelPricing> findByTokenRange(Integer minTokens, Integer maxTokens);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import com.ainovel.server.domain.model.NextOutline;
|
||||
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
/**
|
||||
* 剧情大纲仓库
|
||||
*/
|
||||
@Repository
|
||||
public interface NextOutlineRepository extends ReactiveCrudRepository<NextOutline, String> {
|
||||
|
||||
/**
|
||||
* 根据小说ID查找大纲
|
||||
*
|
||||
* @param novelId 小说ID
|
||||
* @return 大纲列表
|
||||
*/
|
||||
Flux<NextOutline> findByNovelId(String novelId);
|
||||
|
||||
/**
|
||||
* 根据小说ID和选中状态查找大纲
|
||||
*
|
||||
* @param novelId 小说ID
|
||||
* @param selected 是否选中
|
||||
* @return 大纲列表
|
||||
*/
|
||||
Flux<NextOutline> findByNovelIdAndSelected(String novelId, boolean selected);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.Novel;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 小说仓库接口
|
||||
*/
|
||||
@Repository
|
||||
public interface NovelRepository extends ReactiveMongoRepository<Novel, String> {
|
||||
|
||||
/**
|
||||
* 根据作者ID查找小说
|
||||
* @param authorId 作者ID
|
||||
* @return 小说列表
|
||||
*/
|
||||
Flux<Novel> findByAuthorId(String authorId);
|
||||
|
||||
/**
|
||||
* 根据作者ID查找已就绪的小说
|
||||
*/
|
||||
Flux<Novel> findByAuthorIdAndIsReadyTrue(String authorId);
|
||||
|
||||
/**
|
||||
* 根据标题模糊查询小说
|
||||
* @param title 标题关键词
|
||||
* @return 小说列表
|
||||
*/
|
||||
Flux<Novel> findByTitleContaining(String title);
|
||||
|
||||
/**
|
||||
* 统计指定时间范围内创建的小说数量
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return 小说数量
|
||||
*/
|
||||
Mono<Long> countByCreatedAtBetween(LocalDateTime startTime, LocalDateTime endTime);
|
||||
|
||||
/**
|
||||
* 统计指定时间之后创建的小说数量
|
||||
* @param createdAfter 创建时间之后
|
||||
* @return 小说数量
|
||||
*/
|
||||
Mono<Long> countByCreatedAtAfter(LocalDateTime createdAfter);
|
||||
|
||||
/**
|
||||
* 查找最近创建的小说
|
||||
* @return 小说列表
|
||||
*/
|
||||
Flux<Novel> findTop10ByOrderByCreatedAtDesc();
|
||||
|
||||
/**
|
||||
* 统计作者的小说数量
|
||||
*/
|
||||
Mono<Long> countByAuthorId(String authorId);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import com.ainovel.server.domain.model.NovelSettingGenerationHistory;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.data.mongodb.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 设定生成历史记录仓库接口
|
||||
*/
|
||||
@Repository
|
||||
public interface NovelSettingGenerationHistoryRepository extends ReactiveMongoRepository<NovelSettingGenerationHistory, String> {
|
||||
|
||||
/**
|
||||
* 根据小说ID和用户ID查找历史记录(按创建时间倒序)
|
||||
*/
|
||||
Flux<NovelSettingGenerationHistory> findByNovelIdAndUserIdOrderByCreatedAtDesc(String novelId, String userId);
|
||||
|
||||
/**
|
||||
* 根据小说ID和用户ID查找历史记录(支持分页)
|
||||
*/
|
||||
Flux<NovelSettingGenerationHistory> findByNovelIdAndUserIdOrderByCreatedAtDesc(String novelId, String userId, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据用户ID查找所有历史记录(按创建时间倒序)
|
||||
*/
|
||||
Flux<NovelSettingGenerationHistory> findByUserIdOrderByCreatedAtDesc(String userId);
|
||||
|
||||
/**
|
||||
* 根据用户ID查找所有历史记录(支持分页,按创建时间倒序)
|
||||
*/
|
||||
Flux<NovelSettingGenerationHistory> findByUserIdOrderByCreatedAtDesc(String userId, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据用户ID和小说ID查找历史记录(按创建时间倒序)
|
||||
* 参数顺序:用户ID在前,小说ID在后
|
||||
*/
|
||||
Flux<NovelSettingGenerationHistory> findByUserIdAndNovelIdOrderByCreatedAtDesc(String userId, String novelId);
|
||||
|
||||
/**
|
||||
* 根据用户ID和小说ID查找历史记录(支持分页,按创建时间倒序)
|
||||
* 参数顺序:用户ID在前,小说ID在后
|
||||
*/
|
||||
Flux<NovelSettingGenerationHistory> findByUserIdAndNovelIdOrderByCreatedAtDesc(String userId, String novelId, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据原始会话ID查找历史记录
|
||||
*/
|
||||
Mono<NovelSettingGenerationHistory> findByOriginalSessionId(String originalSessionId);
|
||||
|
||||
/**
|
||||
* 根据源历史记录ID查找衍生的历史记录
|
||||
*/
|
||||
Flux<NovelSettingGenerationHistory> findBySourceHistoryId(String sourceHistoryId);
|
||||
|
||||
/**
|
||||
* 统计用户在指定小说下的历史记录数量
|
||||
*/
|
||||
@Query(value = "{ 'novelId': ?0, 'userId': ?1 }", count = true)
|
||||
Mono<Long> countByNovelIdAndUserId(String novelId, String userId);
|
||||
|
||||
/**
|
||||
* 统计用户和小说的历史记录数量
|
||||
* 参数顺序:用户ID在前,小说ID在后
|
||||
*/
|
||||
@Query(value = "{ 'userId': ?0, 'novelId': ?1 }", count = true)
|
||||
Mono<Long> countByUserIdAndNovelId(String userId, String novelId);
|
||||
|
||||
/**
|
||||
* 统计用户的历史记录数量
|
||||
*/
|
||||
@Query(value = "{ 'userId': ?0 }", count = true)
|
||||
Mono<Long> countByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 删除指定小说的所有历史记录
|
||||
*/
|
||||
Mono<Void> deleteByNovelIdAndUserId(String novelId, String userId);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import com.ainovel.server.domain.model.NovelSettingItemHistory;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.data.mongodb.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 设定节点历史记录仓库接口
|
||||
*/
|
||||
@Repository
|
||||
public interface NovelSettingItemHistoryRepository extends ReactiveMongoRepository<NovelSettingItemHistory, String> {
|
||||
|
||||
/**
|
||||
* 根据设定条目ID查找历史记录(按创建时间倒序)
|
||||
*/
|
||||
Flux<NovelSettingItemHistory> findBySettingItemIdOrderByCreatedAtDesc(String settingItemId);
|
||||
|
||||
/**
|
||||
* 根据设定条目ID查找历史记录(支持分页)
|
||||
*/
|
||||
Flux<NovelSettingItemHistory> findBySettingItemIdOrderByCreatedAtDesc(String settingItemId, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据历史记录ID查找所有节点历史
|
||||
*/
|
||||
Flux<NovelSettingItemHistory> findByHistoryIdOrderByCreatedAtDesc(String historyId);
|
||||
|
||||
/**
|
||||
* 根据设定条目ID和版本号查找特定版本
|
||||
*/
|
||||
Mono<NovelSettingItemHistory> findBySettingItemIdAndVersion(String settingItemId, Integer version);
|
||||
|
||||
/**
|
||||
* 获取设定条目的最新版本号
|
||||
*/
|
||||
@Query(value = "{ 'settingItemId': ?0 }", sort = "{ 'version': -1 }")
|
||||
Mono<NovelSettingItemHistory> findTopBySettingItemIdOrderByVersionDesc(String settingItemId);
|
||||
|
||||
/**
|
||||
* 统计设定条目的历史记录数量
|
||||
*/
|
||||
@Query(value = "{ 'settingItemId': ?0 }", count = true)
|
||||
Mono<Long> countBySettingItemId(String settingItemId);
|
||||
|
||||
/**
|
||||
* 删除设定条目的所有历史记录
|
||||
*/
|
||||
Mono<Void> deleteBySettingItemId(String settingItemId);
|
||||
|
||||
/**
|
||||
* 删除历史记录的所有节点历史
|
||||
*/
|
||||
Mono<Void> deleteByHistoryId(String historyId);
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.data.mongodb.repository.Query;
|
||||
|
||||
import com.ainovel.server.domain.model.NovelSettingItem;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 小说设定条目数据访问接口
|
||||
*/
|
||||
public interface NovelSettingItemRepository extends ReactiveMongoRepository<NovelSettingItem, String> {
|
||||
|
||||
/**
|
||||
* 根据小说ID查找设定条目
|
||||
*/
|
||||
Flux<NovelSettingItem> findByNovelId(String novelId);
|
||||
|
||||
/**
|
||||
* 根据小说ID和类型查找设定条目
|
||||
*/
|
||||
Flux<NovelSettingItem> findByNovelIdAndType(String novelId, String type);
|
||||
|
||||
/**
|
||||
* 根据小说ID和名称查找设定条目
|
||||
*/
|
||||
Flux<NovelSettingItem> findByNovelIdAndNameContaining(String novelId, String name);
|
||||
|
||||
/**
|
||||
* 根据小说ID和场景ID查找设定条目
|
||||
* 使用@Query注解查询sceneIds数组中包含指定sceneId的文档
|
||||
*/
|
||||
@Query("{ 'novelId': ?0, 'sceneIds': ?1 }")
|
||||
Flux<NovelSettingItem> findByNovelIdAndSceneIdIn(String novelId, String sceneId);
|
||||
|
||||
/**
|
||||
* 根据小说ID、类型和优先级查找设定条目,支持分页
|
||||
*/
|
||||
Flux<NovelSettingItem> findByNovelIdAndTypeAndPriorityOrderByPriorityAsc(
|
||||
String novelId, String type, Integer priority, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据小说ID和优先级范围查找设定条目
|
||||
*/
|
||||
Flux<NovelSettingItem> findByNovelIdAndPriorityBetween(
|
||||
String novelId, Integer minPriority, Integer maxPriority);
|
||||
|
||||
/**
|
||||
* 根据小说ID、类型和生成源查找设定条目
|
||||
*/
|
||||
Flux<NovelSettingItem> findByNovelIdAndTypeAndGeneratedBy(
|
||||
String novelId, String type, String generatedBy);
|
||||
|
||||
/**
|
||||
* 根据小说ID、生成源和状态查找设定条目
|
||||
*/
|
||||
Flux<NovelSettingItem> findByNovelIdAndGeneratedByAndStatus(
|
||||
String novelId, String generatedBy, String status);
|
||||
|
||||
/**
|
||||
* 批量删除小说的所有设定条目
|
||||
*/
|
||||
Mono<Void> deleteByNovelId(String novelId);
|
||||
|
||||
/**
|
||||
* 批量删除特定场景的设定条目
|
||||
*/
|
||||
@Query("{ 'novelId': ?0, 'sceneIds': ?1 }")
|
||||
Mono<Void> deleteByNovelIdAndSceneIdIn(String novelId, String sceneId);
|
||||
|
||||
/**
|
||||
* 根据父设定ID查找子设定条目
|
||||
*/
|
||||
Flux<NovelSettingItem> findByParentId(String parentId);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.data.mongodb.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.NovelSnippetHistory;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 小说片段历史记录仓库接口
|
||||
*/
|
||||
@Repository
|
||||
public interface NovelSnippetHistoryRepository extends ReactiveMongoRepository<NovelSnippetHistory, String> {
|
||||
|
||||
/**
|
||||
* 根据片段ID查找历史记录(按时间倒序)
|
||||
*/
|
||||
@Query("{ 'snippetId': ?0 }")
|
||||
Flux<NovelSnippetHistory> findBySnippetIdOrderByCreatedAtDesc(String snippetId, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据片段ID和版本号查找历史记录
|
||||
*/
|
||||
Mono<NovelSnippetHistory> findBySnippetIdAndVersion(String snippetId, Integer version);
|
||||
|
||||
/**
|
||||
* 根据片段ID和用户ID查找历史记录(权限验证)
|
||||
*/
|
||||
@Query("{ 'snippetId': ?0, 'userId': ?1 }")
|
||||
Flux<NovelSnippetHistory> findBySnippetIdAndUserId(String snippetId, String userId, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 统计片段的历史记录数量
|
||||
*/
|
||||
@Query(value = "{ 'snippetId': ?0 }", count = true)
|
||||
Mono<Long> countBySnippetId(String snippetId);
|
||||
|
||||
/**
|
||||
* 删除片段的所有历史记录
|
||||
*/
|
||||
Mono<Void> deleteBySnippetId(String snippetId);
|
||||
|
||||
/**
|
||||
* 根据用户ID删除所有历史记录
|
||||
*/
|
||||
Mono<Void> deleteByUserId(String userId);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.data.mongodb.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.NovelSnippet;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 小说片段仓库接口
|
||||
*/
|
||||
@Repository
|
||||
public interface NovelSnippetRepository extends ReactiveMongoRepository<NovelSnippet, String> {
|
||||
|
||||
/**
|
||||
* 根据用户ID和小说ID查找片段(支持分页)
|
||||
*/
|
||||
@Query("{ 'userId': ?0, 'novelId': ?1, 'status': 'ACTIVE' }")
|
||||
Flux<NovelSnippet> findByUserIdAndNovelIdAndStatusActive(String userId, String novelId, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据ID和用户ID查找片段(权限验证)
|
||||
*/
|
||||
Mono<NovelSnippet> findByIdAndUserId(String id, String userId);
|
||||
|
||||
/**
|
||||
* 根据用户ID查找收藏的片段
|
||||
*/
|
||||
@Query("{ 'userId': ?0, 'isFavorite': true, 'status': 'ACTIVE' }")
|
||||
Flux<NovelSnippet> findFavoritesByUserId(String userId, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据用户ID和分类查找片段
|
||||
*/
|
||||
@Query("{ 'userId': ?0, 'category': ?1, 'status': 'ACTIVE' }")
|
||||
Flux<NovelSnippet> findByUserIdAndCategory(String userId, String category, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据用户ID和标签查找片段
|
||||
*/
|
||||
@Query("{ 'userId': ?0, 'tags': { $in: ?1 }, 'status': 'ACTIVE' }")
|
||||
Flux<NovelSnippet> findByUserIdAndTagsIn(String userId, List<String> tags, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 全文搜索片段
|
||||
*/
|
||||
@Query("{ 'userId': ?0, 'novelId': ?1, '$text': { '$search': ?2 }, 'status': 'ACTIVE' }")
|
||||
Flux<NovelSnippet> findByUserIdAndNovelIdAndFullTextSearch(String userId, String novelId, String searchText, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据时间范围查找片段
|
||||
*/
|
||||
@Query("{ 'userId': ?0, 'novelId': ?1, 'createdAt': { '$gte': ?2, '$lte': ?3 }, 'status': 'ACTIVE' }")
|
||||
Flux<NovelSnippet> findByUserIdAndNovelIdAndCreatedAtBetween(String userId, String novelId, LocalDateTime startTime, LocalDateTime endTime, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 统计用户在特定小说中的片段数量
|
||||
*/
|
||||
@Query(value = "{ 'userId': ?0, 'novelId': ?1, 'status': 'ACTIVE' }", count = true)
|
||||
Mono<Long> countByUserIdAndNovelIdAndStatusActive(String userId, String novelId);
|
||||
|
||||
/**
|
||||
* 统计用户收藏片段数量
|
||||
*/
|
||||
@Query(value = "{ 'userId': ?0, 'isFavorite': true, 'status': 'ACTIVE' }", count = true)
|
||||
Mono<Long> countFavoritesByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 删除用户在特定小说中的所有片段
|
||||
*/
|
||||
@Query("{ 'userId': ?0, 'novelId': ?1 }")
|
||||
Mono<Void> deleteByUserIdAndNovelId(String userId, String novelId);
|
||||
|
||||
/**
|
||||
* 根据小说ID删除所有相关片段
|
||||
*/
|
||||
Mono<Void> deleteByNovelId(String novelId);
|
||||
|
||||
/**
|
||||
* 查找用户的最新片段
|
||||
*/
|
||||
@Query("{ 'userId': ?0, 'novelId': ?1, 'status': 'ACTIVE' }")
|
||||
Flux<NovelSnippet> findLatestByUserIdAndNovelId(String userId, String novelId, Pageable pageable);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.PaymentOrder;
|
||||
import com.ainovel.server.domain.model.PaymentOrder.PayStatus;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Repository
|
||||
public interface PaymentOrderRepository extends ReactiveMongoRepository<PaymentOrder, String> {
|
||||
|
||||
Mono<PaymentOrder> findByOutTradeNo(String outTradeNo);
|
||||
|
||||
Flux<PaymentOrder> findByUserIdOrderByCreatedAtDesc(String userId);
|
||||
|
||||
Mono<Long> countByUserIdAndStatus(String userId, PayStatus status);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.AIFeatureType;
|
||||
import com.ainovel.server.domain.model.PublicModelConfig;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 公共模型配置数据访问层
|
||||
*/
|
||||
@Repository
|
||||
public interface PublicModelConfigRepository extends ReactiveMongoRepository<PublicModelConfig, String> {
|
||||
|
||||
/**
|
||||
* 根据提供商和模型ID查找配置
|
||||
*
|
||||
* @param provider 提供商名称
|
||||
* @param modelId 模型ID
|
||||
* @return 公共模型配置
|
||||
*/
|
||||
Mono<PublicModelConfig> findByProviderAndModelId(String provider, String modelId);
|
||||
|
||||
/**
|
||||
* 查找所有启用的公共模型配置
|
||||
*
|
||||
* @return 启用的公共模型配置列表
|
||||
*/
|
||||
Flux<PublicModelConfig> findByEnabledTrue();
|
||||
|
||||
/**
|
||||
* 根据提供商查找启用的公共模型配置
|
||||
*
|
||||
* @param provider 提供商名称
|
||||
* @return 启用的公共模型配置列表
|
||||
*/
|
||||
Flux<PublicModelConfig> findByProviderAndEnabledTrue(String provider);
|
||||
|
||||
/**
|
||||
* 根据AI功能类型查找支持的公共模型配置
|
||||
*
|
||||
* @param featureType AI功能类型
|
||||
* @return 支持该功能的公共模型配置列表
|
||||
*/
|
||||
Flux<PublicModelConfig> findByEnabledTrueAndEnabledForFeaturesContaining(AIFeatureType featureType);
|
||||
|
||||
/**
|
||||
* 根据提供商和AI功能类型查找支持的公共模型配置
|
||||
*
|
||||
* @param provider 提供商名称
|
||||
* @param featureType AI功能类型
|
||||
* @return 支持该功能的公共模型配置列表
|
||||
*/
|
||||
Flux<PublicModelConfig> findByProviderAndEnabledTrueAndEnabledForFeaturesContaining(String provider, AIFeatureType featureType);
|
||||
|
||||
/**
|
||||
* 查找所有启用的公共模型配置,按优先级降序排列
|
||||
*
|
||||
* @return 按优先级排序的启用公共模型配置列表
|
||||
*/
|
||||
Flux<PublicModelConfig> findByEnabledTrueOrderByPriorityDesc();
|
||||
|
||||
/**
|
||||
* 根据标签查找公共模型配置
|
||||
*
|
||||
* @param tag 标签
|
||||
* @return 包含该标签的公共模型配置列表
|
||||
*/
|
||||
Flux<PublicModelConfig> findByEnabledTrueAndTagsContaining(String tag);
|
||||
|
||||
/**
|
||||
* 检查指定提供商和模型ID的配置是否存在
|
||||
*
|
||||
* @param provider 提供商名称
|
||||
* @param modelId 模型ID
|
||||
* @return 是否存在
|
||||
*/
|
||||
Mono<Boolean> existsByProviderAndModelId(String provider, String modelId);
|
||||
|
||||
/**
|
||||
* 根据提供商列表查找启用的公共模型配置
|
||||
*
|
||||
* @param providers 提供商名称列表
|
||||
* @return 启用的公共模型配置列表
|
||||
*/
|
||||
Flux<PublicModelConfig> findByProviderInAndEnabledTrue(List<String> providers);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.Role;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 角色数据访问层
|
||||
*/
|
||||
@Repository
|
||||
public interface RoleRepository extends ReactiveMongoRepository<Role, String> {
|
||||
|
||||
/**
|
||||
* 根据角色名称查找角色
|
||||
*
|
||||
* @param roleName 角色名称
|
||||
* @return 角色信息
|
||||
*/
|
||||
Mono<Role> findByRoleName(String roleName);
|
||||
|
||||
/**
|
||||
* 根据角色名称列表查找角色
|
||||
*
|
||||
* @param roleNames 角色名称列表
|
||||
* @return 角色列表
|
||||
*/
|
||||
Flux<Role> findByRoleNameIn(List<String> roleNames);
|
||||
|
||||
/**
|
||||
* 查找所有启用的角色
|
||||
*
|
||||
* @return 启用的角色列表
|
||||
*/
|
||||
Flux<Role> findByEnabledTrue();
|
||||
|
||||
/**
|
||||
* 根据优先级降序查找所有角色
|
||||
*
|
||||
* @return 按优先级排序的角色列表
|
||||
*/
|
||||
Flux<Role> findAllByOrderByPriorityDesc();
|
||||
|
||||
/**
|
||||
* 检查角色名称是否存在
|
||||
*
|
||||
* @param roleName 角色名称
|
||||
* @return 是否存在
|
||||
*/
|
||||
Mono<Boolean> existsByRoleName(String roleName);
|
||||
|
||||
/**
|
||||
* 根据权限查找拥有该权限的角色
|
||||
*
|
||||
* @param permission 权限标识符
|
||||
* @return 拥有该权限的角色列表
|
||||
*/
|
||||
Flux<Role> findByPermissionsContaining(String permission);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.Scene;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 场景仓库接口
|
||||
*/
|
||||
@Repository
|
||||
public interface SceneRepository extends ReactiveMongoRepository<Scene, String> {
|
||||
|
||||
/**
|
||||
* 根据小说ID查找场景
|
||||
* @param novelId 小说ID
|
||||
* @return 场景列表
|
||||
*/
|
||||
Flux<Scene> findByNovelId(String novelId);
|
||||
|
||||
/**
|
||||
* 根据章节ID查找场景
|
||||
* @param chapterId 章节ID
|
||||
* @return 场景列表
|
||||
*/
|
||||
Flux<Scene> findByChapterId(String chapterId);
|
||||
|
||||
/**
|
||||
* 根据章节ID查找场景并按顺序排序
|
||||
* @param chapterId 章节ID
|
||||
* @return 排序后的场景列表
|
||||
*/
|
||||
Flux<Scene> findByChapterIdOrderBySequenceAsc(String chapterId);
|
||||
|
||||
/**
|
||||
* 根据小说ID查找场景并按章节ID和顺序排序
|
||||
* @param novelId 小说ID
|
||||
* @return 排序后的场景列表
|
||||
*/
|
||||
Flux<Scene> findByNovelIdOrderByChapterIdAscSequenceAsc(String novelId);
|
||||
|
||||
/**
|
||||
* 根据章节ID列表查找场景
|
||||
* @param chapterIds 章节ID列表
|
||||
* @return 场景列表
|
||||
*/
|
||||
Flux<Scene> findByChapterIdIn(List<String> chapterIds);
|
||||
|
||||
/**
|
||||
* 根据小说ID和场景类型查找场景
|
||||
* @param novelId 小说ID
|
||||
* @param sceneType 场景类型
|
||||
* @return 场景列表
|
||||
*/
|
||||
Flux<Scene> findByNovelIdAndSceneType(String novelId, String sceneType);
|
||||
|
||||
/**
|
||||
* 删除小说的所有场景
|
||||
* @param novelId 小说ID
|
||||
* @return 操作结果
|
||||
*/
|
||||
Mono<Void> deleteByNovelId(String novelId);
|
||||
|
||||
/**
|
||||
* 删除章节的所有场景
|
||||
* @param chapterId 章节ID
|
||||
* @return 操作结果
|
||||
*/
|
||||
Mono<Void> deleteByChapterId(String chapterId);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import com.ainovel.server.domain.model.SettingGroup;
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
|
||||
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 设定组数据访问接口
|
||||
*/
|
||||
public interface SettingGroupRepository extends ReactiveMongoRepository<SettingGroup, String> {
|
||||
|
||||
/**
|
||||
* 根据小说ID查找设定组
|
||||
*/
|
||||
Flux<SettingGroup> findByNovelId(String novelId);
|
||||
|
||||
/**
|
||||
* 根据小说ID和名称查找设定组
|
||||
*/
|
||||
Flux<SettingGroup> findByNovelIdAndNameContaining(String novelId, String name);
|
||||
|
||||
/**
|
||||
* 根据小说ID和是否激活状态查找设定组
|
||||
*/
|
||||
Flux<SettingGroup> findByNovelIdAndIsActiveContext(String novelId, Boolean isActiveContext);
|
||||
|
||||
/**
|
||||
* 根据小说ID和用户ID查找设定组
|
||||
*/
|
||||
Flux<SettingGroup> findByNovelIdAndUserId(String novelId, String userId);
|
||||
|
||||
/**
|
||||
* 删除小说的所有设定组
|
||||
*/
|
||||
Mono<Void> deleteByNovelId(String novelId);
|
||||
|
||||
/**
|
||||
* 检查设定组是否包含特定设定条目
|
||||
*/
|
||||
Mono<Boolean> existsByIdAndItemIdsContaining(String groupId, String settingItemId);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.SubscriptionPlan;
|
||||
import com.ainovel.server.domain.model.SubscriptionPlan.BillingCycle;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 订阅计划数据访问层
|
||||
*/
|
||||
@Repository
|
||||
public interface SubscriptionPlanRepository extends ReactiveMongoRepository<SubscriptionPlan, String> {
|
||||
|
||||
/**
|
||||
* 查找所有激活的订阅计划
|
||||
*
|
||||
* @return 激活的订阅计划列表
|
||||
*/
|
||||
Flux<SubscriptionPlan> findByActiveTrue();
|
||||
|
||||
/**
|
||||
* 根据计费周期查找订阅计划
|
||||
*
|
||||
* @param billingCycle 计费周期
|
||||
* @return 订阅计划列表
|
||||
*/
|
||||
Flux<SubscriptionPlan> findByBillingCycle(BillingCycle billingCycle);
|
||||
|
||||
/**
|
||||
* 查找所有激活的订阅计划,按优先级降序排列
|
||||
*
|
||||
* @return 按优先级排序的激活订阅计划列表
|
||||
*/
|
||||
Flux<SubscriptionPlan> findByActiveTrueOrderByPriorityDesc();
|
||||
|
||||
/**
|
||||
* 根据角色ID查找订阅计划
|
||||
*
|
||||
* @param roleId 角色ID
|
||||
* @return 订阅计划列表
|
||||
*/
|
||||
Flux<SubscriptionPlan> findByRoleId(String roleId);
|
||||
|
||||
/**
|
||||
* 查找推荐的订阅计划
|
||||
*
|
||||
* @return 推荐的订阅计划列表
|
||||
*/
|
||||
Flux<SubscriptionPlan> findByRecommendedTrueAndActiveTrue();
|
||||
|
||||
/**
|
||||
* 根据套餐名称查找订阅计划
|
||||
*
|
||||
* @param planName 套餐名称
|
||||
* @return 订阅计划
|
||||
*/
|
||||
Mono<SubscriptionPlan> findByPlanName(String planName);
|
||||
|
||||
/**
|
||||
* 检查套餐名称是否存在
|
||||
*
|
||||
* @param planName 套餐名称
|
||||
* @return 是否存在
|
||||
*/
|
||||
Mono<Boolean> existsByPlanName(String planName);
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.SystemConfig;
|
||||
import com.ainovel.server.domain.model.SystemConfig.ConfigType;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 系统配置数据访问层
|
||||
*/
|
||||
@Repository
|
||||
public interface SystemConfigRepository extends ReactiveMongoRepository<SystemConfig, String> {
|
||||
|
||||
/**
|
||||
* 根据配置键查找配置
|
||||
*
|
||||
* @param configKey 配置键
|
||||
* @return 系统配置
|
||||
*/
|
||||
Mono<SystemConfig> findByConfigKey(String configKey);
|
||||
|
||||
/**
|
||||
* 查找所有启用的配置
|
||||
*
|
||||
* @return 启用的配置列表
|
||||
*/
|
||||
Flux<SystemConfig> findByEnabledTrue();
|
||||
|
||||
/**
|
||||
* 根据配置分组查找配置
|
||||
*
|
||||
* @param configGroup 配置分组
|
||||
* @return 配置列表
|
||||
*/
|
||||
Flux<SystemConfig> findByConfigGroup(String configGroup);
|
||||
|
||||
/**
|
||||
* 根据配置类型查找配置
|
||||
*
|
||||
* @param configType 配置类型
|
||||
* @return 配置列表
|
||||
*/
|
||||
Flux<SystemConfig> findByConfigType(ConfigType configType);
|
||||
|
||||
/**
|
||||
* 查找所有非只读的配置
|
||||
*
|
||||
* @return 非只读配置列表
|
||||
*/
|
||||
Flux<SystemConfig> findByReadOnlyFalse();
|
||||
|
||||
/**
|
||||
* 根据配置分组查找启用的配置
|
||||
*
|
||||
* @param configGroup 配置分组
|
||||
* @return 启用的配置列表
|
||||
*/
|
||||
Flux<SystemConfig> findByConfigGroupAndEnabledTrue(String configGroup);
|
||||
|
||||
/**
|
||||
* 检查配置键是否存在
|
||||
*
|
||||
* @param configKey 配置键
|
||||
* @return 是否存在
|
||||
*/
|
||||
Mono<Boolean> existsByConfigKey(String configKey);
|
||||
|
||||
/**
|
||||
* 根据配置键删除配置
|
||||
*
|
||||
* @param configKey 配置键
|
||||
* @return 删除结果
|
||||
*/
|
||||
Mono<Void> deleteByConfigKey(String configKey);
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.UserAIModelConfig;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Repository
|
||||
public interface UserAIModelConfigRepository extends ReactiveMongoRepository<UserAIModelConfig, String> {
|
||||
|
||||
Flux<UserAIModelConfig> findByUserId(String userId);
|
||||
|
||||
Mono<UserAIModelConfig> findByUserIdAndId(String userId, String id);
|
||||
|
||||
Mono<UserAIModelConfig> findByUserIdAndProviderAndModelName(String userId, String provider, String modelName);
|
||||
|
||||
Mono<Void> deleteByUserIdAndId(String userId, String id);
|
||||
|
||||
/**
|
||||
* 查找用户特定提供商和模型的已验证配置
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param provider 提供商
|
||||
* @param modelName 模型名称
|
||||
* @param isValidated 是否已验证
|
||||
* @return 配置信息
|
||||
*/
|
||||
Mono<UserAIModelConfig> findByUserIdAndProviderAndModelNameAndIsValidated(String userId, String provider, String modelName, boolean isValidated);
|
||||
|
||||
/**
|
||||
* 查找用户所有已验证的配置
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param isValidated 是否已验证
|
||||
* @return 配置列表
|
||||
*/
|
||||
Flux<UserAIModelConfig> findByUserIdAndIsValidated(String userId, boolean isValidated);
|
||||
|
||||
/**
|
||||
* 查找用户的默认配置
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 默认配置,可能为空
|
||||
*/
|
||||
Mono<UserAIModelConfig> findByUserIdAndIsDefaultIsTrue(String userId);
|
||||
|
||||
/**
|
||||
* 查找用户所有非默认的配置
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 非默认配置列表
|
||||
*/
|
||||
Flux<UserAIModelConfig> findByUserIdAndIsDefaultIsFalse(String userId);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import com.ainovel.server.domain.model.UserEditorSettings;
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 用户编辑器设置仓库接口
|
||||
*/
|
||||
@Repository
|
||||
public interface UserEditorSettingsRepository extends ReactiveMongoRepository<UserEditorSettings, String> {
|
||||
|
||||
/**
|
||||
* 根据用户ID查找编辑器设置
|
||||
* @param userId 用户ID
|
||||
* @return 用户编辑器设置
|
||||
*/
|
||||
Mono<UserEditorSettings> findByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 根据用户ID删除编辑器设置
|
||||
* @param userId 用户ID
|
||||
* @return 删除结果
|
||||
*/
|
||||
Mono<Void> deleteByUserId(String userId);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.AIFeatureType;
|
||||
import com.ainovel.server.domain.model.UserPromptTemplate;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 用户提示词模板仓库
|
||||
* 提供对用户提示词模板的存储和查询操作
|
||||
*/
|
||||
@Repository
|
||||
public interface UserPromptTemplateRepository extends ReactiveMongoRepository<UserPromptTemplate, String> {
|
||||
|
||||
/**
|
||||
* 根据用户ID和功能类型查找用户提示词模板
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param featureType 功能类型
|
||||
* @return 用户提示词模板
|
||||
*/
|
||||
Mono<UserPromptTemplate> findByUserIdAndFeatureType(String userId, AIFeatureType featureType);
|
||||
|
||||
/**
|
||||
* 根据用户ID查找所有用户提示词模板
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 用户提示词模板流
|
||||
*/
|
||||
Flux<UserPromptTemplate> findByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 根据用户ID和功能类型删除用户提示词模板
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param featureType 功能类型
|
||||
* @return 操作结果
|
||||
*/
|
||||
Mono<Void> deleteByUserIdAndFeatureType(String userId, AIFeatureType featureType);
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.User;
|
||||
import com.ainovel.server.domain.model.User.AccountStatus;
|
||||
import com.ainovel.server.repository.custom.CustomUserRepository;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 用户仓库接口
|
||||
*/
|
||||
@Repository
|
||||
public interface UserRepository extends ReactiveMongoRepository<User, String>, CustomUserRepository {
|
||||
|
||||
/**
|
||||
* 根据用户名查找用户
|
||||
* @param username 用户名
|
||||
* @return 用户信息
|
||||
*/
|
||||
Mono<User> findByUsername(String username);
|
||||
|
||||
/**
|
||||
* 根据邮箱查找用户
|
||||
* @param email 邮箱
|
||||
* @return 用户信息
|
||||
*/
|
||||
Mono<User> findByEmail(String email);
|
||||
|
||||
/**
|
||||
* 根据手机号码查找用户
|
||||
* @param phone 手机号码
|
||||
* @return 用户信息
|
||||
*/
|
||||
Mono<User> findByPhone(String phone);
|
||||
|
||||
/**
|
||||
* 检查用户名是否存在
|
||||
* @param username 用户名
|
||||
* @return 是否存在
|
||||
*/
|
||||
Mono<Boolean> existsByUsername(String username);
|
||||
|
||||
/**
|
||||
* 检查邮箱是否存在
|
||||
* @param email 邮箱
|
||||
* @return 是否存在
|
||||
*/
|
||||
Mono<Boolean> existsByEmail(String email);
|
||||
|
||||
/**
|
||||
* 检查手机号码是否存在
|
||||
* @param phone 手机号码
|
||||
* @return 是否存在
|
||||
*/
|
||||
Mono<Boolean> existsByPhone(String phone);
|
||||
|
||||
/**
|
||||
* 根据用户名或邮箱模糊查询
|
||||
* @param username 用户名关键词
|
||||
* @param email 邮箱关键词
|
||||
* @return 用户列表
|
||||
*/
|
||||
Flux<User> findByUsernameContainingIgnoreCaseOrEmailContainingIgnoreCase(String username, String email);
|
||||
|
||||
/**
|
||||
* 根据账户状态统计用户数量
|
||||
* @param status 账户状态
|
||||
* @return 用户数量
|
||||
*/
|
||||
Mono<Long> countByAccountStatus(AccountStatus status);
|
||||
|
||||
/**
|
||||
* 统计指定时间之后创建的用户数量
|
||||
* @param createdAt 创建时间
|
||||
* @return 用户数量
|
||||
*/
|
||||
Mono<Long> countByCreatedAtAfter(LocalDateTime createdAt);
|
||||
|
||||
/**
|
||||
* 统计指定时间范围内创建的用户数量
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return 用户数量
|
||||
*/
|
||||
Mono<Long> countByCreatedAtBetween(LocalDateTime startTime, LocalDateTime endTime);
|
||||
|
||||
/**
|
||||
* 根据最后登录时间查找活跃用户
|
||||
* @param lastLoginAfter 最后登录时间之后
|
||||
* @return 活跃用户列表
|
||||
*/
|
||||
Flux<User> findByAccountStatusAndLastLoginAtAfter(AccountStatus status, LocalDateTime lastLoginAfter);
|
||||
|
||||
/**
|
||||
* 统计指定时间之后登录的用户数量
|
||||
* @param lastLoginAfter 最后登录时间之后
|
||||
* @return 用户数量
|
||||
*/
|
||||
Mono<Long> countByAccountStatusAndLastLoginAtAfter(AccountStatus status, LocalDateTime lastLoginAfter);
|
||||
|
||||
/**
|
||||
* 查找最近注册的用户
|
||||
* @param limit 数量限制
|
||||
* @return 用户列表
|
||||
*/
|
||||
Flux<User> findTop10ByOrderByCreatedAtDesc();
|
||||
|
||||
/**
|
||||
* 查找所有有消费积分记录的用户
|
||||
* @return 用户列表
|
||||
*/
|
||||
Flux<User> findByTotalCreditsUsedGreaterThan(Long credits);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.UserSubscription;
|
||||
import com.ainovel.server.domain.model.UserSubscription.SubscriptionStatus;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 用户订阅数据访问层
|
||||
*/
|
||||
@Repository
|
||||
public interface UserSubscriptionRepository extends ReactiveMongoRepository<UserSubscription, String> {
|
||||
|
||||
/**
|
||||
* 根据用户ID查找当前有效的订阅
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 当前有效订阅
|
||||
*/
|
||||
Mono<UserSubscription> findByUserIdAndStatusIn(String userId, SubscriptionStatus... statuses);
|
||||
|
||||
/**
|
||||
* 根据用户ID查找所有订阅历史
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 订阅历史列表
|
||||
*/
|
||||
Flux<UserSubscription> findByUserIdOrderByCreatedAtDesc(String userId);
|
||||
|
||||
/**
|
||||
* 根据用户ID查找活跃的订阅
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 活跃订阅
|
||||
*/
|
||||
Mono<UserSubscription> findByUserIdAndStatus(String userId, SubscriptionStatus status);
|
||||
|
||||
/**
|
||||
* 查找所有即将过期的订阅(7天内)
|
||||
*
|
||||
* @param endDate 结束时间
|
||||
* @return 即将过期的订阅列表
|
||||
*/
|
||||
Flux<UserSubscription> findByStatusAndEndDateBetween(SubscriptionStatus status, LocalDateTime startTime, LocalDateTime endTime);
|
||||
|
||||
/**
|
||||
* 查找所有已过期的订阅
|
||||
*
|
||||
* @param currentTime 当前时间
|
||||
* @return 已过期的订阅列表
|
||||
*/
|
||||
Flux<UserSubscription> findByStatusAndEndDateBefore(SubscriptionStatus status, LocalDateTime currentTime);
|
||||
|
||||
/**
|
||||
* 根据订阅计划ID查找所有订阅
|
||||
*
|
||||
* @param planId 订阅计划ID
|
||||
* @return 订阅列表
|
||||
*/
|
||||
Flux<UserSubscription> findByPlanId(String planId);
|
||||
|
||||
/**
|
||||
* 根据支付交易ID查找订阅
|
||||
*
|
||||
* @param transactionId 交易ID
|
||||
* @return 订阅信息
|
||||
*/
|
||||
Mono<UserSubscription> findByTransactionId(String transactionId);
|
||||
|
||||
/**
|
||||
* 查找试用期内的订阅
|
||||
*
|
||||
* @return 试用期订阅列表
|
||||
*/
|
||||
Flux<UserSubscription> findByIsTrialTrueAndStatus(SubscriptionStatus status);
|
||||
|
||||
/**
|
||||
* 查找设置了自动续费的订阅
|
||||
*
|
||||
* @return 自动续费订阅列表
|
||||
*/
|
||||
Flux<UserSubscription> findByAutoRenewalTrueAndStatus(SubscriptionStatus status);
|
||||
|
||||
/**
|
||||
* 统计用户的订阅次数
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 订阅次数
|
||||
*/
|
||||
Mono<Long> countByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 统计指定计划的订阅次数
|
||||
*
|
||||
* @param planId 计划ID
|
||||
* @return 订阅次数
|
||||
*/
|
||||
Mono<Long> countByPlanIdAndStatus(String planId, SubscriptionStatus status);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.ainovel.server.repository;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ainovel.server.domain.model.analytics.WritingEvent;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
@Repository
|
||||
public interface WritingEventRepository extends ReactiveMongoRepository<WritingEvent, String> {
|
||||
|
||||
Flux<WritingEvent> findByUserIdOrderByTimestampDesc(String userId, Pageable pageable);
|
||||
|
||||
Flux<WritingEvent> findByNovelIdOrderByTimestampDesc(String novelId, Pageable pageable);
|
||||
|
||||
Flux<WritingEvent> findBySceneIdOrderByTimestampDesc(String sceneId, Pageable pageable);
|
||||
|
||||
Flux<WritingEvent> findByUserIdAndTimestampBetweenOrderByTimestampDesc(
|
||||
String userId, LocalDateTime start, LocalDateTime end, Pageable pageable);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.ainovel.server.repository.custom;
|
||||
|
||||
import com.ainovel.server.domain.model.User;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 自定义用户仓库接口
|
||||
* 定义带有日志和计数功能的方法
|
||||
*/
|
||||
public interface CustomUserRepository {
|
||||
|
||||
/**
|
||||
* 根据用户名查找用户,并记录查询日志
|
||||
* @param username 用户名
|
||||
* @return 用户信息
|
||||
*/
|
||||
Mono<User> findByUsernameWithLogging(String username);
|
||||
|
||||
/**
|
||||
* 根据邮箱查找用户,并记录查询日志
|
||||
* @param email 邮箱
|
||||
* @return 用户信息
|
||||
*/
|
||||
Mono<User> findByEmailWithLogging(String email);
|
||||
|
||||
/**
|
||||
* 检查用户名是否存在,并记录查询日志
|
||||
* @param username 用户名
|
||||
* @return 是否存在
|
||||
*/
|
||||
Mono<Boolean> existsByUsernameWithLogging(String username);
|
||||
|
||||
/**
|
||||
* 检查邮箱是否存在,并记录查询日志
|
||||
* @param email 邮箱
|
||||
* @return 是否存在
|
||||
*/
|
||||
Mono<Boolean> existsByEmailWithLogging(String email);
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package com.ainovel.server.repository.impl;
|
||||
|
||||
import com.ainovel.server.domain.model.NextOutline;
|
||||
import com.ainovel.server.repository.NextOutlineRepository;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 剧情大纲仓库MongoDB实现
|
||||
*/
|
||||
@Repository
|
||||
public class NextOutlineRepositoryImpl implements NextOutlineRepository {
|
||||
|
||||
private final ReactiveMongoTemplate mongoTemplate;
|
||||
|
||||
@Autowired
|
||||
public NextOutlineRepositoryImpl(ReactiveMongoTemplate mongoTemplate) {
|
||||
this.mongoTemplate = mongoTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S extends NextOutline> Mono<S> save(S outline) {
|
||||
return mongoTemplate.save(outline);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<NextOutline> findById(String id) {
|
||||
return mongoTemplate.findById(id, NextOutline.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<NextOutline> findByNovelId(String novelId) {
|
||||
Query query = Query.query(Criteria.where("novelId").is(novelId));
|
||||
return mongoTemplate.find(query, NextOutline.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<NextOutline> findByNovelIdAndSelected(String novelId, boolean selected) {
|
||||
Query query = Query.query(
|
||||
Criteria.where("novelId").is(novelId)
|
||||
.and("selected").is(selected)
|
||||
);
|
||||
return mongoTemplate.find(query, NextOutline.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<NextOutline> findAll() {
|
||||
return mongoTemplate.findAll(NextOutline.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> deleteById(String id) {
|
||||
return mongoTemplate.remove(Query.query(Criteria.where("id").is(id)), NextOutline.class).then();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> deleteAll() {
|
||||
return mongoTemplate.remove(new Query(), NextOutline.class).then();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S extends NextOutline> Flux<S> saveAll(Iterable<S> entities) {
|
||||
// 将Iterable转换为Flux并逐个保存
|
||||
return Flux.fromIterable(entities)
|
||||
.flatMap(this::save);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S extends NextOutline> Flux<S> saveAll(Publisher<S> entityStream) {
|
||||
// 逐个保存Publisher中的实体
|
||||
return Flux.from(entityStream)
|
||||
.flatMap(this::save);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<NextOutline> findById(Publisher<String> id) {
|
||||
// 从Publisher获取ID并查找
|
||||
return Mono.from(id)
|
||||
.flatMap(this::findById);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> existsById(String id) {
|
||||
// 检查指定ID的实体是否存在
|
||||
return findById(id)
|
||||
.map(outline -> true)
|
||||
.defaultIfEmpty(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> existsById(Publisher<String> id) {
|
||||
// 从Publisher获取ID并检查是否存在
|
||||
return Mono.from(id)
|
||||
.flatMap(this::existsById);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<NextOutline> findAllById(Iterable<String> ids) {
|
||||
// 查询所有指定ID的实体
|
||||
return Flux.fromIterable(ids)
|
||||
.flatMap(this::findById);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<NextOutline> findAllById(Publisher<String> idStream) {
|
||||
// 从Publisher中的ID流查找所有实体
|
||||
return Flux.from(idStream)
|
||||
.flatMap(this::findById);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Long> count() {
|
||||
// 计算总数
|
||||
return mongoTemplate.count(new Query(), NextOutline.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> deleteById(Publisher<String> id) {
|
||||
// 从Publisher获取ID并删除
|
||||
return Mono.from(id)
|
||||
.flatMap(this::deleteById);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> delete(NextOutline entity) {
|
||||
// 删除指定实体
|
||||
return deleteById(entity.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> deleteAllById(Iterable<? extends String> ids) {
|
||||
// 删除所有指定ID的实体
|
||||
return Flux.fromIterable(ids)
|
||||
.flatMap(this::deleteById)
|
||||
.then();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> deleteAll(Iterable<? extends NextOutline> entities) {
|
||||
// 删除所有指定的实体
|
||||
return Flux.fromIterable(entities)
|
||||
.map(NextOutline::getId)
|
||||
.flatMap(this::deleteById)
|
||||
.then();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> deleteAll(Publisher<? extends NextOutline> entityStream) {
|
||||
// 删除Publisher中的所有实体
|
||||
return Flux.from(entityStream)
|
||||
.map(NextOutline::getId)
|
||||
.flatMap(this::deleteById)
|
||||
.then();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package com.ainovel.server.repository.impl;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.ainovel.server.domain.model.User;
|
||||
import com.ainovel.server.repository.custom.CustomUserRepository;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* UserRepository接口的自定义实现
|
||||
* 添加查询日志和计数功能
|
||||
*/
|
||||
@Component
|
||||
public class UserRepositoryImpl implements CustomUserRepository {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(UserRepositoryImpl.class);
|
||||
|
||||
private final ReactiveMongoTemplate mongoTemplate;
|
||||
|
||||
@Autowired
|
||||
public UserRepositoryImpl(ReactiveMongoTemplate mongoTemplate) {
|
||||
this.mongoTemplate = mongoTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户名查找用户,并记录查询日志
|
||||
* @param username 用户名
|
||||
* @return 用户信息
|
||||
*/
|
||||
@Override
|
||||
public Mono<User> findByUsernameWithLogging(String username) {
|
||||
logger.debug("开始查询用户: username={}", username);
|
||||
|
||||
Query query = new Query(Criteria.where("username").is(username));
|
||||
|
||||
return mongoTemplate.findOne(query, User.class)
|
||||
.doOnSuccess(user -> {
|
||||
if (user != null) {
|
||||
logger.debug("查询用户成功: username={}, userId={}", username, user.getId());
|
||||
} else {
|
||||
logger.debug("未找到用户: username={}", username);
|
||||
}
|
||||
})
|
||||
.doOnError(error ->
|
||||
logger.error("查询用户出错: username={}, error={}", username, error.getMessage())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据邮箱查找用户,并记录查询日志
|
||||
* @param email 邮箱
|
||||
* @return 用户信息
|
||||
*/
|
||||
@Override
|
||||
public Mono<User> findByEmailWithLogging(String email) {
|
||||
logger.debug("开始查询用户: email={}", email);
|
||||
|
||||
Query query = new Query(Criteria.where("email").is(email));
|
||||
|
||||
return mongoTemplate.findOne(query, User.class)
|
||||
.doOnSuccess(user -> {
|
||||
if (user != null) {
|
||||
logger.debug("查询用户成功: email={}, userId={}", email, user.getId());
|
||||
} else {
|
||||
logger.debug("未找到用户: email={}", email);
|
||||
}
|
||||
})
|
||||
.doOnError(error ->
|
||||
logger.error("查询用户出错: email={}, error={}", email, error.getMessage())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户名是否存在,并记录查询日志
|
||||
* @param username 用户名
|
||||
* @return 是否存在
|
||||
*/
|
||||
@Override
|
||||
public Mono<Boolean> existsByUsernameWithLogging(String username) {
|
||||
logger.debug("检查用户名是否存在: username={}", username);
|
||||
|
||||
Query query = new Query(Criteria.where("username").is(username));
|
||||
|
||||
return mongoTemplate.exists(query, User.class)
|
||||
.doOnSuccess(exists ->
|
||||
logger.debug("用户名存在检查结果: username={}, exists={}", username, exists)
|
||||
)
|
||||
.doOnError(error ->
|
||||
logger.error("检查用户名是否存在出错: username={}, error={}", username, error.getMessage())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查邮箱是否存在,并记录查询日志
|
||||
* @param email 邮箱
|
||||
* @return 是否存在
|
||||
*/
|
||||
@Override
|
||||
public Mono<Boolean> existsByEmailWithLogging(String email) {
|
||||
logger.debug("检查邮箱是否存在: email={}", email);
|
||||
|
||||
Query query = new Query(Criteria.where("email").is(email));
|
||||
|
||||
return mongoTemplate.exists(query, User.class)
|
||||
.doOnSuccess(exists ->
|
||||
logger.debug("邮箱存在检查结果: email={}, exists={}", email, exists)
|
||||
)
|
||||
.doOnError(error ->
|
||||
logger.error("检查邮箱是否存在出错: email={}, error={}", email, error.getMessage())
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user