Files
2026-10-08 15:44:07 +08:00

153 lines
6.8 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using 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;
}
}