完善基础数据
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
using F9WebAiTest.Application.Common.Exceptions;
|
||||
using F9WebAiTest.Application.Interfaces.SnowflakeID;
|
||||
using F9WebAiTest.Domain.Entities.SYS.Registries;
|
||||
using F9WebAiTest.Domain.Interfaces.SYS.Registries;
|
||||
using MediatR;
|
||||
|
||||
namespace F9WebAiTest.Application.CQRS.SYS.Registries.Commands;
|
||||
|
||||
/// <summary>注册表支持的数据类型(与前端下拉、F9 的 IRegistryService 保持一致)</summary>
|
||||
public static class RegistryDataTypes
|
||||
{
|
||||
public static readonly string[] All = { "string", "int", "decimal", "bool", "json", "array" };
|
||||
|
||||
/// <summary>归一化为小写并校验(如 F9 历史数据里的 "Array" → "array")</summary>
|
||||
public static string Normalize(string dataType)
|
||||
{
|
||||
var value = (dataType ?? "").Trim().ToLowerInvariant();
|
||||
if (value.Length == 0) return "string";
|
||||
if (!All.Contains(value))
|
||||
throw new F9OperationException($"数据类型[{dataType}]不支持,可选:{string.Join(" / ", All)}");
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增配置项(存在同"命名空间 + 键名"的记录时自动改为更新,对应 F9 的 BASE-REGISTRY-RULE-1)
|
||||
/// </summary>
|
||||
public record Registry_CreateCommand(string Category, string KeyName, string Value, string DataType, string Description, bool IsActive)
|
||||
: IRequest<long>;
|
||||
|
||||
public class CreateRegistryCommandHandler(
|
||||
IRegistryWriteRepository registryRepository,
|
||||
ISnowflakeIdGenerator snowflakeIdGenerator,
|
||||
IPublisher eventBus) : IRequestHandler<Registry_CreateCommand, long>
|
||||
{
|
||||
public async Task<long> Handle(Registry_CreateCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var category = (command.Category ?? "").Trim();
|
||||
var keyName = (command.KeyName ?? "").Trim();
|
||||
if (string.IsNullOrEmpty(category)) throw new F9OperationException("命名空间不能为空");
|
||||
if (string.IsNullOrEmpty(keyName)) throw new F9OperationException("键名不能为空");
|
||||
|
||||
var dataType = RegistryDataTypes.Normalize(command.DataType);
|
||||
var value = command.Value ?? string.Empty;
|
||||
var description = command.Description ?? string.Empty;
|
||||
|
||||
// 已存在同命名空间 + 键名的配置:直接更新(供 SetRegistry 之类的"设置值"场景复用)
|
||||
var exist = await registryRepository.GetByCategoryAndKeyAsync(category, keyName);
|
||||
if (exist != null)
|
||||
{
|
||||
exist.Update(category, keyName, value, dataType, description, command.IsActive);
|
||||
var updated = await registryRepository.UpdateAsync(exist);
|
||||
if (updated == false) throw new F9OperationException("注册表配置", "修改");
|
||||
|
||||
foreach (var de in exist.DomainEvents) await eventBus.Publish(de, cancellationToken);
|
||||
exist.ClearDomainEvents();
|
||||
return exist.Id;
|
||||
}
|
||||
|
||||
var entity = new Registry(snowflakeIdGenerator.CreateId(), category, keyName, value, dataType, description, command.IsActive);
|
||||
var result = await registryRepository.AddAsync(entity);
|
||||
if (result == false) throw new F9OperationException("注册表配置", "新增");
|
||||
|
||||
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
|
||||
entity.ClearDomainEvents();
|
||||
|
||||
return entity.Id;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>修改配置项</summary>
|
||||
public record Registry_UpdateCommand(long Id, string Category, string KeyName, string Value, string DataType, string Description, bool IsActive)
|
||||
: IRequest<bool>;
|
||||
|
||||
public class UpdateRegistryCommandHandler(
|
||||
IRegistryWriteRepository registryRepository,
|
||||
IPublisher eventBus) : IRequestHandler<Registry_UpdateCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(Registry_UpdateCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await registryRepository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("注册表配置不存在");
|
||||
|
||||
var category = (command.Category ?? "").Trim();
|
||||
var keyName = (command.KeyName ?? "").Trim();
|
||||
if (string.IsNullOrEmpty(category)) throw new F9OperationException("命名空间不能为空");
|
||||
if (string.IsNullOrEmpty(keyName)) throw new F9OperationException("键名不能为空");
|
||||
|
||||
// 同一命名空间下键名不能重复
|
||||
var duplicate = await registryRepository.GetByCategoryAndKeyAsync(category, keyName);
|
||||
if (duplicate != null && duplicate.Id != command.Id)
|
||||
throw new F9OperationException($"命名空间[{category}]下已存在键名[{keyName}]");
|
||||
|
||||
entity.Update(category, keyName, command.Value ?? string.Empty, RegistryDataTypes.Normalize(command.DataType),
|
||||
command.Description ?? string.Empty, command.IsActive);
|
||||
|
||||
var result = await registryRepository.UpdateAsync(entity);
|
||||
if (result == false) throw new F9OperationException("注册表配置", "修改");
|
||||
|
||||
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
|
||||
entity.ClearDomainEvents();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>只修改值("设置注册表值"场景)</summary>
|
||||
public record Registry_SetValueCommand(long Id, string Value) : IRequest<bool>;
|
||||
|
||||
public class SetValueRegistryCommandHandler(
|
||||
IRegistryWriteRepository registryRepository,
|
||||
IPublisher eventBus) : IRequestHandler<Registry_SetValueCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(Registry_SetValueCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await registryRepository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("注册表配置不存在");
|
||||
|
||||
entity.SetValue(command.Value ?? string.Empty);
|
||||
|
||||
var result = await registryRepository.UpdateAsync(entity);
|
||||
if (result == false) throw new F9OperationException("注册表配置", "修改");
|
||||
|
||||
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
|
||||
entity.ClearDomainEvents();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>删除配置项</summary>
|
||||
public record Registry_DelCommand(long Id) : IRequest<bool>;
|
||||
|
||||
public class DelRegistryCommandHandler(
|
||||
IRegistryWriteRepository registryRepository,
|
||||
IPublisher eventBus) : IRequestHandler<Registry_DelCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(Registry_DelCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await registryRepository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("注册表配置不存在");
|
||||
|
||||
var result = await registryRepository.SoftDeleteAsync(command.Id);
|
||||
if (result == false) throw new F9OperationException("注册表配置", "删除");
|
||||
|
||||
entity.Deleted();
|
||||
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
|
||||
entity.ClearDomainEvents();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using F9WebAiTest.Application.Dtos.SYS.Registries;
|
||||
using F9WebAiTest.Application.Interfaces.Repositories.SYS.Registries;
|
||||
using MediatR;
|
||||
|
||||
namespace F9WebAiTest.Application.CQRS.SYS.Registries.Queries;
|
||||
|
||||
/// <summary>全部注册表配置(含未启用)</summary>
|
||||
public record GetRegistryAllQuery() : IRequest<List<RegistryReadDto_View>>;
|
||||
|
||||
public class GetRegistryAllQueryHandler(IRegistryReadRepository readRepository)
|
||||
: IRequestHandler<GetRegistryAllQuery, List<RegistryReadDto_View>>
|
||||
{
|
||||
public async Task<List<RegistryReadDto_View>> Handle(GetRegistryAllQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetAllAsync();
|
||||
}
|
||||
|
||||
/// <summary>按 Id 查询(编辑回显)</summary>
|
||||
public record GetRegistryByIdForEditQuery(long Id) : IRequest<RegistryReadDto_Edit>;
|
||||
|
||||
public class GetRegistryByIdForEditQueryHandler(IRegistryReadRepository readRepository)
|
||||
: IRequestHandler<GetRegistryByIdForEditQuery, RegistryReadDto_Edit>
|
||||
{
|
||||
public async Task<RegistryReadDto_Edit> Handle(GetRegistryByIdForEditQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetByIdForEditAsync(query.Id);
|
||||
}
|
||||
|
||||
/// <summary>按命名空间 + 键名查询(业务模块取值入口)</summary>
|
||||
public record GetByCategoryAndKeyQuery(string Category, string KeyName) : IRequest<RegistryReadDto_Edit>;
|
||||
|
||||
public class GetByCategoryAndKeyQueryHandler(IRegistryReadRepository readRepository)
|
||||
: IRequestHandler<GetByCategoryAndKeyQuery, RegistryReadDto_Edit>
|
||||
{
|
||||
public async Task<RegistryReadDto_Edit> Handle(GetByCategoryAndKeyQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetByCategoryAndKeyAsync(query.Category, query.KeyName);
|
||||
}
|
||||
Reference in New Issue
Block a user