Files
tiku-backend.net/Tiku.Api/Contracts/ContentManagementDtos.cs

666 lines
14 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using Tiku.Application.Content;
using Tiku.Application.QuestionBanks;
using Tiku.Domain.Common;
using Tiku.Domain.Content;
namespace Tiku.Api.Contracts;
/// <summary>
/// 内容管理查询参数。
/// </summary>
public sealed class ContentManagementQueryDto
{
/// <summary>
/// 地区 ID。
/// </summary>
public Guid? RegionId { get; set; }
/// <summary>
/// 内容入口 ID。
/// </summary>
public Guid? EntryId { get; set; }
/// <summary>
/// 节点 ID。
/// </summary>
public Guid? NodeId { get; set; }
/// <summary>
/// 题集 ID。
/// </summary>
public Guid? CollectionId { get; set; }
/// <summary>
/// 父节点 ID传 root 表示根节点。
/// </summary>
[StringLength(64)]
[RegularExpression("^(root|[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$")]
public string? ParentId { get; set; }
/// <summary>
/// 入口类型。
/// </summary>
[StringLength(50)]
public string? EntryType { get; set; }
/// <summary>
/// 题集类型。
/// </summary>
[StringLength(50)]
public string? CollectionType { get; set; }
/// <summary>
/// 模式。
/// </summary>
[StringLength(50)]
public string? Mode { get; set; }
/// <summary>
/// 标记类型。
/// </summary>
[StringLength(50)]
public string? MarkerType { get; set; }
/// <summary>
/// 关键字。
/// </summary>
[StringLength(100)]
public string? Keyword { get; set; }
/// <summary>
/// 是否包含停用数据。
/// </summary>
public bool IncludeInactive { get; set; }
/// <summary>
/// 返回数量上限。
/// </summary>
[Range(1, 1000)]
public int? Limit { get; set; }
public ContentManagementFilter ToFilter()
{
return new ContentManagementFilter(
RegionId,
EntryId,
NodeId,
CollectionId,
ParentId,
EntryType,
CollectionType,
Mode,
MarkerType,
Keyword,
IncludeInactive,
Limit);
}
}
/// <summary>
/// 新增或更新内容条目请求 DTO。
/// </summary>
public sealed class UpsertContentEntryDto
{
/// <summary>
/// ID。
/// </summary>
public Guid? Id { get; set; }
/// <summary>
/// 地区 ID。
/// </summary>
public Guid? RegionId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
[StringLength(64)]
public string? LegacyId { get; set; }
/// <summary>
/// 入口键。
/// </summary>
[StringLength(100)]
public string? EntryKey { get; set; }
/// <summary>
/// 名称。
/// </summary>
[Required]
[StringLength(300)]
public string Name { get; set; } = string.Empty;
/// <summary>
/// 入口类型。
/// </summary>
[StringLength(50)]
public string? EntryType { get; set; }
/// <summary>
/// 图标。
/// </summary>
[StringLength(100)]
public string? Icon { get; set; }
/// <summary>
/// 路由地址。
/// </summary>
[StringLength(500)]
public string? Route { get; set; }
/// <summary>
/// 说明。
/// </summary>
[StringLength(2000)]
public string? Description { get; set; }
/// <summary>
/// 可见性。
/// </summary>
[StringLength(50)]
public string? Visibility { get; set; }
/// <summary>
/// 访问规则。
/// </summary>
public JsonElement AccessRules { get; set; } = JsonDefaults.Object();
/// <summary>
/// 布局配置。
/// </summary>
public JsonElement LayoutConfig { get; set; } = JsonDefaults.Object();
/// <summary>
/// 显示顺序。
/// </summary>
public int? Order { get; set; }
/// <summary>
/// 是否启用。
/// </summary>
public bool? IsActive { get; set; }
public UpsertContentEntryCommand ToCommand()
{
return new UpsertContentEntryCommand(
Id,
RegionId,
LegacyId,
EntryKey,
Name,
EntryType,
Icon,
Route,
Description,
Visibility,
AccessRules,
LayoutConfig,
Order,
IsActive);
}
}
/// <summary>
/// 新增或更新内容节点请求 DTO。
/// </summary>
public sealed class UpsertContentNodeDto
{
/// <summary>
/// ID。
/// </summary>
public Guid? Id { get; set; }
/// <summary>
/// 内容入口 ID。
/// </summary>
[Required]
public Guid EntryId { get; set; }
/// <summary>
/// 地区 ID。
/// </summary>
public Guid? RegionId { get; set; }
/// <summary>
/// 父节点 ID。
/// </summary>
public Guid? ParentId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
[StringLength(64)]
public string? LegacyId { get; set; }
/// <summary>
/// 节点键。
/// </summary>
[StringLength(100)]
public string? NodeKey { get; set; }
/// <summary>
/// 名称。
/// </summary>
[Required]
[StringLength(300)]
public string Name { get; set; } = string.Empty;
/// <summary>
/// 节点Type。
/// </summary>
[StringLength(50)]
public string? NodeType { get; set; }
/// <summary>
/// 标记类型。
/// </summary>
[StringLength(50)]
public string? MarkerType { get; set; }
/// <summary>
/// 标记配置。
/// </summary>
public JsonElement MarkerConfig { get; set; } = JsonDefaults.Object();
/// <summary>
/// 显示顺序。
/// </summary>
public int? Order { get; set; }
/// <summary>
/// 是否启用。
/// </summary>
public bool? IsActive { get; set; }
/// <summary>
/// 是否可选择。
/// </summary>
public bool? IsSelectable { get; set; }
/// <summary>
/// 是否叶子节点。
/// </summary>
public bool? IsLeaf { get; set; }
/// <summary>
/// 访问规则。
/// </summary>
public JsonElement AccessRules { get; set; } = JsonDefaults.Object();
/// <summary>
/// 扩展元数据。
/// </summary>
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
public UpsertContentNodeCommand ToCommand()
{
return new UpsertContentNodeCommand(
Id,
EntryId,
RegionId,
ParentId,
LegacyId,
NodeKey,
Name,
NodeType,
MarkerType,
MarkerConfig,
Order,
IsActive,
IsSelectable,
IsLeaf,
AccessRules,
Metadata);
}
}
/// <summary>
/// 新增或更新题目题集请求 DTO。
/// </summary>
public sealed class UpsertQuestionCollectionDto
{
/// <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? NodeId { 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>
[StringLength(64)]
public string? LegacyId { get; set; }
/// <summary>
/// 名称。
/// </summary>
[Required]
[StringLength(300)]
public string Name { get; set; } = string.Empty;
/// <summary>
/// 题集类型。
/// </summary>
[StringLength(50)]
public string? CollectionType { get; set; }
/// <summary>
/// 来源类型。
/// </summary>
[StringLength(50)]
public string? SourceType { get; set; }
/// <summary>
/// 筛选条件。
/// </summary>
public JsonElement Filters { get; set; } = JsonDefaults.Object();
/// <summary>
/// 总分。
/// </summary>
public decimal? TotalScore { get; set; }
/// <summary>
/// 时长,单位为分钟。
/// </summary>
public int? DurationMinutes { get; set; }
/// <summary>
/// 状态。
/// </summary>
[StringLength(50)]
public string? Status { get; set; }
/// <summary>
/// 显示顺序。
/// </summary>
public int? Order { get; set; }
/// <summary>
/// 访问规则。
/// </summary>
public JsonElement AccessRules { get; set; } = JsonDefaults.Object();
/// <summary>
/// 扩展元数据。
/// </summary>
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
public UpsertQuestionCollectionCommand ToCommand()
{
return new UpsertQuestionCollectionCommand(
Id,
RegionId,
EntryId,
NodeId,
SubjectId,
CategoryId,
QuestionBankId,
LegacyId,
Name,
CollectionType,
SourceType,
Filters,
TotalScore,
DurationMinutes,
Status,
Order,
AccessRules,
Metadata);
}
}
/// <summary>
/// 题集题目请求 DTO。
/// </summary>
public sealed class CollectionQuestionDto
{
/// <summary>
/// 题目 ID。
/// </summary>
[Required]
public Guid QuestionId { get; set; }
/// <summary>
/// 来源。
/// </summary>
[Required]
public QuestionSource Source { get; set; } = QuestionSource.Tenant;
/// <summary>
/// 分段键。
/// </summary>
[StringLength(100)]
public string? SectionKey { get; set; }
/// <summary>
/// 显示顺序。
/// </summary>
public int? Order { get; set; }
/// <summary>
/// 分数。
/// </summary>
public decimal? Score { get; set; }
/// <summary>
/// 是否必填。
/// </summary>
public bool? Required { get; set; }
/// <summary>
/// 扩展元数据。
/// </summary>
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
public CollectionQuestionCommand ToCommand()
{
return new CollectionQuestionCommand(
new QuestionLocator(Source, QuestionId),
SectionKey,
Order,
Score,
Required,
Metadata);
}
}
/// <summary>
/// 替换题集Items请求 DTO。
/// </summary>
public sealed class ReplaceCollectionItemsDto
{
/// <summary>
/// 题集 ID。
/// </summary>
[Required]
public Guid CollectionId { get; set; }
/// <summary>
/// 题目列表。
/// </summary>
public IReadOnlyCollection<CollectionQuestionDto> Questions { get; set; } = [];
public ReplaceCollectionItemsCommand ToCommand()
{
return new ReplaceCollectionItemsCommand(
CollectionId,
Questions.Select(question => question.ToCommand()).ToArray());
}
}
/// <summary>
/// 新增或更新练习Blueprint请求 DTO。
/// </summary>
public sealed class UpsertPracticeBlueprintDto
{
/// <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? NodeId { get; set; }
/// <summary>
/// 题集 ID。
/// </summary>
public Guid? CollectionId { get; set; }
/// <summary>
/// 历史系统 ID。
/// </summary>
[StringLength(64)]
public string? LegacyId { get; set; }
/// <summary>
/// 名称。
/// </summary>
[Required]
[StringLength(300)]
public string Name { get; set; } = string.Empty;
/// <summary>
/// 模式。
/// </summary>
[StringLength(50)]
public string? Mode { get; set; }
/// <summary>
/// 组卷方式。
/// </summary>
[StringLength(50)]
public string? AssemblyType { get; set; }
/// <summary>
/// 题目数量上限。
/// </summary>
public int? QuestionLimit { get; set; }
/// <summary>
/// 时长,单位为分钟。
/// </summary>
public int? DurationMinutes { get; set; }
/// <summary>
/// 总分。
/// </summary>
public decimal? TotalScore { get; set; }
/// <summary>
/// 及格分。
/// </summary>
public decimal? PassScore { get; set; }
/// <summary>
/// 分段配置。
/// </summary>
public JsonElement Sections { get; set; } = JsonDefaults.Array();
/// <summary>
/// 规则配置。
/// </summary>
public JsonElement Rules { get; set; } = JsonDefaults.Object();
/// <summary>
/// 访问规则。
/// </summary>
public JsonElement AccessRules { get; set; } = JsonDefaults.Object();
/// <summary>
/// 状态。
/// </summary>
[StringLength(50)]
public string? Status { get; set; }
/// <summary>
/// 显示顺序。
/// </summary>
public int? Order { get; set; }
public UpsertPracticeBlueprintCommand ToCommand()
{
return new UpsertPracticeBlueprintCommand(
Id,
RegionId,
EntryId,
NodeId,
CollectionId,
LegacyId,
Name,
Mode,
AssemblyType,
QuestionLimit,
DurationMinutes,
TotalScore,
PassScore,
Sections,
Rules,
AccessRules,
Status,
Order);
}
}
/// <summary>
/// 导入Template查询参数。
/// </summary>
public sealed class ImportTemplateQueryDto
{
/// <summary>
/// 导入Type。
/// </summary>
[Required]
[StringLength(50)]
public string ImportType { get; set; } = string.Empty;
/// <summary>
/// 导出格式。
/// </summary>
[StringLength(10)]
public string? Format { get; set; }
}