feat(saas): implement marketplace and tenant onboarding

This commit is contained in:
2026-07-29 13:58:59 +08:00
parent 76606029e2
commit 6db200a2fc
145 changed files with 16862 additions and 94529 deletions

View File

@@ -5,28 +5,73 @@ using Tiku.Domain.Common;
namespace Tiku.Api.Contracts;
/// <summary>
/// 管理侧内容查询参数。
/// </summary>
public sealed class DirectContentQueryDto
{
/// <summary>
/// 地区 ID。
/// </summary>
public Guid? RegionId { get; set; }
/// <summary>
/// 内容入口 ID。
/// </summary>
public Guid? EntryId { get; set; }
/// <summary>
/// 内容节点 ID。
/// </summary>
public Guid? ContentNodeId { get; set; }
/// <summary>
/// 父节点 ID。
/// </summary>
public Guid? ParentId { get; set; }
/// <summary>
/// 科目 ID。
/// </summary>
public Guid? SubjectId { get; set; }
/// <summary>
/// 章节 ID。
/// </summary>
public Guid? ChapterId { get; set; }
/// <summary>
/// 单元 ID。
/// </summary>
public Guid? UnitId { get; set; }
/// <summary>
/// 院校 ID。
/// </summary>
public Guid? SchoolId { get; set; }
/// <summary>
/// 专业 ID。
/// </summary>
public Guid? MajorId { get; set; }
/// <summary>
/// 题目 ID。
/// </summary>
public Guid? QuestionId { get; set; }
/// <summary>
/// 状态。
/// </summary>
[StringLength(50)]
public string? Status { get; set; }
/// <summary>
/// 关键字。
/// </summary>
[StringLength(200)]
public string? Keyword { get; set; }
/// <summary>
/// 年份。
/// </summary>
[Range(1900, 3000)]
public int? Year { get; set; }
/// <summary>
/// 返回数量上限。
/// </summary>
[Range(1, 1000)]
public int? Limit { get; set; }
@@ -50,37 +95,121 @@ public sealed class DirectContentQueryDto
}
}
/// <summary>
/// 管理侧题目写入请求。
/// </summary>
public sealed class DirectQuestionWriteDto
{
/// <summary>
/// 题目 ID。
/// </summary>
public Guid? QuestionId { get; set; }
/// <summary>
/// 题库 ID。
/// </summary>
public Guid? QuestionBankId { get; set; }
/// <summary>
/// 科目 ID。
/// </summary>
public Guid? SubjectId { get; set; }
/// <summary>
/// 分类 ID。
/// </summary>
public Guid? CategoryId { get; set; }
/// <summary>
/// 节点 ID。
/// </summary>
public Guid? NodeId { get; set; }
/// <summary>
/// 内容入口 ID。
/// </summary>
public Guid? EntryId { get; set; }
/// <summary>
/// 内容节点 ID。
/// </summary>
public Guid? ContentNodeId { get; set; }
/// <summary>
/// 主题集 ID。
/// </summary>
public Guid? PrimaryCollectionId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
public string? LegacyId { get; set; }
/// <summary>
/// 类型。
/// </summary>
public string? Type { get; set; }
/// <summary>
/// 类型显示名。
/// </summary>
public string? TypeLabel { get; set; }
/// <summary>
/// 难度。
/// </summary>
[Range(1, 5)]
public int? Difficulty { get; set; }
/// <summary>
/// 标签列表。
/// </summary>
public JsonElement Tags { get; set; } = JsonDefaults.Array();
/// <summary>
/// 内容。
/// </summary>
public string? Content { get; set; }
/// <summary>
/// 选项配置。
/// </summary>
public JsonElement Options { get; set; } = JsonDefaults.Array();
/// <summary>
/// 正确选项索引。
/// </summary>
public int? CorrectOptionIndex { get; set; }
/// <summary>
/// 正确选项索引列表。
/// </summary>
public JsonElement CorrectOptionIndices { get; set; } = JsonDefaults.Array();
/// <summary>
/// 文字答案。
/// </summary>
public string? AnswerText { get; set; }
/// <summary>
/// 解析。
/// </summary>
public string? Explanation { get; set; }
/// <summary>
/// 子题列表。
/// </summary>
public JsonElement SubQuestions { get; set; } = JsonDefaults.Array();
/// <summary>
/// 代码语言。
/// </summary>
public string? CodeLang { get; set; }
/// <summary>
/// 代码模板。
/// </summary>
public string? CodeTemplate { get; set; }
/// <summary>
/// 媒体地址。
/// </summary>
public string? MediaUrl { get; set; }
/// <summary>
/// 状态。
/// </summary>
public string? Status { get; set; }
/// <summary>
/// 考试标记配置。
/// </summary>
public JsonElement ExamMarkers { get; set; } = JsonDefaults.Object();
/// <summary>
/// 来源哈希。
/// </summary>
public string? SourceHash { get; set; }
/// <summary>
/// 是否创建题目版本。
/// </summary>
public bool? CreateVersion { get; set; }
public QuestionWriteCommand ToCommand(bool createVersionDefault)
@@ -116,18 +245,54 @@ public sealed class DirectQuestionWriteDto
}
}
/// <summary>
/// 管理侧词汇单元写入请求。
/// </summary>
public sealed class DirectVocabularyUnitDto
{
/// <summary>
/// ID。
/// </summary>
public Guid? Id { get; set; }
/// <summary>
/// 地区 ID。
/// </summary>
public Guid? RegionId { get; set; }
/// <summary>
/// 内容入口 ID。
/// </summary>
public Guid? EntryId { get; set; }
/// <summary>
/// 内容节点 ID。
/// </summary>
public Guid? ContentNodeId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
public string? LegacyId { get; set; }
/// <summary>
/// 名称。
/// </summary>
public required string Name { get; set; }
/// <summary>
/// 说明。
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 单词数量。
/// </summary>
public int? WordCount { get; set; }
/// <summary>
/// 显示顺序。
/// </summary>
public int? Order { get; set; }
/// <summary>
/// 是否启用。
/// </summary>
public bool? IsActive { get; set; }
/// <summary>
/// 扩展元数据。
/// </summary>
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
public VocabularyUnitCommand ToCommand()
@@ -136,22 +301,70 @@ public sealed class DirectVocabularyUnitDto
}
}
/// <summary>
/// 管理侧词汇单词写入请求。
/// </summary>
public sealed class DirectVocabularyWordDto
{
/// <summary>
/// ID。
/// </summary>
public Guid? Id { get; set; }
/// <summary>
/// 单元 ID。
/// </summary>
public Guid? UnitId { get; set; }
/// <summary>
/// 内容入口 ID。
/// </summary>
public Guid? EntryId { get; set; }
/// <summary>
/// 内容节点 ID。
/// </summary>
public Guid? ContentNodeId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
public string? LegacyId { get; set; }
/// <summary>
/// 单词。
/// </summary>
public required string Word { get; set; }
/// <summary>
/// 音标。
/// </summary>
public string? Phonetic { get; set; }
/// <summary>
/// 释义。
/// </summary>
public string? Meaning { get; set; }
/// <summary>
/// 例句。
/// </summary>
public string? Example { get; set; }
/// <summary>
/// 例句翻译。
/// </summary>
public string? ExampleTranslation { get; set; }
/// <summary>
/// 难度。
/// </summary>
public int? Difficulty { get; set; }
/// <summary>
/// 标签列表。
/// </summary>
public JsonElement Tags { get; set; } = JsonDefaults.Array();
/// <summary>
/// 显示顺序。
/// </summary>
public int? Order { get; set; }
/// <summary>
/// 是否启用。
/// </summary>
public bool? IsActive { get; set; }
/// <summary>
/// 扩展元数据。
/// </summary>
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
public VocabularyWordCommand ToCommand()
@@ -175,22 +388,70 @@ public sealed class DirectVocabularyWordDto
}
}
/// <summary>
/// 管理侧知识手册科目写入请求。
/// </summary>
public sealed class DirectHandbookSubjectDto
{
/// <summary>
/// ID。
/// </summary>
public Guid? Id { get; set; }
/// <summary>
/// 地区 ID。
/// </summary>
public Guid? RegionId { get; set; }
/// <summary>
/// 院校 ID。
/// </summary>
public Guid? SchoolId { get; set; }
/// <summary>
/// 专业 ID。
/// </summary>
public Guid? MajorId { get; set; }
/// <summary>
/// 内容入口 ID。
/// </summary>
public Guid? EntryId { get; set; }
/// <summary>
/// 内容节点 ID。
/// </summary>
public Guid? ContentNodeId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
public string? LegacyId { get; set; }
/// <summary>
/// 名称。
/// </summary>
public required string Name { get; set; }
/// <summary>
/// 类型。
/// </summary>
public string? Type { get; set; }
/// <summary>
/// 图标。
/// </summary>
public string? Icon { get; set; }
/// <summary>
/// 颜色。
/// </summary>
public string? Color { get; set; }
/// <summary>
/// 说明。
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 显示顺序。
/// </summary>
public int? Order { get; set; }
/// <summary>
/// 是否启用。
/// </summary>
public bool? IsActive { get; set; }
/// <summary>
/// 扩展元数据。
/// </summary>
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
public HandbookSubjectCommand ToCommand()
@@ -214,17 +475,50 @@ public sealed class DirectHandbookSubjectDto
}
}
/// <summary>
/// 管理侧知识手册章节写入请求。
/// </summary>
public sealed class DirectHandbookChapterDto
{
/// <summary>
/// ID。
/// </summary>
public Guid? Id { get; set; }
/// <summary>
/// 科目 ID。
/// </summary>
public Guid? SubjectId { get; set; }
/// <summary>
/// 内容入口 ID。
/// </summary>
public Guid? EntryId { get; set; }
/// <summary>
/// 内容节点 ID。
/// </summary>
public Guid? ContentNodeId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
public string? LegacyId { get; set; }
/// <summary>
/// 名称。
/// </summary>
public required string Name { get; set; }
/// <summary>
/// 说明。
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 显示顺序。
/// </summary>
public int? Order { get; set; }
/// <summary>
/// 是否启用。
/// </summary>
public bool? IsActive { get; set; }
/// <summary>
/// 扩展元数据。
/// </summary>
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
public HandbookChapterCommand ToCommand()
@@ -233,19 +527,58 @@ public sealed class DirectHandbookChapterDto
}
}
/// <summary>
/// 管理侧知识手册条目写入请求。
/// </summary>
public sealed class DirectHandbookEntryDto
{
/// <summary>
/// ID。
/// </summary>
public Guid? Id { get; set; }
/// <summary>
/// 章节 ID。
/// </summary>
public Guid? ChapterId { get; set; }
/// <summary>
/// 内容入口 ID。
/// </summary>
public Guid? EntryId { get; set; }
/// <summary>
/// 内容节点 ID。
/// </summary>
public Guid? ContentNodeId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
public string? LegacyId { get; set; }
/// <summary>
/// 标题。
/// </summary>
public required string Title { get; set; }
/// <summary>
/// 摘要。
/// </summary>
public string? Summary { get; set; }
/// <summary>
/// 内容。
/// </summary>
public string? Content { get; set; }
/// <summary>
/// 标签列表。
/// </summary>
public JsonElement Tags { get; set; } = JsonDefaults.Array();
/// <summary>
/// 显示顺序。
/// </summary>
public int? Order { get; set; }
/// <summary>
/// 是否启用。
/// </summary>
public bool? IsActive { get; set; }
/// <summary>
/// 扩展元数据。
/// </summary>
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
public HandbookEntryCommand ToCommand()
@@ -254,13 +587,34 @@ public sealed class DirectHandbookEntryDto
}
}
/// <summary>
/// 管理侧院校写入请求。
/// </summary>
public sealed class DirectSchoolDto
{
/// <summary>
/// ID。
/// </summary>
public Guid? Id { get; set; }
/// <summary>
/// 地区 ID。
/// </summary>
public Guid? RegionId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
public string? LegacyId { get; set; }
/// <summary>
/// 名称。
/// </summary>
public required string Name { get; set; }
/// <summary>
/// 专业考试日期。
/// </summary>
public string? ProfessionalExamDate { get; set; }
/// <summary>
/// 扩展元数据。
/// </summary>
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
public SchoolCommand ToCommand()
@@ -269,16 +623,46 @@ public sealed class DirectSchoolDto
}
}
/// <summary>
/// 管理侧专业写入请求。
/// </summary>
public sealed class DirectMajorDto
{
/// <summary>
/// ID。
/// </summary>
public Guid? Id { get; set; }
/// <summary>
/// 地区 ID。
/// </summary>
public Guid? RegionId { get; set; }
/// <summary>
/// 院校 ID。
/// </summary>
public Guid? SchoolId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
public string? LegacyId { get; set; }
/// <summary>
/// 名称。
/// </summary>
public required string Name { get; set; }
/// <summary>
/// 说明。
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 备考建议。
/// </summary>
public string? StudyTips { get; set; }
/// <summary>
/// 显示顺序。
/// </summary>
public int? Order { get; set; }
/// <summary>
/// 是否启用。
/// </summary>
public bool? IsActive { get; set; }
public MajorCommand ToCommand()
@@ -287,22 +671,70 @@ public sealed class DirectMajorDto
}
}
/// <summary>
/// 管理侧分数线字段写入请求。
/// </summary>
public sealed class DirectScorelineFieldDto
{
/// <summary>
/// ID。
/// </summary>
public Guid? Id { get; set; }
/// <summary>
/// 地区 ID。
/// </summary>
public Guid? RegionId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
public string? LegacyId { get; set; }
/// <summary>
/// 字段键。
/// </summary>
public required string FieldKey { get; set; }
/// <summary>
/// 字段名称。
/// </summary>
public required string FieldName { get; set; }
/// <summary>
/// 字段类型。
/// </summary>
public string? FieldType { get; set; }
/// <summary>
/// 单位。
/// </summary>
public string? Unit { get; set; }
/// <summary>
/// 是否可筛选。
/// </summary>
public bool? IsFilter { get; set; }
/// <summary>
/// 是否必填。
/// </summary>
public bool? IsRequired { get; set; }
/// <summary>
/// 是否可见。
/// </summary>
public bool? IsVisible { get; set; }
/// <summary>
/// 是否参与趋势展示。
/// </summary>
public bool? IsTrend { get; set; }
/// <summary>
/// 选项配置。
/// </summary>
public JsonElement Options { get; set; } = JsonDefaults.Array();
/// <summary>
/// 占位提示。
/// </summary>
public string? Placeholder { get; set; }
/// <summary>
/// 说明。
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 显示顺序。
/// </summary>
public int? Order { get; set; }
public ScorelineFieldCommand ToCommand()
@@ -326,19 +758,49 @@ public sealed class DirectScorelineFieldDto
}
}
/// <summary>
/// 管理侧分数线记录写入请求。
/// </summary>
public sealed class DirectScorelineRecordDto
{
/// <summary>
/// ID。
/// </summary>
public Guid? Id { get; set; }
/// <summary>
/// 地区 ID。
/// </summary>
public Guid? RegionId { get; set; }
/// <summary>
/// 院校 ID。
/// </summary>
public Guid? SchoolId { get; set; }
/// <summary>
/// 专业 ID。
/// </summary>
public Guid? MajorId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
public string? LegacyId { get; set; }
/// <summary>
/// 年份。
/// </summary>
[Range(1900, 3000)]
public int Year { get; set; }
/// <summary>
/// 院校名称。
/// </summary>
public string? SchoolName { get; set; }
/// <summary>
/// 专业名称。
/// </summary>
public string? MajorName { get; set; }
/// <summary>
/// 动态字段值。
/// </summary>
public JsonElement FieldValues { get; set; } = JsonDefaults.Object();
public ScorelineRecordCommand ToCommand()
@@ -356,21 +818,66 @@ public sealed class DirectScorelineRecordDto
}
}
/// <summary>
/// 管理侧视频写入请求。
/// </summary>
public sealed class DirectVideoDto
{
/// <summary>
/// ID。
/// </summary>
public Guid? Id { get; set; }
/// <summary>
/// 科目 ID。
/// </summary>
public Guid? SubjectId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
public string? LegacyId { get; set; }
/// <summary>
/// 标题。
/// </summary>
public required string Title { get; set; }
/// <summary>
/// 说明。
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 视频地址。
/// </summary>
public string? VideoUrl { get; set; }
/// <summary>
/// 缩略图地址。
/// </summary>
public string? ThumbnailUrl { get; set; }
/// <summary>
/// 时长,单位为秒。
/// </summary>
public int? DurationSeconds { get; set; }
/// <summary>
/// 知识标签。
/// </summary>
public JsonElement KnowledgeTags { get; set; } = JsonDefaults.Array();
/// <summary>
/// 是否通用视频。
/// </summary>
public bool? IsGeneral { get; set; }
/// <summary>
/// 难度。
/// </summary>
public int? Difficulty { get; set; }
/// <summary>
/// 显示顺序。
/// </summary>
public int? Order { get; set; }
/// <summary>
/// 是否启用。
/// </summary>
public bool? IsActive { get; set; }
/// <summary>
/// 扩展元数据。
/// </summary>
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
public VideoExplanationCommand ToCommand()
@@ -393,13 +900,34 @@ public sealed class DirectVideoDto
}
}
/// <summary>
/// 管理侧题目视频绑定请求。
/// </summary>
public sealed class DirectQuestionVideoDto
{
/// <summary>
/// 题目 ID。
/// </summary>
public Guid QuestionId { get; set; }
/// <summary>
/// 视频 ID。
/// </summary>
public Guid VideoId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
public string? LegacyId { get; set; }
/// <summary>
/// 视频类型。
/// </summary>
public string? VideoType { get; set; }
/// <summary>
/// 显示顺序。
/// </summary>
public int? Order { get; set; }
/// <summary>
/// 扩展元数据。
/// </summary>
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
public QuestionVideoCommand ToCommand()
@@ -408,28 +936,94 @@ public sealed class DirectQuestionVideoDto
}
}
/// <summary>
/// 管理侧运营内容写入请求。
/// </summary>
public sealed class DirectOperationContentDto
{
/// <summary>
/// ID。
/// </summary>
public Guid? Id { get; set; }
/// <summary>
/// 地区 ID。
/// </summary>
public Guid? RegionId { get; set; }
/// <summary>
/// 院校 ID。
/// </summary>
public Guid? SchoolId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
public string? LegacyId { get; set; }
/// <summary>
/// 标题。
/// </summary>
public string? Title { get; set; }
/// <summary>
/// 副标题。
/// </summary>
public string? Subtitle { get; set; }
/// <summary>
/// 内容。
/// </summary>
public string? Content { get; set; }
/// <summary>
/// 问题。
/// </summary>
public string? Question { get; set; }
/// <summary>
/// 答案。
/// </summary>
public string? Answer { get; set; }
/// <summary>
/// 链接地址。
/// </summary>
public string? Link { get; set; }
/// <summary>
/// 按钮文案。
/// </summary>
public string? ButtonText { get; set; }
/// <summary>
/// 按钮链接。
/// </summary>
public string? ButtonLink { get; set; }
/// <summary>
/// 背景颜色。
/// </summary>
public string? BackgroundColor { get; set; }
/// <summary>
/// 边框颜色。
/// </summary>
public string? BorderColor { get; set; }
/// <summary>
/// 考试名称。
/// </summary>
public string? ExamName { get; set; }
/// <summary>
/// 考试时间。
/// </summary>
public DateTimeOffset? ExamAt { get; set; }
/// <summary>
/// 考试类型。
/// </summary>
public string? ExamType { get; set; }
/// <summary>
/// 说明。
/// </summary>
public string? Description { get; set; }
/// <summary>
/// 显示顺序。
/// </summary>
public int? Order { get; set; }
/// <summary>
/// 是否启用。
/// </summary>
public bool? IsActive { get; set; }
/// <summary>
/// 扩展元数据。
/// </summary>
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
public OperationContentCommand ToCommand()
@@ -459,27 +1053,90 @@ public sealed class DirectOperationContentDto
}
}
/// <summary>
/// 管理侧内容导入请求。
/// </summary>
public sealed class DirectImportDto
{
/// <summary>
/// 来源格式。
/// </summary>
public string? SourceFormat { get; set; }
/// <summary>
/// 来源名称。
/// </summary>
public string? SourceName { get; set; }
/// <summary>
/// 地区 ID。
/// </summary>
public Guid? RegionId { get; set; }
/// <summary>
/// 内容入口 ID。
/// </summary>
public Guid? EntryId { get; set; }
/// <summary>
/// 内容节点 ID。
/// </summary>
public Guid? ContentNodeId { get; set; }
/// <summary>
/// 科目 ID。
/// </summary>
public Guid? SubjectId { get; set; }
/// <summary>
/// 分类 ID。
/// </summary>
public Guid? CategoryId { get; set; }
/// <summary>
/// 题库 ID。
/// </summary>
public Guid? QuestionBankId { get; set; }
/// <summary>
/// 题集 ID。
/// </summary>
public Guid? CollectionId { get; set; }
/// <summary>
/// 是否异步执行。
/// </summary>
public bool? Async { get; set; }
/// <summary>
/// 数据项列表。
/// </summary>
public IReadOnlyCollection<JsonElement>? Items { get; set; }
/// <summary>
/// 单元数据列表。
/// </summary>
public IReadOnlyCollection<JsonElement>? Units { get; set; }
/// <summary>
/// 单词数据列表。
/// </summary>
public IReadOnlyCollection<JsonElement>? Words { get; set; }
/// <summary>
/// 科目数据列表。
/// </summary>
public IReadOnlyCollection<JsonElement>? Subjects { get; set; }
/// <summary>
/// 条目数据列表。
/// </summary>
public IReadOnlyCollection<JsonElement>? Entries { get; set; }
/// <summary>
/// 字段数据列表。
/// </summary>
public IReadOnlyCollection<JsonElement>? Fields { get; set; }
/// <summary>
/// 院校数据列表。
/// </summary>
public IReadOnlyCollection<JsonElement>? Schools { get; set; }
/// <summary>
/// 专业数据列表。
/// </summary>
public IReadOnlyCollection<JsonElement>? Majors { get; set; }
/// <summary>
/// 记录数据列表。
/// </summary>
public IReadOnlyCollection<JsonElement>? Records { get; set; }
/// <summary>
/// 视频数据列表。
/// </summary>
public IReadOnlyCollection<JsonElement>? Videos { get; set; }
public SimpleImportCommand ToCommand(string importType, bool dryRun)
@@ -513,7 +1170,13 @@ public sealed class DirectImportDto
}
}
/// <summary>
/// 管理侧内容导入任务查询请求。
/// </summary>
public sealed class DirectImportJobDto
{
/// <summary>
/// 任务 ID。
/// </summary>
public Guid JobId { get; set; }
}