完善基础数据

This commit is contained in:
yanpeng200212
2026-10-08 15:44:07 +08:00
parent 8430ba0452
commit 2ffb83830c
95 changed files with 37759 additions and 5 deletions
@@ -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;
}
}