forked from gongxuegit/tiku-backend.net
feat(saas): implement marketplace and tenant onboarding
This commit is contained in:
@@ -6,15 +6,27 @@ using Tiku.Domain.Content;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 资产访问签名查询参数。
|
||||
/// </summary>
|
||||
public sealed class AssetAccessQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 租户编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? TenantCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 有效期秒数。
|
||||
/// </summary>
|
||||
[Range(1, 7200)]
|
||||
public int? ExpiresInSeconds { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 资产访问签名响应。
|
||||
/// </summary>
|
||||
public sealed record AssetAccessResponseDto(
|
||||
ContentAssetAccessSummaryDto Item,
|
||||
AssetAccessPrincipalDto Access,
|
||||
@@ -34,6 +46,9 @@ public sealed record AssetAccessResponseDto(
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 内容资产访问摘要。
|
||||
/// </summary>
|
||||
public sealed record ContentAssetAccessSummaryDto(
|
||||
Guid Id,
|
||||
ContentAssetType AssetType,
|
||||
@@ -60,11 +75,17 @@ public sealed record ContentAssetAccessSummaryDto(
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 资产访问Principal请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record AssetAccessPrincipalDto(
|
||||
Guid? UserId,
|
||||
bool IsMember,
|
||||
bool HasSvip);
|
||||
|
||||
/// <summary>
|
||||
/// SignedStorageUrl请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record SignedStorageUrlDto(
|
||||
string Provider,
|
||||
string? Bucket,
|
||||
|
||||
@@ -3,39 +3,84 @@ using Tiku.Application.Assets;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 资产查询参数。
|
||||
/// </summary>
|
||||
public sealed class AssetQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 租户编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? TenantCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地区 ID。
|
||||
/// </summary>
|
||||
public Guid? RegionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 科目 ID。
|
||||
/// </summary>
|
||||
public Guid? SubjectId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类 ID。
|
||||
/// </summary>
|
||||
public Guid? CategoryId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 内容节点 ID。
|
||||
/// </summary>
|
||||
public Guid? ContentNodeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 题目 ID。
|
||||
/// </summary>
|
||||
public Guid? QuestionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 资产 ID。
|
||||
/// </summary>
|
||||
public Guid? AssetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 资产类型。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? AssetType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 资产键。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? AssetKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关键字。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Keyword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否包含锁定资源。
|
||||
/// </summary>
|
||||
public bool IncludeLocked { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否包含停用数据。
|
||||
/// </summary>
|
||||
public bool IncludeInactive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 500)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
|
||||
@@ -5,64 +5,130 @@ using Tiku.Domain.Common;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 创建资产上传签名请求。
|
||||
/// </summary>
|
||||
public sealed class AssetUploadSignDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 资产 ID。
|
||||
/// </summary>
|
||||
public Guid? AssetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地区 ID。
|
||||
/// </summary>
|
||||
public Guid? RegionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 科目 ID。
|
||||
/// </summary>
|
||||
public Guid? SubjectId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类 ID。
|
||||
/// </summary>
|
||||
public Guid? CategoryId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 内容节点 ID。
|
||||
/// </summary>
|
||||
public Guid? ContentNodeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 资产键。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? AssetKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标题。
|
||||
/// </summary>
|
||||
[StringLength(300)]
|
||||
public string? Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 说明。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件名。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(500)]
|
||||
public string FileName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// MIME 类型。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(200)]
|
||||
public string MimeType { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 文件大小,单位为字节。
|
||||
/// </summary>
|
||||
[Range(0, long.MaxValue)]
|
||||
public long? FileSizeBytes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// SHA-256 校验值。
|
||||
/// </summary>
|
||||
[RegularExpression("^[A-Fa-f0-9]{64}$")]
|
||||
public string? ChecksumSha256 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 资产类型。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? AssetType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 可见性。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Visibility { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否公开。
|
||||
/// </summary>
|
||||
public bool? IsPublic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 服务提供方。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Provider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 存储桶。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? Bucket { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 对象存储键。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? ObjectKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 有效期秒数。
|
||||
/// </summary>
|
||||
[Range(1, 3600)]
|
||||
public int? ExpiresInSeconds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
|
||||
public AssetUploadSignCommand ToCommand()
|
||||
@@ -92,17 +158,32 @@ public sealed class AssetUploadSignDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 确认资产上传请求。
|
||||
/// </summary>
|
||||
public sealed class AssetUploadConfirmDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 资产 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid AssetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// MIME 类型。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? MimeType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件大小,单位为字节。
|
||||
/// </summary>
|
||||
[Range(0, long.MaxValue)]
|
||||
public long? FileSizeBytes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// SHA-256 校验值。
|
||||
/// </summary>
|
||||
[RegularExpression("^[A-Fa-f0-9]{64}$")]
|
||||
public string? ChecksumSha256 { get; set; }
|
||||
|
||||
@@ -112,34 +193,118 @@ public sealed class AssetUploadConfirmDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增或更新内容资产请求。
|
||||
/// </summary>
|
||||
public sealed class UpsertAssetDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 资产 ID。
|
||||
/// </summary>
|
||||
public Guid? AssetId { get; set; }
|
||||
/// <summary>
|
||||
/// 地区 ID。
|
||||
/// </summary>
|
||||
public Guid? RegionId { get; set; }
|
||||
/// <summary>
|
||||
/// 科目 ID。
|
||||
/// </summary>
|
||||
public Guid? SubjectId { get; set; }
|
||||
/// <summary>
|
||||
/// 分类 ID。
|
||||
/// </summary>
|
||||
public Guid? CategoryId { get; set; }
|
||||
/// <summary>
|
||||
/// 内容节点 ID。
|
||||
/// </summary>
|
||||
public Guid? ContentNodeId { get; set; }
|
||||
/// <summary>
|
||||
/// 历史系统 ID。
|
||||
/// </summary>
|
||||
public string? LegacyId { get; set; }
|
||||
/// <summary>
|
||||
/// 资产键。
|
||||
/// </summary>
|
||||
public string? AssetKey { get; set; }
|
||||
/// <summary>
|
||||
/// 标题。
|
||||
/// </summary>
|
||||
public string? Title { get; set; }
|
||||
/// <summary>
|
||||
/// 分类。
|
||||
/// </summary>
|
||||
public string? Category { get; set; }
|
||||
/// <summary>
|
||||
/// 说明。
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
/// <summary>
|
||||
/// 文件名。
|
||||
/// </summary>
|
||||
public string? FileName { get; set; }
|
||||
/// <summary>
|
||||
/// CDN 地址。
|
||||
/// </summary>
|
||||
public string? CdnUrl { get; set; }
|
||||
/// <summary>
|
||||
/// 是否公开。
|
||||
/// </summary>
|
||||
public bool? IsPublic { get; set; }
|
||||
/// <summary>
|
||||
/// 资产类型。
|
||||
/// </summary>
|
||||
public string? AssetType { get; set; }
|
||||
/// <summary>
|
||||
/// 可见性。
|
||||
/// </summary>
|
||||
public string? Visibility { get; set; }
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public string? Status { get; set; }
|
||||
/// <summary>
|
||||
/// 服务提供方。
|
||||
/// </summary>
|
||||
public string? Provider { get; set; }
|
||||
/// <summary>
|
||||
/// 存储桶。
|
||||
/// </summary>
|
||||
public string? Bucket { get; set; }
|
||||
/// <summary>
|
||||
/// 对象存储键。
|
||||
/// </summary>
|
||||
public string? ObjectKey { get; set; }
|
||||
/// <summary>
|
||||
/// MIME 类型。
|
||||
/// </summary>
|
||||
public string? MimeType { get; set; }
|
||||
/// <summary>
|
||||
/// 文件大小,单位为字节。
|
||||
/// </summary>
|
||||
public long? FileSizeBytes { get; set; }
|
||||
/// <summary>
|
||||
/// SHA-256 校验值。
|
||||
/// </summary>
|
||||
public string? ChecksumSha256 { get; set; }
|
||||
/// <summary>
|
||||
/// 预览地址。
|
||||
/// </summary>
|
||||
public string? PreviewUrl { get; set; }
|
||||
/// <summary>
|
||||
/// 预览对象存储键。
|
||||
/// </summary>
|
||||
public string? PreviewObjectKey { 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 UpsertAssetCommand ToCommand()
|
||||
@@ -175,11 +340,20 @@ public sealed class UpsertAssetDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建资产访问签名请求。
|
||||
/// </summary>
|
||||
public sealed class AssetAccessSignDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 资产 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid AssetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 有效期秒数。
|
||||
/// </summary>
|
||||
[Range(60, 3600)]
|
||||
public int? ExpiresInSeconds { get; set; }
|
||||
|
||||
@@ -189,31 +363,64 @@ public sealed class AssetAccessSignDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 资产管理查询参数。
|
||||
/// </summary>
|
||||
public sealed class AssetManagementQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 地区 ID。
|
||||
/// </summary>
|
||||
public Guid? RegionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 科目 ID。
|
||||
/// </summary>
|
||||
public Guid? SubjectId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类 ID。
|
||||
/// </summary>
|
||||
public Guid? CategoryId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 内容节点 ID。
|
||||
/// </summary>
|
||||
public Guid? ContentNodeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 资产类型。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? AssetType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上传状态。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? UploadStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 安全扫描状态。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? SecurityScanStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关键字。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Keyword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 500)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
@@ -233,11 +440,23 @@ public sealed class AssetManagementQueryDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 资产事件查询参数。
|
||||
/// </summary>
|
||||
public sealed class AssetEventQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 资产 ID。
|
||||
/// </summary>
|
||||
public Guid? AssetId { get; set; }
|
||||
/// <summary>
|
||||
/// 用户 ID。
|
||||
/// </summary>
|
||||
public Guid? UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 500)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
@@ -247,17 +466,32 @@ public sealed class AssetEventQueryDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导入任务查询参数。
|
||||
/// </summary>
|
||||
public sealed class ImportJobQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导入Type。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? ImportType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源格式。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? SourceFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 500)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
|
||||
@@ -6,32 +6,38 @@ using Tiku.Domain.Tenancy;
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 手机号密码登录请求。
|
||||
/// PasswordLogin请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class PasswordLoginDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 认证域。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public AuthRealm? Realm { get; set; }
|
||||
/// <summary>
|
||||
/// 平台控制域名登录时使用的租户代码;自定义域名登录可省略。
|
||||
/// 租户编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
[Description("平台控制域名登录时使用的租户代码;自定义域名登录可省略。")]
|
||||
public string? TenantCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 账号标识。tenant 可使用手机号,platform 可使用邮箱或用户名。
|
||||
/// 账号标识。
|
||||
/// </summary>
|
||||
[StringLength(320)]
|
||||
[Description("账号标识。tenant 可使用手机号,platform 可使用邮箱或用户名。")]
|
||||
public string? Identifier { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 兼容手机号字段;新客户端应使用 identifier。
|
||||
/// </summary>
|
||||
[StringLength(32)]
|
||||
[Description("兼容手机号字段;新客户端应使用 identifier。")]
|
||||
public string? Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户密码。
|
||||
/// 密码。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(128, MinimumLength = 8)]
|
||||
@@ -40,21 +46,24 @@ public sealed class PasswordLoginDto
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 短信验证码登录请求。
|
||||
/// SmsLogin请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class SmsLoginDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 认证域。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public AuthRealm? Realm { get; set; }
|
||||
/// <summary>
|
||||
/// 平台控制域名登录时使用的租户代码;自定义域名登录可省略。
|
||||
/// 租户编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
[Description("平台控制域名登录时使用的租户代码;自定义域名登录可省略。")]
|
||||
public string? TenantCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 中国大陆手机号。
|
||||
/// 手机号。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(32)]
|
||||
@@ -62,7 +71,7 @@ public sealed class SmsLoginDto
|
||||
public string Phone { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 收到的短信验证码。
|
||||
/// 编码。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(12, MinimumLength = 4)]
|
||||
@@ -70,38 +79,56 @@ public sealed class SmsLoginDto
|
||||
public string Code { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送短信验证码请求。
|
||||
/// </summary>
|
||||
public sealed class SendSmsCodeDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 认证域。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public AuthRealm? Realm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 租户编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? TenantCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 手机号。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(32)]
|
||||
public string Phone { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 设备 ID。
|
||||
/// </summary>
|
||||
[StringLength(256)]
|
||||
public string? DeviceId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OAuth code 登录请求。
|
||||
/// O认证编码请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class OAuthCodeDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 认证域。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public AuthRealm? Realm { get; set; }
|
||||
/// <summary>
|
||||
/// 平台控制域名登录时使用的租户代码;自定义域名登录可省略。
|
||||
/// 租户编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
[Description("平台控制域名登录时使用的租户代码;自定义域名登录可省略。")]
|
||||
public string? TenantCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OAuth 平台返回的一次性授权 code。
|
||||
/// 编码。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(512)]
|
||||
@@ -109,13 +136,13 @@ public sealed class OAuthCodeDto
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 客户端可提供的公开用户资料,不允许包含 token/secret。当前后端先保留模板字段,后续按业务需要逐步使用。
|
||||
/// 公开用户资料。
|
||||
/// </summary>
|
||||
[Description("客户端可提供的公开用户资料,不允许包含 token/secret。当前后端先保留模板字段,后续按业务需要逐步使用。")]
|
||||
public Dictionary<string, object?>? Profile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 微信用户资料语言,例如 zh_CN。当前微信小程序登录不会使用该字段。
|
||||
/// 语言。
|
||||
/// </summary>
|
||||
[StringLength(20)]
|
||||
[Description("微信用户资料语言,例如 zh_CN。当前微信小程序登录不会使用该字段。")]
|
||||
@@ -123,12 +150,12 @@ public sealed class OAuthCodeDto
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// refresh token 请求。
|
||||
/// 刷新会话请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class RefreshSessionDto
|
||||
{
|
||||
/// <summary>
|
||||
/// refresh token。服务端只存储哈希,明文只返回给客户端一次。
|
||||
/// 刷新令牌。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(2048)]
|
||||
@@ -137,7 +164,7 @@ public sealed class RefreshSessionDto
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登录成功后的用户、租户成员和令牌信息。
|
||||
/// Authenticated用户请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class AuthenticatedUserDto
|
||||
{
|
||||
@@ -157,19 +184,22 @@ public sealed class AuthenticatedUserDto
|
||||
public string? Email { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户显示名称。
|
||||
/// 名称。
|
||||
/// </summary>
|
||||
public string? Name { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 认证域。
|
||||
/// </summary>
|
||||
public AuthRealm Realm { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前登录租户成员摘要。
|
||||
/// 租户成员摘要。
|
||||
/// </summary>
|
||||
public TenantMembershipSummary? Tenant { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// access token 和 refresh token。
|
||||
/// 访问令牌和刷新令牌。
|
||||
/// </summary>
|
||||
public AuthTokenPair Tokens { get; init; } = default!;
|
||||
|
||||
@@ -188,11 +218,26 @@ public sealed class AuthenticatedUserDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登录认证结果。
|
||||
/// </summary>
|
||||
public sealed class AuthenticationResultDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public AuthenticationStatus Status { get; init; }
|
||||
/// <summary>
|
||||
/// 用户信息。
|
||||
/// </summary>
|
||||
public AuthenticatedUserDto? User { get; init; }
|
||||
/// <summary>
|
||||
/// 挑战令牌。
|
||||
/// </summary>
|
||||
public string? ChallengeToken { get; init; }
|
||||
/// <summary>
|
||||
/// 挑战令牌过期时间。
|
||||
/// </summary>
|
||||
public DateTimeOffset? ChallengeExpiresAt { get; init; }
|
||||
|
||||
public static AuthenticationResultDto FromApplication(AuthenticationResult result) => new()
|
||||
@@ -204,12 +249,21 @@ public sealed class AuthenticationResultDto
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 首次登录必改密码请求。
|
||||
/// </summary>
|
||||
public sealed class RequiredPasswordChangeDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 挑战令牌。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(2048)]
|
||||
public string ChallengeToken { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 新密码。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(128, MinimumLength = 8)]
|
||||
public string NewPassword { get; set; } = string.Empty;
|
||||
|
||||
@@ -3,11 +3,26 @@ using Tiku.Application.Jobs;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 创建租户后台任务请求。
|
||||
/// </summary>
|
||||
public sealed class CreateBackgroundJobDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 任务类型。
|
||||
/// </summary>
|
||||
public string JobType { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// 任务载荷。
|
||||
/// </summary>
|
||||
public JsonElement Payload { get; set; }
|
||||
/// <summary>
|
||||
/// 计划运行时间。
|
||||
/// </summary>
|
||||
public DateTimeOffset? RunAfter { get; set; }
|
||||
/// <summary>
|
||||
/// 最大重试次数。
|
||||
/// </summary>
|
||||
public int MaxRetries { get; set; } = 3;
|
||||
|
||||
public CreateBackgroundJobCommand ToCommand(Guid tenantId)
|
||||
|
||||
@@ -4,13 +4,34 @@ using Tiku.Domain.Operations;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 创建或更新后台角色请求。
|
||||
/// </summary>
|
||||
public sealed class UpsertBackofficeRoleDto
|
||||
{
|
||||
/// <summary>
|
||||
/// ID。
|
||||
/// </summary>
|
||||
public Guid? Id { get; set; }
|
||||
/// <summary>
|
||||
/// 编码。
|
||||
/// </summary>
|
||||
public string Code { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// 名称。
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public BackendRoleStatus Status { get; set; } = BackendRoleStatus.Active;
|
||||
/// <summary>
|
||||
/// 说明。
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
/// <summary>
|
||||
/// 数据范围配置。
|
||||
/// </summary>
|
||||
public JsonElement? DataScope { get; set; }
|
||||
|
||||
public UpsertBackofficeRoleCommand ToCommand()
|
||||
@@ -19,9 +40,18 @@ public sealed class UpsertBackofficeRoleDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 替换角色权限绑定请求。
|
||||
/// </summary>
|
||||
public sealed class ReplaceRoleBindingsDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 权限编码列表。
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<string> PermissionCodes { get; set; } = [];
|
||||
/// <summary>
|
||||
/// 菜单编码列表。
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<string> MenuCodes { get; set; } = [];
|
||||
|
||||
public ReplaceRoleBindingsCommand ToCommand(Guid roleId)
|
||||
@@ -30,8 +60,14 @@ public sealed class ReplaceRoleBindingsDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 替换用户角色请求。
|
||||
/// </summary>
|
||||
public sealed class ReplaceUserRolesDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色 ID 列表。
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<Guid> RoleIds { get; set; } = [];
|
||||
|
||||
public ReplaceUserRolesCommand ToCommand(Guid userId)
|
||||
|
||||
@@ -3,10 +3,13 @@ using Tiku.Application.Catalog;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 目录查询参数。
|
||||
/// </summary>
|
||||
public sealed class CatalogQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 租户编码。未登录公开查询时使用;已登录时优先使用当前 token 的租户。
|
||||
/// 租户编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? TenantCode { get; set; }
|
||||
@@ -17,7 +20,7 @@ public sealed class CatalogQueryDto
|
||||
public Guid? RegionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 功能模块 ID。
|
||||
/// ModuleId。
|
||||
/// </summary>
|
||||
public Guid? ModuleId { get; set; }
|
||||
|
||||
@@ -44,24 +47,24 @@ public sealed class CatalogQueryDto
|
||||
public Guid? SubjectId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导航节点 ID。
|
||||
/// 节点 ID。
|
||||
/// </summary>
|
||||
public Guid? NodeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称关键词。
|
||||
/// 关键字。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Keyword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型过滤,例如 cultural、professional、chapter、paper。
|
||||
/// 类型。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回条数上限。
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 2000)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
@@ -3,25 +3,49 @@ using Tiku.Application.Commerce;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 创建交易订单请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class CreateCommerceOrderDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 套餐 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid PlanId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数量。
|
||||
/// </summary>
|
||||
[Range(1, 99)]
|
||||
public int Quantity { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 支付方式。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? PayMethod { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付渠道。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? PayProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地区 ID。
|
||||
/// </summary>
|
||||
public Guid? RegionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 优惠券码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? CouponCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 优惠券领取记录 ID。
|
||||
/// </summary>
|
||||
public Guid? CouponRedemptionId { get; set; }
|
||||
|
||||
public CreateCommerceOrderCommand ToCommand()
|
||||
@@ -37,35 +61,65 @@ public sealed class CreateCommerceOrderDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 交易订单查询参数。
|
||||
/// </summary>
|
||||
public sealed class CommerceOrderQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 100)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(32)]
|
||||
public string? Status { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建交易支付请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class CreateCommercePaymentDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 订单号。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string OrderNo { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 服务提供方。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Provider { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 方式。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Method { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 微信或支付渠道 openid。
|
||||
/// </summary>
|
||||
[StringLength(255)]
|
||||
public string? OpenId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付完成返回地址。
|
||||
/// </summary>
|
||||
[StringLength(2048)]
|
||||
public string? ReturnUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付取消返回地址。
|
||||
/// </summary>
|
||||
[StringLength(2048)]
|
||||
public string? QuitUrl { get; set; }
|
||||
|
||||
@@ -81,11 +135,20 @@ public sealed class CreateCommercePaymentDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 交易优惠券查询参数。
|
||||
/// </summary>
|
||||
public sealed class CommerceCouponQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 100)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(32)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
@@ -95,8 +158,14 @@ public sealed class CommerceCouponQueryDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 领取交易优惠券请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class ClaimCommerceCouponDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 优惠券码。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string CouponCode { get; set; } = string.Empty;
|
||||
@@ -107,19 +176,37 @@ public sealed class ClaimCommerceCouponDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验交易优惠券请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class CheckCommerceCouponDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 优惠券码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? CouponCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 优惠券领取记录 ID。
|
||||
/// </summary>
|
||||
public Guid? CouponRedemptionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 套餐 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid PlanId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数量。
|
||||
/// </summary>
|
||||
[Range(1, 99)]
|
||||
public int Quantity { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 地区 ID。
|
||||
/// </summary>
|
||||
public Guid? RegionId { get; set; }
|
||||
|
||||
public CheckCommerceCouponCommand ToCommand()
|
||||
|
||||
@@ -5,132 +5,294 @@ using Tiku.Application.Growth;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 保存佣金配置请求。
|
||||
/// </summary>
|
||||
public sealed class UpdateCommissionSettingsDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认佣金比例。
|
||||
/// </summary>
|
||||
[Range(0, 1)]
|
||||
public decimal? DefaultRate { get; set; }
|
||||
/// <summary>
|
||||
/// 最低结算金额,单位为分。
|
||||
/// </summary>
|
||||
[Range(0, int.MaxValue)]
|
||||
public int? MinSettlementCents { get; set; }
|
||||
/// <summary>
|
||||
/// 结算周期。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? SettlementCycle { get; set; }
|
||||
/// <summary>
|
||||
/// 配置内容。
|
||||
/// </summary>
|
||||
public JsonElement? Config { get; set; }
|
||||
public UpdateCommissionSettingsCommand ToCommand() => new(DefaultRate, MinSettlementCents, SettlementCycle, Config);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 调整成员佣金比例请求。
|
||||
/// </summary>
|
||||
public sealed class UpdateMemberCommissionRateDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid UserId { get; set; }
|
||||
/// <summary>
|
||||
/// 成员佣金比例。
|
||||
/// </summary>
|
||||
[Range(0, 1)]
|
||||
public decimal? CommissionRate { get; set; }
|
||||
/// <summary>
|
||||
/// 佣金扩展配置。
|
||||
/// </summary>
|
||||
public JsonElement? CommissionConfig { get; set; }
|
||||
public UpdateMemberCommissionRateCommand ToCommand() => new(UserId, CommissionRate, CommissionConfig);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 佣金统计周期查询参数。
|
||||
/// </summary>
|
||||
public class CommissionPeriodQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 开始日期,格式为 yyyy-MM-dd。
|
||||
/// </summary>
|
||||
[RegularExpression("^\\d{4}-\\d{2}-\\d{2}$")]
|
||||
public string? StartDate { get; set; }
|
||||
/// <summary>
|
||||
/// 结束日期,格式为 yyyy-MM-dd。
|
||||
/// </summary>
|
||||
[RegularExpression("^\\d{4}-\\d{2}-\\d{2}$")]
|
||||
public string? EndDate { get; set; }
|
||||
/// <summary>
|
||||
/// 推荐人用户 ID。
|
||||
/// </summary>
|
||||
public Guid? ReferrerUserId { get; set; }
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 500)]
|
||||
public int? Limit { get; set; }
|
||||
public CommissionPeriodQuery ToQuery() => new(ParseDate(StartDate), ParseDate(EndDate), ReferrerUserId, Limit);
|
||||
protected static DateOnly? ParseDate(string? value) => string.IsNullOrWhiteSpace(value) ? null : DateOnly.ParseExact(value, "yyyy-MM-dd", CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 佣金结算单查询参数。
|
||||
/// </summary>
|
||||
public sealed class CommissionSettlementsQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Status { get; set; }
|
||||
/// <summary>
|
||||
/// 推荐人用户 ID。
|
||||
/// </summary>
|
||||
public Guid? ReferrerUserId { get; set; }
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 500)]
|
||||
public int? Limit { get; set; }
|
||||
public CommissionSettlementQuery ToQuery() => new(Status, ReferrerUserId, Limit);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成佣金结算单请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class GenerateCommissionSettlementDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 开始日期,格式为 yyyy-MM-dd。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[RegularExpression("^\\d{4}-\\d{2}-\\d{2}$")]
|
||||
public string StartDate { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// 结束日期,格式为 yyyy-MM-dd。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[RegularExpression("^\\d{4}-\\d{2}-\\d{2}$")]
|
||||
public string EndDate { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// 推荐人用户 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid ReferrerUserId { get; set; }
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Status { get; set; }
|
||||
/// <summary>
|
||||
/// 备注。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Remark { get; set; }
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement? Metadata { get; set; }
|
||||
public GenerateCommissionSettlementCommand ToCommand() => new(Parse(StartDate), Parse(EndDate), ReferrerUserId, Status, Remark, Metadata);
|
||||
private static DateOnly Parse(string value) => DateOnly.ParseExact(value, "yyyy-MM-dd", CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新佣金结算单状态请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpdateCommissionSettlementStatusDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 结算单 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid SettlementId { get; set; }
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Status { get; set; }
|
||||
/// <summary>
|
||||
/// 审核备注。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? ReviewNote { get; set; }
|
||||
/// <summary>
|
||||
/// 支付方式。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? PaymentMethod { get; set; }
|
||||
/// <summary>
|
||||
/// 收款账号。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? PaymentAccount { get; set; }
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement? Metadata { get; set; }
|
||||
public UpdateCommissionSettlementStatusCommand ToCommand() => new(SettlementId, Status, ReviewNote, PaymentMethod, PaymentAccount, Metadata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 佣金结算单导出查询参数。
|
||||
/// </summary>
|
||||
public sealed class CommissionSettlementExportQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 结算单 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid SettlementId { get; set; }
|
||||
/// <summary>
|
||||
/// 导出格式。
|
||||
/// </summary>
|
||||
[StringLength(10)]
|
||||
public string? Format { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 佣金结算单凭证查询参数。
|
||||
/// </summary>
|
||||
public sealed class CommissionSettlementProofQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 结算单 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid SettlementId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建佣金结算凭证请求。
|
||||
/// </summary>
|
||||
public sealed class CreateCommissionProofDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 结算单 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid SettlementId { get; set; }
|
||||
/// <summary>
|
||||
/// 凭证类型。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? ProofType { get; set; }
|
||||
/// <summary>
|
||||
/// 标题。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? Title { get; set; }
|
||||
/// <summary>
|
||||
/// 说明。
|
||||
/// </summary>
|
||||
[StringLength(2000)]
|
||||
public string? Description { get; set; }
|
||||
/// <summary>
|
||||
/// 资产 ID。
|
||||
/// </summary>
|
||||
public Guid? AssetId { get; set; }
|
||||
/// <summary>
|
||||
/// 外部链接。
|
||||
/// </summary>
|
||||
[StringLength(2048)]
|
||||
public string? ExternalUrl { get; set; }
|
||||
/// <summary>
|
||||
/// 金额,单位为分。
|
||||
/// </summary>
|
||||
[Range(0, int.MaxValue)]
|
||||
public int? AmountCents { get; set; }
|
||||
/// <summary>
|
||||
/// 支付方式。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? PaymentMethod { get; set; }
|
||||
/// <summary>
|
||||
/// 收款账号。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? PaymentAccount { get; set; }
|
||||
/// <summary>
|
||||
/// 支付时间。
|
||||
/// </summary>
|
||||
public DateTimeOffset? PaidAt { get; set; }
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement? Metadata { get; set; }
|
||||
public CreateCommissionProofCommand ToCommand() => new(SettlementId, ProofType, Title, Description, AssetId, ExternalUrl, AmountCents, PaymentMethod, PaymentAccount, PaidAt, Metadata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新佣金结算凭证状态请求。
|
||||
/// </summary>
|
||||
public sealed class UpdateCommissionProofStatusDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 凭证 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid ProofId { get; set; }
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Status { get; set; }
|
||||
/// <summary>
|
||||
/// 审核备注。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? ReviewNote { get; set; }
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement? Metadata { get; set; }
|
||||
public UpdateCommissionProofStatusCommand ToCommand() => new(ProofId, Status, ReviewNote, Metadata);
|
||||
}
|
||||
|
||||
@@ -7,37 +7,76 @@ 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; }
|
||||
|
||||
@@ -59,43 +98,88 @@ public sealed class ContentManagementQueryDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <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()
|
||||
@@ -118,45 +202,96 @@ public sealed class UpsertContentEntryDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <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()
|
||||
@@ -181,48 +316,105 @@ public sealed class UpsertContentNodeDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <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()
|
||||
@@ -249,23 +441,47 @@ public sealed class UpsertQuestionCollectionDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <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()
|
||||
@@ -280,11 +496,20 @@ public sealed class CollectionQuestionDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <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()
|
||||
@@ -295,48 +520,105 @@ public sealed class ReplaceCollectionItemsDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <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()
|
||||
@@ -363,12 +645,21 @@ public sealed class UpsertPracticeBlueprintDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <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; }
|
||||
}
|
||||
|
||||
@@ -3,42 +3,87 @@ using Tiku.Application.Content;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 内容Navigation查询参数。
|
||||
/// </summary>
|
||||
public sealed class ContentNavigationQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 租户编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? TenantCode { 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;传 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 IncludeHidden { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否包含停用数据。
|
||||
/// </summary>
|
||||
public bool IncludeInactive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 1000)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
|
||||
@@ -4,35 +4,71 @@ using Tiku.Application.Growth;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 新增或更新CRM配置请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpsertCrmConfigDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否启用。
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 访问地址。
|
||||
/// </summary>
|
||||
[StringLength(2048)]
|
||||
public string? Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密钥引用。
|
||||
/// </summary>
|
||||
[StringLength(300)]
|
||||
public string? SecretRef { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密钥内容。
|
||||
/// </summary>
|
||||
public string? Secret { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 表单名称。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? FormName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 考试类型。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? ExamType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 超时时长,单位为秒。
|
||||
/// </summary>
|
||||
[Range(1, 120)]
|
||||
public int? TimeoutSeconds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 延迟秒数。
|
||||
/// </summary>
|
||||
[Range(0, 86400)]
|
||||
public int? DelaySeconds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分配模式。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? AssignmentMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分配池。
|
||||
/// </summary>
|
||||
public JsonElement? AssignmentPool { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分配配置。
|
||||
/// </summary>
|
||||
public JsonElement? AssignmentConfig { get; set; }
|
||||
|
||||
public UpsertCrmConfigCommand ToCommand()
|
||||
@@ -52,16 +88,31 @@ public sealed class UpsertCrmConfigDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CRM队列查询参数。
|
||||
/// </summary>
|
||||
public sealed class CrmQueueQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 队列任务 ID。
|
||||
/// </summary>
|
||||
public Guid? QueueId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 500)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
@@ -71,10 +122,19 @@ public sealed class CrmQueueQueryDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CRM队列日志查询参数。
|
||||
/// </summary>
|
||||
public sealed class CrmQueueLogQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 队列任务 ID。
|
||||
/// </summary>
|
||||
public Guid? QueueId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 200)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
@@ -84,17 +144,32 @@ public sealed class CrmQueueLogQueryDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CRM队列Action请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class CrmQueueActionDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 队列任务 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid QueueId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Action { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注。
|
||||
/// </summary>
|
||||
[StringLength(500)]
|
||||
public string? Note { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement? Metadata { get; set; }
|
||||
|
||||
public CrmQueueActionCommand ToCommand()
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@ namespace Tiku.Api.Contracts;
|
||||
/// <param name="Status">服务状态,例如 ok。</param>
|
||||
/// <param name="Service">服务名称。</param>
|
||||
/// <param name="CheckedAt">检查时间。</param>
|
||||
/// <summary>
|
||||
/// 健康检查Response请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record HealthResponseDto(
|
||||
string Status,
|
||||
string Service,
|
||||
|
||||
@@ -7,14 +7,26 @@ using Tiku.Domain.Content;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 学习Limit查询参数。
|
||||
/// </summary>
|
||||
public sealed class LearningLimitQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 500)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 单元 ID。
|
||||
/// </summary>
|
||||
public Guid? UnitId { get; set; }
|
||||
|
||||
public LearningLimitFilter ToFilter()
|
||||
@@ -23,18 +35,36 @@ public sealed class LearningLimitQueryDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 练习会话查询参数。
|
||||
/// </summary>
|
||||
public sealed class PracticeSessionQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 练习会话 ID。
|
||||
/// </summary>
|
||||
public Guid? PracticeSessionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 练习蓝图 ID。
|
||||
/// </summary>
|
||||
public Guid? BlueprintId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模式。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Mode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 200)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
@@ -49,33 +79,69 @@ public sealed class PracticeSessionQueryDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建练习会话请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class CreatePracticeSessionDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 模式。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Mode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标类型。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? TargetType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标 ID。
|
||||
/// </summary>
|
||||
public Guid? TargetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 练习蓝图 ID。
|
||||
/// </summary>
|
||||
public Guid? BlueprintId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 题集 ID。
|
||||
/// </summary>
|
||||
public Guid? CollectionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 内容入口 ID。
|
||||
/// </summary>
|
||||
public Guid? EntryId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 内容节点 ID。
|
||||
/// </summary>
|
||||
public Guid? ContentNodeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 题目数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 500)]
|
||||
public int? QuestionLimit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时长,单位为分钟。
|
||||
/// </summary>
|
||||
[Range(1, 1440)]
|
||||
public int? DurationMinutes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 总分。
|
||||
/// </summary>
|
||||
[Range(typeof(decimal), "0", "99999")]
|
||||
public decimal? TotalScore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
|
||||
public PracticeSessionCommand ToCommand()
|
||||
@@ -95,8 +161,14 @@ public sealed class CreatePracticeSessionDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提交练习会话请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class SubmitPracticeSessionDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 练习会话 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid PracticeSessionId { get; set; }
|
||||
|
||||
@@ -106,16 +178,31 @@ public sealed class SubmitPracticeSessionDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提交答案请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class SubmitAnswerDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 会话题目 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid SessionQuestionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 已选选项。
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<string>? SelectedOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文字答案。
|
||||
/// </summary>
|
||||
[StringLength(10000)]
|
||||
public string? AnswerText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主观题自评是否正确。
|
||||
/// </summary>
|
||||
public bool? SelfJudgedCorrect { get; set; }
|
||||
|
||||
public SubmitAnswerCommand ToCommand()
|
||||
@@ -128,14 +215,26 @@ public sealed class SubmitAnswerDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 题目Action请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class QuestionActionDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 题目 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid QuestionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public QuestionSource Source { get; set; } = QuestionSource.Tenant;
|
||||
|
||||
/// <summary>
|
||||
/// 是否收藏。
|
||||
/// </summary>
|
||||
public bool? Favorite { get; set; }
|
||||
|
||||
public QuestionActionCommand ToCommand()
|
||||
@@ -144,20 +243,38 @@ public sealed class QuestionActionDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单词Progress请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class WordProgressDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 单词 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid WordId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 答对数量变化。
|
||||
/// </summary>
|
||||
[Range(0, 100)]
|
||||
public int? CorrectDelta { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 答错数量变化。
|
||||
/// </summary>
|
||||
[Range(0, 100)]
|
||||
public int? WrongDelta { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 下次复习时间。
|
||||
/// </summary>
|
||||
public DateTimeOffset? NextReviewAt { get; set; }
|
||||
|
||||
public WordProgressCommand ToCommand()
|
||||
@@ -171,13 +288,25 @@ public sealed class WordProgressDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 收藏单词请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class FavoriteWordDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 单词 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid WordId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否收藏。
|
||||
/// </summary>
|
||||
public bool? Favorite { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Note { get; set; }
|
||||
|
||||
@@ -187,14 +316,26 @@ public sealed class FavoriteWordDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单词Review请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class WordReviewDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 单词 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid WordId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结果。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Result { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 下次复习时间。
|
||||
/// </summary>
|
||||
public DateTimeOffset? NextReviewAt { get; set; }
|
||||
|
||||
public WordReviewCommand ToCommand()
|
||||
|
||||
@@ -9,88 +9,201 @@ using Tiku.Domain.Tenancy;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 平台管理端查询参数。
|
||||
/// </summary>
|
||||
public sealed class PlatformAdminQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(32)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 搜索关键字。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? Search { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 200)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
public PlatformAdminQuery ToQuery() => new(Status, Search, Limit);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建平台租户请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class CreatePlatformTenantDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 短编码。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Slug { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 名称。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(200)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 法定名称。
|
||||
/// </summary>
|
||||
[StringLength(300)]
|
||||
public string? LegalName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public TenantStatus Status { get; set; } = TenantStatus.Active;
|
||||
/// <summary>
|
||||
/// 账务状态。
|
||||
/// </summary>
|
||||
public BillingStatus BillingStatus { get; set; } = BillingStatus.Trial;
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
|
||||
public CreatePlatformTenantCommand ToCommand() => new(Slug, Name, LegalName, Status, BillingStatus, Metadata);
|
||||
/// <summary>
|
||||
/// 租户负责人邮箱。
|
||||
/// </summary>
|
||||
[EmailAddress, StringLength(320)]
|
||||
public string? OwnerEmail { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 租户负责人手机号。
|
||||
/// </summary>
|
||||
[Phone, StringLength(32)]
|
||||
public string? OwnerPhone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 租户负责人姓名。
|
||||
/// </summary>
|
||||
[Required, StringLength(100)]
|
||||
public string OwnerName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 临时密码。
|
||||
/// </summary>
|
||||
[Required, StringLength(200, MinimumLength = 12)]
|
||||
public string TemporaryPassword { get; set; } = string.Empty;
|
||||
|
||||
public CreatePlatformTenantCommand ToCommand() => new(
|
||||
Slug, Name, LegalName, Status, BillingStatus, Metadata,
|
||||
OwnerEmail, OwnerPhone, OwnerName, TemporaryPassword);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新平台租户状态请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpdatePlatformTenantStatusDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 租户 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid TenantId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public TenantStatus Status { get; set; } = TenantStatus.Active;
|
||||
/// <summary>
|
||||
/// 账务状态。
|
||||
/// </summary>
|
||||
public BillingStatus BillingStatus { get; set; } = BillingStatus.Active;
|
||||
|
||||
/// <summary>
|
||||
/// 原因。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Reason { get; set; }
|
||||
|
||||
public UpdatePlatformTenantStatusCommand ToCommand() => new(TenantId, Status, BillingStatus, Reason);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增或更新平台租户账务资料请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpsertPlatformTenantBillingProfileDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 租户 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid TenantId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 账务名称。
|
||||
/// </summary>
|
||||
[StringLength(300)]
|
||||
public string? BillingName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 税号。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? TaxId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系人姓名。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? ContactName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系人手机号。
|
||||
/// </summary>
|
||||
[StringLength(32)]
|
||||
public string? ContactPhone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系人邮箱。
|
||||
/// </summary>
|
||||
[StringLength(320)]
|
||||
public string? ContactEmail { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 账务地址。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? BillingAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发票抬头。
|
||||
/// </summary>
|
||||
[StringLength(300)]
|
||||
public string? InvoiceTitle { get; set; }
|
||||
|
||||
public TenantInvoiceTitleType? InvoiceType { get; set; }
|
||||
/// <summary>
|
||||
/// 发票类型。
|
||||
/// </summary>
|
||||
public TenantBillingInvoiceTitleType? InvoiceType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开户银行。
|
||||
/// </summary>
|
||||
[StringLength(300)]
|
||||
public string? BankName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 脱敏银行账号。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? BankAccountMasked { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
|
||||
public UpsertPlatformTenantBillingProfileCommand ToCommand() => new(
|
||||
@@ -108,143 +221,180 @@ public sealed class UpsertPlatformTenantBillingProfileDto
|
||||
Metadata);
|
||||
}
|
||||
|
||||
public sealed class UpsertPlatformSubscriptionDto
|
||||
{
|
||||
[Required]
|
||||
public Guid TenantId { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string PlanCode { get; set; } = string.Empty;
|
||||
|
||||
public TenantSubscriptionStatus Status { get; set; } = TenantSubscriptionStatus.Active;
|
||||
public DateTimeOffset? StartsAt { get; set; }
|
||||
public DateTimeOffset? ExpiresAt { get; set; }
|
||||
|
||||
[StringLength(32)]
|
||||
public string? BillingCycle { get; set; }
|
||||
|
||||
[Range(0, int.MaxValue)]
|
||||
public int AmountCents { get; set; }
|
||||
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
|
||||
public UpsertPlatformSubscriptionCommand ToCommand() => new(
|
||||
TenantId,
|
||||
PlanCode,
|
||||
Status,
|
||||
StartsAt,
|
||||
ExpiresAt,
|
||||
BillingCycle,
|
||||
AmountCents,
|
||||
Metadata);
|
||||
}
|
||||
|
||||
public sealed class ReplacePlatformPlanModulesDto
|
||||
{
|
||||
[Required]
|
||||
public IReadOnlyCollection<string> ModuleCodes { get; set; } = [];
|
||||
|
||||
public ReplacePlatformPlanModulesCommand ToCommand(string planCode) => new(planCode, ModuleCodes);
|
||||
}
|
||||
|
||||
public sealed class UpsertPlatformTenantModuleOverrideDto
|
||||
{
|
||||
public TenantModuleOverrideMode Mode { get; set; }
|
||||
public DateTimeOffset? ExpiresAt { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(1000, MinimumLength = 1)]
|
||||
public string Reason { get; set; } = string.Empty;
|
||||
|
||||
public UpsertPlatformTenantModuleOverrideCommand ToCommand(Guid tenantId, string moduleCode) =>
|
||||
new(tenantId, moduleCode, Mode, ExpiresAt, Reason);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增或更新平台Staff请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpsertPlatformStaffDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户 ID。
|
||||
/// </summary>
|
||||
public Guid? UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 邮箱。
|
||||
/// </summary>
|
||||
[StringLength(320)]
|
||||
public string? Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 手机号。
|
||||
/// </summary>
|
||||
[StringLength(32)]
|
||||
public string? Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public UserStatus Status { get; set; } = UserStatus.Active;
|
||||
/// <summary>
|
||||
/// 角色 ID 列表。
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<Guid> RoleIds { get; set; } = [];
|
||||
|
||||
public UpsertPlatformStaffCommand ToCommand() => new(UserId, Email, Phone, Name, Status, RoleIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新平台Staff状态请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpdatePlatformStaffStatusDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public UserStatus Status { get; set; } = UserStatus.Active;
|
||||
|
||||
/// <summary>
|
||||
/// 原因。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Reason { get; set; }
|
||||
|
||||
public UpdatePlatformStaffStatusCommand ToCommand() => new(UserId, Status, Reason);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新平台审计Alert状态请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpdatePlatformAuditAlertStatusDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 告警 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid AlertId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public PlatformAuditAlertStatus Status { get; set; } = PlatformAuditAlertStatus.Acknowledged;
|
||||
|
||||
/// <summary>
|
||||
/// 处理备注。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? ResolutionNote { get; set; }
|
||||
|
||||
public UpdatePlatformAuditAlertStatusCommand ToCommand() => new(AlertId, Status, ResolutionNote);
|
||||
}
|
||||
|
||||
public sealed class UpsertPlatformDunningChannelDto
|
||||
/// <summary>
|
||||
/// 新增或更新平台DunningChannel请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpsertPlatformBillingDunningChannelDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 通知渠道 ID。
|
||||
/// </summary>
|
||||
public Guid? ChannelId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 渠道编码。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string ChannelCode { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 名称。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(200)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 说明。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用。
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; } = true;
|
||||
public PlatformDunningProvider Provider { get; set; } = PlatformDunningProvider.Generic;
|
||||
/// <summary>
|
||||
/// 服务提供方。
|
||||
/// </summary>
|
||||
public PlatformBillingDunningProvider Provider { get; set; } = PlatformBillingDunningProvider.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Webhook 地址。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(2048)]
|
||||
public string WebhookUrl { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 密钥引用。
|
||||
/// </summary>
|
||||
[StringLength(300)]
|
||||
public string? SecretRef { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提醒类型列表。
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<string> ReminderTypes { get; set; } = ["overdue", "final_notice"];
|
||||
/// <summary>
|
||||
/// 提醒渠道列表。
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<string> ReminderChannels { get; set; } = ["internal"];
|
||||
|
||||
/// <summary>
|
||||
/// 最低提醒级别。
|
||||
/// </summary>
|
||||
[Range(1, 20)]
|
||||
public int MinReminderLevel { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 租户 ID 列表。
|
||||
/// </summary>
|
||||
public IReadOnlyCollection<Guid> TenantIds { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 超时时长,单位为秒。
|
||||
/// </summary>
|
||||
[Range(1, 60)]
|
||||
public int TimeoutSeconds { get; set; } = 10;
|
||||
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
|
||||
public UpsertPlatformDunningChannelCommand ToCommand() => new(
|
||||
public UpsertPlatformBillingDunningChannelCommand ToCommand() => new(
|
||||
ChannelId,
|
||||
ChannelCode,
|
||||
Name,
|
||||
@@ -261,24 +411,42 @@ public sealed class UpsertPlatformDunningChannelDto
|
||||
Metadata);
|
||||
}
|
||||
|
||||
public sealed class DisablePlatformDunningChannelDto
|
||||
/// <summary>
|
||||
/// 禁用平台DunningChannel请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class DisablePlatformBillingDunningChannelDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 通知渠道 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid ChannelId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 原因。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Reason { get; set; }
|
||||
|
||||
public DisablePlatformDunningChannelCommand ToCommand() => new(ChannelId, Reason);
|
||||
public DisablePlatformBillingDunningChannelCommand ToCommand() => new(ChannelId, Reason);
|
||||
}
|
||||
|
||||
public sealed class RetryPlatformDunningEventDto
|
||||
/// <summary>
|
||||
/// 重试平台Dunning事件请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class RetryPlatformBillingDunningEventDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 事件 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid EventId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 原因。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Reason { get; set; }
|
||||
|
||||
public RetryPlatformDunningEventCommand ToCommand() => new(EventId, Reason);
|
||||
public RetryPlatformBillingDunningEventCommand ToCommand() => new(EventId, Reason);
|
||||
}
|
||||
|
||||
@@ -3,14 +3,26 @@ using Tiku.Application.Points;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 积分查询参数。
|
||||
/// </summary>
|
||||
public sealed class PointQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 200)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(32)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地区 ID。
|
||||
/// </summary>
|
||||
public Guid? RegionId { get; set; }
|
||||
|
||||
public PointLimitQuery ToQuery()
|
||||
@@ -19,15 +31,27 @@ public sealed class PointQueryDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 领取积分任务请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class ClaimPointTaskDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 任务键。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string TaskKey { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 来源类型。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? SourceType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源 ID。
|
||||
/// </summary>
|
||||
public Guid? SourceId { get; set; }
|
||||
|
||||
public ClaimPointTaskCommand ToCommand()
|
||||
@@ -36,8 +60,14 @@ public sealed class ClaimPointTaskDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建积分兑换订单请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class CreatePointExchangeOrderDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 兑换项 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid ItemId { get; set; }
|
||||
|
||||
|
||||
@@ -4,47 +4,107 @@ using Tiku.Application.Profile;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 资料查询参数。
|
||||
/// </summary>
|
||||
public sealed class ProfileQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 最近记录数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 50)]
|
||||
public int? RecentLimit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 20)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(32)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否包含锁定资源。
|
||||
/// </summary>
|
||||
public bool IncludeLocked { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源类型。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? SourceType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始时间。
|
||||
/// </summary>
|
||||
public DateTimeOffset? From { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结束时间。
|
||||
/// </summary>
|
||||
public DateTimeOffset? To { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新资料请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpdateProfileDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 名称。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 头像预设。
|
||||
/// </summary>
|
||||
[StringLength(32)]
|
||||
public string? AvatarPreset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地区 ID。
|
||||
/// </summary>
|
||||
public Guid? RegionId { get; set; }
|
||||
/// <summary>
|
||||
/// 已选择院校 ID。
|
||||
/// </summary>
|
||||
public Guid? SelectedSchoolId { get; set; }
|
||||
/// <summary>
|
||||
/// 已选择专业 ID。
|
||||
/// </summary>
|
||||
public Guid? SelectedMajorId { get; set; }
|
||||
/// <summary>
|
||||
/// 统计数据。
|
||||
/// </summary>
|
||||
public JsonElement? Stats { get; set; }
|
||||
/// <summary>
|
||||
/// 进度数据。
|
||||
/// </summary>
|
||||
public JsonElement? Progress { get; set; }
|
||||
/// <summary>
|
||||
/// 模块选择数据。
|
||||
/// </summary>
|
||||
public JsonElement? ModuleSelections { get; set; }
|
||||
/// <summary>
|
||||
/// 最近活动数据。
|
||||
/// </summary>
|
||||
public JsonElement? RecentActivities { get; set; }
|
||||
|
||||
public UpdateProfileCommand ToCommand()
|
||||
@@ -62,13 +122,22 @@ public sealed class UpdateProfileDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通知状态请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class NotificationStatusDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 通知 ID 列表。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[MinLength(1)]
|
||||
[MaxLength(100)]
|
||||
public IReadOnlyCollection<Guid> NotificationIds { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(32)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
@@ -78,30 +147,60 @@ public sealed class NotificationStatusDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提交反馈请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class SubmitFeedbackDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 题目 ID。
|
||||
/// </summary>
|
||||
public Guid? QuestionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分类。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Category { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标题。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 说明。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(5000)]
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 优先级。
|
||||
/// </summary>
|
||||
[StringLength(32)]
|
||||
public string? Priority { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系方式。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? Contact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 附件列表。
|
||||
/// </summary>
|
||||
public JsonElement Attachments { get; set; } = JsonSerializer.SerializeToElement(Array.Empty<object>());
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement Metadata { get; set; } = JsonSerializer.SerializeToElement(new { });
|
||||
|
||||
public SubmitFeedbackCommand ToCommand()
|
||||
|
||||
@@ -4,40 +4,82 @@ using Tiku.Domain.Content;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 题目题库查询参数。
|
||||
/// </summary>
|
||||
public sealed class QuestionBankQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 租户编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? TenantCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地区 ID。
|
||||
/// </summary>
|
||||
public Guid? RegionId { 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? CollectionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源。
|
||||
/// </summary>
|
||||
public QuestionSource? Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关键字。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Keyword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 题目 ID 列表,支持逗号分隔;最多取前 300 个。
|
||||
/// 题目 ID 列表。
|
||||
/// </summary>
|
||||
public string? QuestionIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 500)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
|
||||
@@ -5,17 +5,32 @@ using Tiku.Application.Growth;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 推荐租户查询参数。
|
||||
/// </summary>
|
||||
public sealed class ReferralTenantQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 租户编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? TenantCode { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 推荐邀请码请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class ReferralInviteDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 渠道。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Channel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 落地页路径。
|
||||
/// </summary>
|
||||
[StringLength(2048)]
|
||||
public string? LandingPath { get; set; }
|
||||
|
||||
@@ -25,11 +40,20 @@ public sealed class ReferralInviteDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析推荐请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class ResolveReferralDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 租户编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? TenantCode { get; set; }
|
||||
|
||||
@@ -39,22 +63,43 @@ public sealed class ResolveReferralDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录推荐事件请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class TrackReferralEventDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 推荐码。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string RefCode { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 事件类型。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? EventType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标用户 ID。
|
||||
/// </summary>
|
||||
public Guid? TargetUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement? Metadata { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 租户编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? TenantCode { get; set; }
|
||||
|
||||
@@ -64,15 +109,27 @@ public sealed class TrackReferralEventDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定推荐请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class BindReferralDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 推荐码。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string RefCode { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 来源。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement? Metadata { get; set; }
|
||||
|
||||
public BindReferralCommand ToCommand()
|
||||
@@ -81,20 +138,38 @@ public sealed class BindReferralDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 推荐二维码请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class ReferralQrcodeDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 页码。
|
||||
/// </summary>
|
||||
[StringLength(500)]
|
||||
public string? Page { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 场景参数。
|
||||
/// </summary>
|
||||
[StringLength(128)]
|
||||
public string? Scene { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 服务提供方。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Provider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 二维码地址。
|
||||
/// </summary>
|
||||
[StringLength(2048)]
|
||||
public string? QrcodeUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement? Metadata { get; set; }
|
||||
|
||||
public ReferralQrcodeCommand ToCommand()
|
||||
@@ -103,10 +178,19 @@ public sealed class ReferralQrcodeDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 推荐统计查询参数。
|
||||
/// </summary>
|
||||
public sealed class ReferralStatsQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 推荐人用户 ID。
|
||||
/// </summary>
|
||||
public Guid? ReferrerUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 500)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
@@ -116,19 +200,37 @@ public sealed class ReferralStatsQueryDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 推荐Conversion查询参数。
|
||||
/// </summary>
|
||||
public sealed class ReferralConversionQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 推荐人用户 ID。
|
||||
/// </summary>
|
||||
public Guid? ReferrerUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始日期,格式为 yyyy-MM-dd。
|
||||
/// </summary>
|
||||
[RegularExpression("^\\d{4}-\\d{2}-\\d{2}$")]
|
||||
public string? StartDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结束日期,格式为 yyyy-MM-dd。
|
||||
/// </summary>
|
||||
[RegularExpression("^\\d{4}-\\d{2}-\\d{2}$")]
|
||||
public string? EndDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 天数。
|
||||
/// </summary>
|
||||
[Range(1, 365)]
|
||||
public int? Days { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 100)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
@@ -150,19 +252,37 @@ public sealed class ReferralConversionQueryDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 人工绑定推荐请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class ManualBindReferralDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 学生用户 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid StudentUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 推荐人用户 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid ReferrerUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否强制执行。
|
||||
/// </summary>
|
||||
public bool Force { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement? Metadata { get; set; }
|
||||
|
||||
public ManualBindReferralCommand ToCommand()
|
||||
@@ -171,8 +291,14 @@ public sealed class ManualBindReferralDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 推荐团队查询参数。
|
||||
/// </summary>
|
||||
public sealed class ReferralTeamQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 上级成员用户 ID。
|
||||
/// </summary>
|
||||
public Guid? LeaderUserId { get; set; }
|
||||
|
||||
public ReferralTeamQuery ToQuery()
|
||||
@@ -181,19 +307,37 @@ public sealed class ReferralTeamQueryDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增或更新推荐团队请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpsertReferralTeamDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 成员用户 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid MemberUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上级成员用户 ID。
|
||||
/// </summary>
|
||||
public Guid? LeaderUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关系类型。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? RelationType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement? Metadata { get; set; }
|
||||
|
||||
public UpsertReferralTeamCommand ToCommand()
|
||||
|
||||
151
Tiku.Api/Contracts/SaasBillingDtos.cs
Normal file
151
Tiku.Api/Contracts/SaasBillingDtos.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json;
|
||||
using Tiku.Application.PlatformBilling;
|
||||
using Tiku.Domain.Platform;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 新增或更新SaaS功能请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record UpsertSaasFeatureDto(
|
||||
Guid? Id,
|
||||
[Required, MaxLength(120)] string Code,
|
||||
[Required, MaxLength(200)] string Name,
|
||||
[Required, MaxLength(100)] string Category,
|
||||
[MaxLength(1000)] string? Description,
|
||||
[Range(0, int.MaxValue)] int ReferencePriceCents,
|
||||
[Required, MaxLength(10)] string Currency,
|
||||
SaasFeatureStatus Status,
|
||||
int SortOrder)
|
||||
{
|
||||
public UpsertSaasFeatureCommand ToCommand() => new(Id, Code, Name, Category, Description, ReferencePriceCents, Currency, Status, SortOrder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增或更新SaaS套餐请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record UpsertSaasOfferingDto(
|
||||
Guid? Id,
|
||||
[Required, MaxLength(120)] string Code,
|
||||
[Required, MaxLength(200)] string Name,
|
||||
SaasOfferingType Type,
|
||||
SaasOfferingStatus Status,
|
||||
[MaxLength(1000)] string? Description,
|
||||
int SortOrder)
|
||||
{
|
||||
public UpsertSaasOfferingCommand ToCommand() => new(Id, Code, Name, Type, Status, Description, SortOrder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增或更新 SaaS 功能额度定义。
|
||||
/// </summary>
|
||||
public sealed record UpsertSaasFeatureLimitDto(
|
||||
Guid? Id,
|
||||
[Required, MaxLength(120)] string MetricCode,
|
||||
[Required, MaxLength(120)] string FeatureCode,
|
||||
[Required, MaxLength(200)] string Name,
|
||||
[Required, MaxLength(50)] string Unit,
|
||||
SaasFeatureLimitKind Kind,
|
||||
[Range(1, 100)] int WarningPercent,
|
||||
bool IsHardLimit)
|
||||
{
|
||||
public UpsertSaasFeatureLimitCommand ToCommand() => new(
|
||||
Id, MetricCode, FeatureCode, Name, Unit, Kind, WarningPercent, IsHardLimit);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增或更新SaaS套餐版本请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record UpsertSaasOfferingVersionDto(
|
||||
Guid? Id,
|
||||
Guid OfferingId,
|
||||
PlatformBillingCycle BillingCycle,
|
||||
[Range(0, int.MaxValue)] int OriginalAmountCents,
|
||||
[Range(0, int.MaxValue)] int AmountCents,
|
||||
[Required, MaxLength(10)] string Currency,
|
||||
DateTimeOffset? EffectiveAt,
|
||||
IReadOnlyCollection<string>? FeatureCodes,
|
||||
IReadOnlyDictionary<string, long>? Limits,
|
||||
JsonElement Metadata)
|
||||
{
|
||||
public UpsertSaasOfferingVersionCommand ToCommand() => new(
|
||||
Id, OfferingId, BillingCycle, OriginalAmountCents, AmountCents, Currency, EffectiveAt,
|
||||
FeatureCodes ?? [], Limits ?? new Dictionary<string, long>(), Metadata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建平台账务报价请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record CreatePlatformBillingQuoteDto(
|
||||
Guid BaseOfferingVersionId,
|
||||
IReadOnlyCollection<Guid>? AddOnOfferingVersionIds,
|
||||
PlatformBillingOrderPurpose Purpose,
|
||||
[Required, MaxLength(200)] string IdempotencyKey)
|
||||
{
|
||||
public CreatePlatformBillingQuoteCommand ToCommand() => new(BaseOfferingVersionId, AddOnOfferingVersionIds ?? [], Purpose, IdempotencyKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建平台账务订单请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record CreatePlatformBillingOrderDto(Guid QuoteId, [Required, MaxLength(200)] string IdempotencyKey)
|
||||
{
|
||||
public CreatePlatformBillingOrderCommand ToCommand() => new(QuoteId, IdempotencyKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建平台账务支付请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record CreatePlatformBillingPaymentDto(
|
||||
[Required, MaxLength(50)] string Provider,
|
||||
[Required, MaxLength(50)] string Method,
|
||||
[Required, MaxLength(200)] string IdempotencyKey,
|
||||
string? OpenId,
|
||||
string? ReturnUrl,
|
||||
string? QuitUrl)
|
||||
{
|
||||
public CreatePlatformBillingPaymentCommand ToCommand(string orderNo) =>
|
||||
new(orderNo, Provider, Method, IdempotencyKey, OpenId, ReturnUrl, QuitUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 变更租户订阅请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record ChangeTenantSubscriptionDto(
|
||||
Guid BaseOfferingVersionId,
|
||||
IReadOnlyCollection<Guid>? AddOnOfferingVersionIds,
|
||||
[Required, MaxLength(200)] string IdempotencyKey)
|
||||
{
|
||||
public ChangeTenantSubscriptionCommand ToCommand() => new(BaseOfferingVersionId, AddOnOfferingVersionIds ?? []);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Idempotent租户账务请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record IdempotentTenantBillingDto([Required, MaxLength(200)] string IdempotencyKey);
|
||||
|
||||
/// <summary>
|
||||
/// 确认人工平台支付请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record ConfirmManualPlatformPaymentDto(
|
||||
Guid PaymentId,
|
||||
string? ProviderTradeNo,
|
||||
DateTimeOffset? PaidAt,
|
||||
[Required, MaxLength(1000)] string Reason)
|
||||
{
|
||||
public ConfirmManualPaymentCommand ToCommand() => new(PaymentId, ProviderTradeNo, PaidAt, Reason);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增或更新租户功能覆盖规则请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record UpsertTenantFeatureOverrideDto(
|
||||
Guid TenantId,
|
||||
[Required, MaxLength(120)] string FeatureCode,
|
||||
TenantFeatureOverrideMode Mode,
|
||||
DateTimeOffset? ExpiresAt,
|
||||
[Required, MaxLength(1000)] string Reason)
|
||||
{
|
||||
public UpsertTenantFeatureOverrideCommand ToCommand() => new(TenantId, FeatureCode, Mode, ExpiresAt, Reason);
|
||||
}
|
||||
@@ -3,27 +3,57 @@ using Tiku.Application.Scoreline;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 分数线查询参数。
|
||||
/// </summary>
|
||||
public sealed class ScorelineQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 租户编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? TenantCode { 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>
|
||||
/// 关键字。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Keyword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 年份。
|
||||
/// </summary>
|
||||
[Range(1900, 3000)]
|
||||
public int? Year { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 页码。
|
||||
/// </summary>
|
||||
[Range(1, 10000)]
|
||||
public int? Page { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 每页数量。
|
||||
/// </summary>
|
||||
[Range(1, 200)]
|
||||
public int? PageSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 2000)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
|
||||
@@ -3,28 +3,61 @@ using Tiku.Application.StudyContent;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// Study内容查询参数。
|
||||
/// </summary>
|
||||
public sealed class StudyContentQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 租户编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? TenantCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地区 ID。
|
||||
/// </summary>
|
||||
public Guid? RegionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 单元 ID。
|
||||
/// </summary>
|
||||
public Guid? UnitId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 科目 ID。
|
||||
/// </summary>
|
||||
public Guid? SubjectId { 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>
|
||||
/// 关键字。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Keyword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否包含正文内容。
|
||||
/// </summary>
|
||||
public bool IncludeContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 2000)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
|
||||
@@ -7,17 +7,41 @@ using Tiku.Domain.Content;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 创建分类节点请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class CreateTaxonomyNodeDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 父节点 ID。
|
||||
/// </summary>
|
||||
public Guid? ParentId { get; set; }
|
||||
/// <summary>
|
||||
/// 父级来源。
|
||||
/// </summary>
|
||||
public QuestionSource? ParentSource { get; set; }
|
||||
/// <summary>
|
||||
/// 节点Type。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public TaxonomyNodeType NodeType { get; set; }
|
||||
/// <summary>
|
||||
/// 编码。
|
||||
/// </summary>
|
||||
[Required, StringLength(100)]
|
||||
public string Code { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// 名称。
|
||||
/// </summary>
|
||||
[Required, StringLength(300)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// 排序值。
|
||||
/// </summary>
|
||||
public int SortOrder { get; set; }
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
|
||||
public CreateTaxonomyNodeCommand ToCommand() => new(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,41 +7,83 @@ using Tiku.Domain.Tenancy;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 租户交易查询参数。
|
||||
/// </summary>
|
||||
public sealed class TenantCommerceQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务提供方。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Provider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
[StringLength(32)]
|
||||
public string? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 200)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户 ID。
|
||||
/// </summary>
|
||||
public Guid? UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地区 ID。
|
||||
/// </summary>
|
||||
public Guid? RegionId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增或更新支付账号请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpsertPaymentAccountDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务提供方。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Provider { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 模式。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Mode { get; set; } = "TenantCollect";
|
||||
|
||||
/// <summary>
|
||||
/// 显示名称。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? DisplayName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public TenantExternalProviderStatus Status { get; set; } = TenantExternalProviderStatus.Disabled;
|
||||
|
||||
/// <summary>
|
||||
/// 密钥引用。
|
||||
/// </summary>
|
||||
[StringLength(300)]
|
||||
public string? SecretRef { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 优先级。
|
||||
/// </summary>
|
||||
public int? Priority { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 公开配置内容。
|
||||
/// </summary>
|
||||
public JsonElement ConfigPublic { get; set; } = JsonDefaults.Object();
|
||||
|
||||
public UpsertPaymentAccountCommand ToCommand()
|
||||
@@ -50,25 +92,49 @@ public sealed class UpsertPaymentAccountDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增或更新租户Secret请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpsertTenantSecretDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 用途。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(80)]
|
||||
public string Purpose { get; set; } = "payment";
|
||||
|
||||
/// <summary>
|
||||
/// 服务提供方。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Provider { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 密钥键。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(120)]
|
||||
public string SecretKey { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 密钥引用。
|
||||
/// </summary>
|
||||
[StringLength(300)]
|
||||
public string SecretRef { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public TenantSecretStatus Status { get; set; } = TenantSecretStatus.Active;
|
||||
/// <summary>
|
||||
/// 密钥载荷。
|
||||
/// </summary>
|
||||
public JsonElement SecretPayload { get; set; } = JsonDefaults.Object();
|
||||
/// <summary>
|
||||
/// 过期时间。
|
||||
/// </summary>
|
||||
public DateTimeOffset? ExpiresAt { get; set; }
|
||||
|
||||
public UpsertTenantSecretCommand ToCommand()
|
||||
@@ -84,32 +150,62 @@ public sealed class UpsertTenantSecretDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建编码批次请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class CreateCodeBatchDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 名称。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(200)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 总数量。
|
||||
/// </summary>
|
||||
[Range(1, 1000)]
|
||||
public int TotalCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 天数。
|
||||
/// </summary>
|
||||
[Range(1, 3650)]
|
||||
public int Days { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地区 ID。
|
||||
/// </summary>
|
||||
public Guid? RegionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 售卖类型。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? SaleType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 渠道。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Channel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认单价,单位为分。
|
||||
/// </summary>
|
||||
[Range(0, int.MaxValue)]
|
||||
public int? DefaultUnitPriceCents { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 成本价,单位为分。
|
||||
/// </summary>
|
||||
[Range(0, int.MaxValue)]
|
||||
public int? CostPriceCents { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Remark { get; set; }
|
||||
|
||||
@@ -128,15 +224,27 @@ public sealed class CreateCodeBatchDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 核销激活码编码请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class RedeemActivationCodeDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 编码。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 用户 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地区 ID。
|
||||
/// </summary>
|
||||
public Guid? RegionId { get; set; }
|
||||
|
||||
public RedeemActivationCodeCommand ToCommand()
|
||||
@@ -145,34 +253,76 @@ public sealed class RedeemActivationCodeDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增或更新积分任务请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpsertPointTaskDto
|
||||
{
|
||||
/// <summary>
|
||||
/// ID。
|
||||
/// </summary>
|
||||
public Guid? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务键。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string TaskKey { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 标题。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(200)]
|
||||
public string Title { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 说明。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务类型。
|
||||
/// </summary>
|
||||
public PointActivityTaskType TaskType { get; set; } = PointActivityTaskType.Manual;
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public PointActivityTaskStatus Status { get; set; } = PointActivityTaskStatus.Active;
|
||||
|
||||
/// <summary>
|
||||
/// 积分数量。
|
||||
/// </summary>
|
||||
[Range(1, int.MaxValue)]
|
||||
public int Points { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 每用户最多领取次数。
|
||||
/// </summary>
|
||||
[Range(1, 1000)]
|
||||
public int MaxClaimsPerUser { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 开始时间。
|
||||
/// </summary>
|
||||
public DateTimeOffset? StartsAt { get; set; }
|
||||
/// <summary>
|
||||
/// 结束时间。
|
||||
/// </summary>
|
||||
public DateTimeOffset? EndsAt { get; set; }
|
||||
/// <summary>
|
||||
/// 排序值。
|
||||
/// </summary>
|
||||
public int SortOrder { get; set; }
|
||||
/// <summary>
|
||||
/// 规则配置。
|
||||
/// </summary>
|
||||
public JsonElement Rules { get; set; } = JsonDefaults.Object();
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
|
||||
public UpsertPointTaskCommand ToCommand()
|
||||
@@ -194,38 +344,86 @@ public sealed class UpsertPointTaskDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增或更新积分兑换Item请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpsertPointExchangeItemDto
|
||||
{
|
||||
/// <summary>
|
||||
/// ID。
|
||||
/// </summary>
|
||||
public Guid? Id { get; set; }
|
||||
/// <summary>
|
||||
/// 地区 ID。
|
||||
/// </summary>
|
||||
public Guid? RegionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 兑换项键。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string ItemKey { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 名称。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(200)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 说明。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 兑换项类型。
|
||||
/// </summary>
|
||||
public PointExchangeItemType ItemType { get; set; } = PointExchangeItemType.Entitlement;
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public PointExchangeItemStatus Status { get; set; } = PointExchangeItemStatus.Active;
|
||||
|
||||
/// <summary>
|
||||
/// 所需积分。
|
||||
/// </summary>
|
||||
[Range(1, int.MaxValue)]
|
||||
public int PointsCost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 库存数量。
|
||||
/// </summary>
|
||||
[Range(0, int.MaxValue)]
|
||||
public int? Stock { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 天数。
|
||||
/// </summary>
|
||||
[Range(0, 3650)]
|
||||
public int? Days { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序值。
|
||||
/// </summary>
|
||||
public int SortOrder { get; set; }
|
||||
/// <summary>
|
||||
/// 开始时间。
|
||||
/// </summary>
|
||||
public DateTimeOffset? StartsAt { get; set; }
|
||||
/// <summary>
|
||||
/// 结束时间。
|
||||
/// </summary>
|
||||
public DateTimeOffset? EndsAt { get; set; }
|
||||
/// <summary>
|
||||
/// 履约载荷。
|
||||
/// </summary>
|
||||
public JsonElement FulfillmentPayload { get; set; } = JsonDefaults.Object();
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
|
||||
public UpsertPointExchangeItemCommand ToCommand()
|
||||
@@ -249,20 +447,41 @@ public sealed class UpsertPointExchangeItemDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建退款Request请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class CreateRefundRequestDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 订单 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid OrderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付记录 ID。
|
||||
/// </summary>
|
||||
public Guid? PaymentId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 金额,单位为分。
|
||||
/// </summary>
|
||||
[Range(1, int.MaxValue)]
|
||||
public int AmountCents { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 原因。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Reason { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 权益动作。
|
||||
/// </summary>
|
||||
public RefundEntitlementAction EntitlementAction { get; set; } = RefundEntitlementAction.RevokeOnSuccess;
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
|
||||
public CreateRefundRequestCommand ToCommand()
|
||||
@@ -271,16 +490,31 @@ public sealed class CreateRefundRequestDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新退款状态请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpdateRefundStatusDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 退款申请 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid RefundRequestId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public CommerceRefundStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 原因。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Reason { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 渠道退款单号。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? ProviderRefundNo { get; set; }
|
||||
|
||||
@@ -290,23 +524,47 @@ public sealed class UpdateRefundStatusDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建对账批次请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class CreateReconciliationBatchDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务提供方。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Provider { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 账单日期。
|
||||
/// </summary>
|
||||
public DateOnly BillDate { get; set; }
|
||||
/// <summary>
|
||||
/// 账单类型。
|
||||
/// </summary>
|
||||
public ReconciliationBillType BillType { get; set; } = ReconciliationBillType.Combined;
|
||||
/// <summary>
|
||||
/// 来源。
|
||||
/// </summary>
|
||||
public ReconciliationSource Source { get; set; } = ReconciliationSource.ManualUpload;
|
||||
|
||||
/// <summary>
|
||||
/// 来源名称。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? SourceName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源哈希。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(200)]
|
||||
public string SourceHash { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
|
||||
public CreateReconciliationBatchCommand ToCommand()
|
||||
@@ -315,17 +573,35 @@ public sealed class CreateReconciliationBatchDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新对账Issue请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpdateReconciliationIssueDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 工单 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid IssueId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public ReconciliationIssueStatus Status { get; set; } = ReconciliationIssueStatus.Investigating;
|
||||
/// <summary>
|
||||
/// 处理类型。
|
||||
/// </summary>
|
||||
public ReconciliationResolutionType ResolutionType { get; set; } = ReconciliationResolutionType.None;
|
||||
|
||||
/// <summary>
|
||||
/// 备注。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Note { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分配处理人。
|
||||
/// </summary>
|
||||
public Guid? AssignedTo { get; set; }
|
||||
|
||||
public UpdateReconciliationIssueCommand ToCommand()
|
||||
@@ -334,19 +610,37 @@ public sealed class UpdateReconciliationIssueDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 预览对账导入请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class PreviewReconciliationImportDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务提供方。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Provider { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 账单日期。
|
||||
/// </summary>
|
||||
public DateOnly BillDate { get; set; }
|
||||
/// <summary>
|
||||
/// 账单类型。
|
||||
/// </summary>
|
||||
public ReconciliationBillType BillType { get; set; } = ReconciliationBillType.Combined;
|
||||
|
||||
/// <summary>
|
||||
/// 来源名称。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(300)]
|
||||
public string SourceName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 数据行列表。
|
||||
/// </summary>
|
||||
public JsonElement Rows { get; set; } = JsonDefaults.Array();
|
||||
|
||||
public PreviewReconciliationImportCommand ToPreviewCommand() => new(Provider, BillDate, BillType, SourceName, Rows);
|
||||
@@ -354,29 +648,68 @@ public sealed class PreviewReconciliationImportDto
|
||||
public ImportReconciliationCommand ToImportCommand() => new(Provider, BillDate, BillType, SourceName, Rows);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建调账凭证请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class CreateAdjustmentVoucherDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 工单 ID。
|
||||
/// </summary>
|
||||
public Guid? IssueId { get; set; }
|
||||
/// <summary>
|
||||
/// 批次 ID。
|
||||
/// </summary>
|
||||
public Guid? BatchId { get; set; }
|
||||
/// <summary>
|
||||
/// 兑换项 ID。
|
||||
/// </summary>
|
||||
public Guid? ItemId { get; set; }
|
||||
/// <summary>
|
||||
/// 订单 ID。
|
||||
/// </summary>
|
||||
public Guid? OrderId { get; set; }
|
||||
/// <summary>
|
||||
/// 支付记录 ID。
|
||||
/// </summary>
|
||||
public Guid? PaymentId { get; set; }
|
||||
/// <summary>
|
||||
/// 退款申请 ID。
|
||||
/// </summary>
|
||||
public Guid? RefundRequestId { get; set; }
|
||||
/// <summary>
|
||||
/// 方向。
|
||||
/// </summary>
|
||||
public CommerceAdjustmentDirection Direction { get; set; } = CommerceAdjustmentDirection.IncreaseRevenue;
|
||||
|
||||
/// <summary>
|
||||
/// 金额,单位为分。
|
||||
/// </summary>
|
||||
[Range(1, int.MaxValue)]
|
||||
public int AmountCents { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 币种。
|
||||
/// </summary>
|
||||
[StringLength(10)]
|
||||
public string? Currency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 原因。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(1000)]
|
||||
public string Reason { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 证明资产键。
|
||||
/// </summary>
|
||||
[StringLength(500)]
|
||||
public string? ProofAssetKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
|
||||
public CreateAdjustmentVoucherCommand ToCommand() => new(
|
||||
@@ -394,56 +727,110 @@ public sealed class CreateAdjustmentVoucherDto
|
||||
Metadata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新调账凭证状态请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpdateAdjustmentVoucherStatusDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 凭证 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid VoucherId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public CommerceAdjustmentVoucherStatus Status { get; set; } = CommerceAdjustmentVoucherStatus.PendingReview;
|
||||
|
||||
/// <summary>
|
||||
/// 备注。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Note { get; set; }
|
||||
|
||||
public UpdateAdjustmentVoucherStatusCommand ToCommand() => new(VoucherId, Status, Note);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RequestProviderBill任务请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class RequestProviderBillJobDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务提供方。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(50)]
|
||||
public string Provider { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 账单日期。
|
||||
/// </summary>
|
||||
public DateOnly BillDate { get; set; }
|
||||
/// <summary>
|
||||
/// 账单类型。
|
||||
/// </summary>
|
||||
public ReconciliationBillType BillType { get; set; } = ReconciliationBillType.Combined;
|
||||
/// <summary>
|
||||
/// 计划运行时间。
|
||||
/// </summary>
|
||||
public DateTimeOffset? RunAfter { get; set; }
|
||||
|
||||
public RequestProviderBillJobCommand ToCommand() => new(Provider, BillDate, BillType, RunAfter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退款通知请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class RefundNotificationDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 退款单号。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string RefundNo { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 渠道退款单号。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? ProviderRefundNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public CommerceRefundStatus Status { get; set; } = CommerceRefundStatus.Succeeded;
|
||||
|
||||
/// <summary>
|
||||
/// 事件 ID。
|
||||
/// </summary>
|
||||
[StringLength(200)]
|
||||
public string? EventId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务载荷。
|
||||
/// </summary>
|
||||
public JsonElement Payload { get; set; } = JsonDefaults.Object();
|
||||
|
||||
public RefundNotificationCommand ToCommand(string provider) => new(provider, RefundNo, ProviderRefundNo, Status, EventId, Payload);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新积分兑换订单状态请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpdatePointExchangeOrderStatusDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 订单 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid OrderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态。
|
||||
/// </summary>
|
||||
public PointExchangeOrderStatus Status { get; set; }
|
||||
|
||||
public UpdatePointExchangeOrderStatusCommand ToCommand()
|
||||
@@ -452,29 +839,62 @@ public sealed class UpdatePointExchangeOrderStatusDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增或更新租户优惠券请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class UpsertTenantCouponDto
|
||||
{
|
||||
/// <summary>
|
||||
/// ID。
|
||||
/// </summary>
|
||||
public Guid? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编码。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Code { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 套餐 ID。
|
||||
/// </summary>
|
||||
public Guid? PlanId { get; set; }
|
||||
/// <summary>
|
||||
/// 优惠类型。
|
||||
/// </summary>
|
||||
public DiscountType DiscountType { get; set; } = DiscountType.Fixed;
|
||||
|
||||
/// <summary>
|
||||
/// 优惠值。
|
||||
/// </summary>
|
||||
[Range(typeof(decimal), "0.01", "999999")]
|
||||
public decimal DiscountValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 有效期开始时间。
|
||||
/// </summary>
|
||||
public DateTimeOffset? ValidFrom { get; set; }
|
||||
/// <summary>
|
||||
/// 有效期结束时间。
|
||||
/// </summary>
|
||||
public DateTimeOffset? ValidTo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大使用次数。
|
||||
/// </summary>
|
||||
[Range(1, int.MaxValue)]
|
||||
public int? MaxUses { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来源。
|
||||
/// </summary>
|
||||
[StringLength(50)]
|
||||
public string? Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注。
|
||||
/// </summary>
|
||||
[StringLength(1000)]
|
||||
public string? Remark { get; set; }
|
||||
|
||||
|
||||
@@ -12,14 +12,14 @@ namespace Tiku.Api.Contracts;
|
||||
public sealed class TenantResolveQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 要解析的访问域名,例如 student.example.com。本地开发也可以直接传 localhost。
|
||||
/// 访问域名。
|
||||
/// </summary>
|
||||
[StringLength(253)]
|
||||
[Description("要解析的访问域名,例如 student.example.com。本地开发也可以直接传 localhost。")]
|
||||
public string? Host { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 租户编码;本地开发或无独立域名时使用,例如 master。
|
||||
/// 租户编码。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
[Description("租户编码;本地开发或无独立域名时使用,例如 master。")]
|
||||
@@ -34,6 +34,9 @@ public sealed class TenantResolveQueryDto
|
||||
/// <param name="Features">面向前端公开的功能开关。</param>
|
||||
/// <param name="AdminFeatures">面向管理端公开的功能开关。</param>
|
||||
/// <param name="PublicConfig">可公开的租户配置,不包含密钥或内部配置。</param>
|
||||
/// <summary>
|
||||
/// 租户解析Response请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record TenantResolveResponseDto(
|
||||
PublicTenantDto Tenant,
|
||||
PublicTenantBrandingDto Branding,
|
||||
@@ -50,6 +53,9 @@ public sealed record TenantResolveResponseDto(
|
||||
/// <param name="Status">租户状态。</param>
|
||||
/// <param name="Mode">租户模式。</param>
|
||||
/// <param name="Host">当前匹配到的访问域名。</param>
|
||||
/// <summary>
|
||||
/// 公开租户请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record PublicTenantDto(
|
||||
Guid Id,
|
||||
string Slug,
|
||||
@@ -70,6 +76,9 @@ public sealed record PublicTenantDto(
|
||||
/// <param name="ServiceAccountName">公众号或服务号名称。</param>
|
||||
/// <param name="Theme">公开主题配置。</param>
|
||||
/// <param name="PublicAssets">公开资源配置。</param>
|
||||
/// <summary>
|
||||
/// 公开租户品牌请求 DTO。
|
||||
/// </summary>
|
||||
public sealed record PublicTenantBrandingDto(
|
||||
string? BrandName,
|
||||
string? ShortName,
|
||||
|
||||
@@ -5,12 +5,30 @@ using Tiku.Domain.Common;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 保存租户前端配置草稿请求。
|
||||
/// </summary>
|
||||
public sealed class SaveTenantFrontendConfigDraftDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 品牌配置。
|
||||
/// </summary>
|
||||
public JsonElement Branding { get; set; } = JsonDefaults.Object();
|
||||
/// <summary>
|
||||
/// 主题配置。
|
||||
/// </summary>
|
||||
public JsonElement Theme { get; set; } = JsonDefaults.Object();
|
||||
/// <summary>
|
||||
/// 功能配置。
|
||||
/// </summary>
|
||||
public JsonElement Features { get; set; } = JsonDefaults.Object();
|
||||
/// <summary>
|
||||
/// 导航配置。
|
||||
/// </summary>
|
||||
public JsonElement Navigation { get; set; } = JsonDefaults.Array();
|
||||
/// <summary>
|
||||
/// 首页模块配置。
|
||||
/// </summary>
|
||||
public JsonElement HomeModules { get; set; } = JsonDefaults.Array();
|
||||
|
||||
public TenantFrontendConfigDraft ToDraft() => new(
|
||||
@@ -21,8 +39,14 @@ public sealed class SaveTenantFrontendConfigDraftDto
|
||||
HomeModules);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发布租户前端配置请求。
|
||||
/// </summary>
|
||||
public sealed class PublishTenantFrontendConfigDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 期望配置版本。
|
||||
/// </summary>
|
||||
[Range(1, int.MaxValue)]
|
||||
public int ExpectedVersion { get; set; }
|
||||
}
|
||||
|
||||
@@ -4,47 +4,92 @@ using Tiku.Application.Assets;
|
||||
|
||||
namespace Tiku.Api.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 视频Search查询参数。
|
||||
/// </summary>
|
||||
public sealed class VideoSearchQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 关键字。
|
||||
/// </summary>
|
||||
[StringLength(100)]
|
||||
public string? Keyword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 科目 ID。
|
||||
/// </summary>
|
||||
public Guid? SubjectId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 200)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
public VideoSearchQuery ToQuery() => new(Keyword, SubjectId, Limit);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 视频Play请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class VideoPlayDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 视频 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid VideoId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 题目 ID。
|
||||
/// </summary>
|
||||
public Guid? QuestionId { get; set; }
|
||||
|
||||
public VideoPlayCommand ToCommand() => new(VideoId, QuestionId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 视频Progress请求 DTO。
|
||||
/// </summary>
|
||||
public sealed class VideoProgressDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 视频 ID。
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Guid VideoId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 题目 ID。
|
||||
/// </summary>
|
||||
public Guid? QuestionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 播放位置,单位为秒。
|
||||
/// </summary>
|
||||
[Range(0, int.MaxValue)]
|
||||
public int PositionSeconds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 时长,单位为秒。
|
||||
/// </summary>
|
||||
[Range(0, int.MaxValue)]
|
||||
public int? DurationSeconds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 已观看时长,单位为秒。
|
||||
/// </summary>
|
||||
[Range(0, int.MaxValue)]
|
||||
public int? WatchedSeconds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否已完成。
|
||||
/// </summary>
|
||||
public bool? IsCompleted { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扩展元数据。
|
||||
/// </summary>
|
||||
public JsonElement Metadata { get; set; } = JsonSerializer.SerializeToElement(new { });
|
||||
|
||||
public VideoProgressCommand ToCommand()
|
||||
@@ -60,13 +105,25 @@ public sealed class VideoProgressDto
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 题目视频查询参数。
|
||||
/// </summary>
|
||||
public sealed class QuestionVideoQueryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 题目 ID。
|
||||
/// </summary>
|
||||
public Guid? QuestionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 题目 ID 列表。
|
||||
/// </summary>
|
||||
[MaxLength(100)]
|
||||
public IReadOnlyCollection<Guid>? QuestionIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回数量上限。
|
||||
/// </summary>
|
||||
[Range(1, 500)]
|
||||
public int? Limit { get; set; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user