完善基础数据
This commit is contained in:
+89
@@ -0,0 +1,89 @@
|
||||
using F9WebAiTest.Application.Common.Exceptions;
|
||||
using F9WebAiTest.Application.Interfaces.SnowflakeID;
|
||||
using F9WebAiTest.Domain.Entities.SYS.Gongyingshangs;
|
||||
using F9WebAiTest.Domain.Enums.SYS.Gongyingshangs;
|
||||
using F9WebAiTest.Domain.Interfaces.SYS.Gongyingshangs;
|
||||
using MediatR;
|
||||
|
||||
namespace F9WebAiTest.Application.CQRS.SYS.Gongyingshangs.Commands;
|
||||
|
||||
/// <summary>新增往来单位</summary>
|
||||
public record Gongyingshang_CreateCommand(string Name, Gys_Type_Enum Type, Gys_Group_Enum Group, string Address,
|
||||
string Lianxiren, string Phone, string Pinyin, Gys_SaleType_Enum SaleType) : IRequest<long>;
|
||||
|
||||
public class CreateGongyingshangCommandHandler(
|
||||
IGongyingshangWriteRepository repository,
|
||||
ISnowflakeIdGenerator snowflakeIdGenerator,
|
||||
IPublisher eventBus) : IRequestHandler<Gongyingshang_CreateCommand, long>
|
||||
{
|
||||
public async Task<long> Handle(Gongyingshang_CreateCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(command.Name)) throw new F9OperationException("往来单位名称不能为空");
|
||||
|
||||
var entity = new Gongyingshang(snowflakeIdGenerator.CreateId(), command.Type, command.Name.Trim(),
|
||||
command.Phone ?? string.Empty, command.Lianxiren ?? string.Empty, command.Address ?? string.Empty,
|
||||
string.IsNullOrWhiteSpace(command.Pinyin) ? BuildPinyin(command.Name) : command.Pinyin.Trim(),
|
||||
command.Group, command.SaleType);
|
||||
|
||||
var result = await repository.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>
|
||||
internal static string BuildPinyin(string name) => (name ?? string.Empty).Trim() is { Length: > 0 } n ? n[..1] : string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>修改往来单位</summary>
|
||||
public record Gongyingshang_UpdateCommand(long Id, string Name, Gys_Type_Enum Type, Gys_Group_Enum Group,
|
||||
string Address, string Lianxiren, string Phone, string Pinyin, Gys_SaleType_Enum SaleType) : IRequest<bool>;
|
||||
|
||||
public class UpdateGongyingshangCommandHandler(
|
||||
IGongyingshangWriteRepository repository,
|
||||
IPublisher eventBus) : IRequestHandler<Gongyingshang_UpdateCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(Gongyingshang_UpdateCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("往来单位不存在");
|
||||
if (string.IsNullOrWhiteSpace(command.Name)) throw new F9OperationException("往来单位名称不能为空");
|
||||
|
||||
entity.Update(command.Type, command.Name.Trim(), command.Phone ?? string.Empty, command.Lianxiren ?? string.Empty,
|
||||
command.Address ?? string.Empty, command.Pinyin ?? string.Empty, command.Group, command.SaleType);
|
||||
|
||||
var result = await repository.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 Gongyingshang_DelCommand(long Id) : IRequest<bool>;
|
||||
|
||||
public class DelGongyingshangCommandHandler(
|
||||
IGongyingshangWriteRepository repository,
|
||||
IPublisher eventBus) : IRequestHandler<Gongyingshang_DelCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(Gongyingshang_DelCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("往来单位不存在");
|
||||
|
||||
var result = await repository.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;
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
using F9WebAiTest.Application.Common;
|
||||
using F9WebAiTest.Application.Dtos.SYS.Gongyingshangs;
|
||||
using F9WebAiTest.Application.Interfaces.Repositories.SYS.Gongyingshangs;
|
||||
using F9WebAiTest.Domain.Enums.SYS.Gongyingshangs;
|
||||
using MediatR;
|
||||
|
||||
namespace F9WebAiTest.Application.CQRS.SYS.Gongyingshangs.Queries;
|
||||
|
||||
/// <summary>往来单位分页查询(业务类型 + 销售类型 + 关键字)</summary>
|
||||
public record GetGongyingshangPagedQuery(Gys_Type_Enum Type = Gys_Type_Enum.干茧, Gys_SaleType_Enum? SaleType = null,
|
||||
string Like = "", int PageIndex = 1, int PageSize = 20) : IRequest<PageResult<GongyingshangReadDto_View>>;
|
||||
|
||||
public class GetGongyingshangPagedQueryHandler(IGongyingshangReadRepository readRepository)
|
||||
: IRequestHandler<GetGongyingshangPagedQuery, PageResult<GongyingshangReadDto_View>>
|
||||
{
|
||||
public async Task<PageResult<GongyingshangReadDto_View>> Handle(GetGongyingshangPagedQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetPagedAsync(query.Type, query.SaleType, query.Like, query.PageIndex, query.PageSize);
|
||||
}
|
||||
|
||||
/// <summary>按 Id 查询往来单位(编辑回显)</summary>
|
||||
public record GetGongyingshangByIdQuery(long Id) : IRequest<GongyingshangDto_Edit>;
|
||||
|
||||
public class GetGongyingshangByIdQueryHandler(IGongyingshangReadRepository readRepository)
|
||||
: IRequestHandler<GetGongyingshangByIdQuery, GongyingshangDto_Edit>
|
||||
{
|
||||
public async Task<GongyingshangDto_Edit> Handle(GetGongyingshangByIdQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetByIdForEditAsync(query.Id);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
using F9WebAiTest.Application.Common.Exceptions;
|
||||
using F9WebAiTest.Application.Interfaces.SnowflakeID;
|
||||
using F9WebAiTest.Domain.Entities.SYS.WorkTypes;
|
||||
using F9WebAiTest.Domain.Interfaces.SYS.WorkTypes;
|
||||
using MediatR;
|
||||
|
||||
namespace F9WebAiTest.Application.CQRS.SYS.WorkTypes.Commands;
|
||||
|
||||
// ==================== 工种主表 ====================
|
||||
|
||||
/// <summary>新增工种</summary>
|
||||
public record WorkType_CreateCommand(string WorkName, int SortOrder, string BizType, string SccbFenlei) : IRequest<long>;
|
||||
|
||||
public class CreateWorkTypeCommandHandler(
|
||||
IWorkTypeWriteRepository workTypeRepository,
|
||||
ISnowflakeIdGenerator snowflakeIdGenerator,
|
||||
IPublisher eventBus) : IRequestHandler<WorkType_CreateCommand, long>
|
||||
{
|
||||
public async Task<long> Handle(WorkType_CreateCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(command.WorkName)) throw new F9OperationException("工种名称不能为空");
|
||||
|
||||
var entity = new WorkType(snowflakeIdGenerator.CreateId(), command.WorkName.Trim(), command.SortOrder,
|
||||
command.BizType ?? string.Empty, command.SccbFenlei ?? string.Empty);
|
||||
|
||||
var result = await workTypeRepository.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 WorkType_UpdateCommand(long Id, string WorkName, int SortOrder, string BizType, string SccbFenlei) : IRequest<bool>;
|
||||
|
||||
public class UpdateWorkTypeCommandHandler(
|
||||
IWorkTypeWriteRepository workTypeRepository,
|
||||
IPublisher eventBus) : IRequestHandler<WorkType_UpdateCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(WorkType_UpdateCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await workTypeRepository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("工种不存在");
|
||||
if (string.IsNullOrWhiteSpace(command.WorkName)) throw new F9OperationException("工种名称不能为空");
|
||||
|
||||
entity.Update(command.WorkName.Trim(), command.SortOrder,
|
||||
command.BizType ?? string.Empty, command.SccbFenlei ?? string.Empty);
|
||||
|
||||
var result = await workTypeRepository.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 WorkType_DelCommand(long Id) : IRequest<bool>;
|
||||
|
||||
public class DelWorkTypeCommandHandler(
|
||||
IWorkTypeWriteRepository workTypeRepository,
|
||||
IWorkTypeDepartmentRepository workTypeDepartmentRepository,
|
||||
IWorkTypeRoleRepository workTypeRoleRepository,
|
||||
IPublisher eventBus) : IRequestHandler<WorkType_DelCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(WorkType_DelCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await workTypeRepository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("工种不存在");
|
||||
|
||||
var result = await workTypeRepository.SoftDeleteAsync(command.Id);
|
||||
if (result == false) throw new F9OperationException("工种", "删除");
|
||||
|
||||
await workTypeDepartmentRepository.HardDeleteByWorkTypeIdAsync(command.Id);
|
||||
await workTypeRoleRepository.HardDeleteByWorkTypeIdAsync(command.Id);
|
||||
|
||||
entity.Deleted();
|
||||
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
|
||||
entity.ClearDomainEvents();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>启用/禁用工种</summary>
|
||||
public record WorkType_ActiveOrDeactivateCommand(long Id, bool Active) : IRequest<bool>;
|
||||
|
||||
public class ActiveOrDeactivateWorkTypeCommandHandler(IWorkTypeWriteRepository workTypeRepository)
|
||||
: IRequestHandler<WorkType_ActiveOrDeactivateCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(WorkType_ActiveOrDeactivateCommand command, CancellationToken cancellationToken)
|
||||
=> await workTypeRepository.ActiveOrDeactive(command.Id, command.Active);
|
||||
}
|
||||
|
||||
// ==================== 工种-部门 ====================
|
||||
|
||||
/// <summary>绑定部门(已存在则直接返回关联 Id)</summary>
|
||||
public record WorkTypeDepartment_AssignCommand(long WorkTypeId, long DepartmentId) : IRequest<long>;
|
||||
|
||||
public class AssignWorkTypeDepartmentCommandHandler(
|
||||
IWorkTypeWriteRepository workTypeRepository,
|
||||
IWorkTypeDepartmentRepository repository,
|
||||
ISnowflakeIdGenerator snowflakeIdGenerator) : IRequestHandler<WorkTypeDepartment_AssignCommand, long>
|
||||
{
|
||||
public async Task<long> Handle(WorkTypeDepartment_AssignCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
_ = await workTypeRepository.GetByIdAsync(command.WorkTypeId, cancellationToken)
|
||||
?? throw new F9NotFoundException("工种不存在");
|
||||
|
||||
var exist = await repository.GetAsync(command.WorkTypeId, command.DepartmentId);
|
||||
if (exist != null) return exist.Id;
|
||||
|
||||
var entity = new WorkTypeDepartment(snowflakeIdGenerator.CreateId(), command.WorkTypeId, command.DepartmentId);
|
||||
var result = await repository.AddAsync(entity);
|
||||
if (result == false) throw new F9OperationException("工种绑定部门", "操作");
|
||||
|
||||
return entity.Id;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>解除部门绑定</summary>
|
||||
public record WorkTypeDepartment_RemoveCommand(long WorkTypeId, long DepartmentId) : IRequest<bool>;
|
||||
|
||||
public class RemoveWorkTypeDepartmentCommandHandler(IWorkTypeDepartmentRepository repository)
|
||||
: IRequestHandler<WorkTypeDepartment_RemoveCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(WorkTypeDepartment_RemoveCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var exist = await repository.GetAsync(command.WorkTypeId, command.DepartmentId)
|
||||
?? throw new F9NotFoundException("工种部门关联不存在");
|
||||
return await repository.HardDeleteAsync(exist.Id);
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 工种-角色 ====================
|
||||
|
||||
/// <summary>关联角色(已存在则直接返回关联 Id)</summary>
|
||||
public record WorkTypeRole_AssignCommand(long WorkTypeId, long RoleId) : IRequest<long>;
|
||||
|
||||
public class AssignWorkTypeRoleCommandHandler(
|
||||
IWorkTypeWriteRepository workTypeRepository,
|
||||
IWorkTypeRoleRepository repository,
|
||||
ISnowflakeIdGenerator snowflakeIdGenerator) : IRequestHandler<WorkTypeRole_AssignCommand, long>
|
||||
{
|
||||
public async Task<long> Handle(WorkTypeRole_AssignCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
_ = await workTypeRepository.GetByIdAsync(command.WorkTypeId, cancellationToken)
|
||||
?? throw new F9NotFoundException("工种不存在");
|
||||
|
||||
var exist = await repository.GetAsync(command.WorkTypeId, command.RoleId);
|
||||
if (exist != null) return exist.Id;
|
||||
|
||||
var entity = new WorkTypeRole(snowflakeIdGenerator.CreateId(), command.WorkTypeId, command.RoleId);
|
||||
var result = await repository.AddAsync(entity);
|
||||
if (result == false) throw new F9OperationException("工种关联角色", "操作");
|
||||
|
||||
return entity.Id;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>解除角色关联</summary>
|
||||
public record WorkTypeRole_RemoveCommand(long WorkTypeId, long RoleId) : IRequest<bool>;
|
||||
|
||||
public class RemoveWorkTypeRoleCommandHandler(IWorkTypeRoleRepository repository)
|
||||
: IRequestHandler<WorkTypeRole_RemoveCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(WorkTypeRole_RemoveCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var exist = await repository.GetAsync(command.WorkTypeId, command.RoleId)
|
||||
?? throw new F9NotFoundException("工种角色关联不存在");
|
||||
return await repository.HardDeleteAsync(exist.Id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using F9WebAiTest.Application.Common;
|
||||
using F9WebAiTest.Application.Dtos.SYS.WorkTypes;
|
||||
using F9WebAiTest.Application.Interfaces.Repositories.SYS.WorkTypes;
|
||||
using MediatR;
|
||||
|
||||
namespace F9WebAiTest.Application.CQRS.SYS.WorkTypes.Queries;
|
||||
|
||||
/// <summary>工种分页查询</summary>
|
||||
public record GetWorkTypePagedQuery(int PageIndex = 1, int PageSize = 20, string Keyword = "") : IRequest<PageResult<WorkTypeReadDto_View>>;
|
||||
|
||||
public class GetWorkTypePagedQueryHandler(IWorkTypeReadRepository readRepository)
|
||||
: IRequestHandler<GetWorkTypePagedQuery, PageResult<WorkTypeReadDto_View>>
|
||||
{
|
||||
public async Task<PageResult<WorkTypeReadDto_View>> Handle(GetWorkTypePagedQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetPagedAsync(query.PageIndex, query.PageSize, query.Keyword);
|
||||
}
|
||||
|
||||
/// <summary>按 Id 查询工种(编辑回显)</summary>
|
||||
public record GetWorkTypeByIdForEditQuery(long Id) : IRequest<WorkTypeReadDto_Edit>;
|
||||
|
||||
public class GetWorkTypeByIdForEditQueryHandler(IWorkTypeReadRepository readRepository)
|
||||
: IRequestHandler<GetWorkTypeByIdForEditQuery, WorkTypeReadDto_Edit>
|
||||
{
|
||||
public async Task<WorkTypeReadDto_Edit> Handle(GetWorkTypeByIdForEditQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetByIdForEditAsync(query.Id);
|
||||
}
|
||||
|
||||
/// <summary>查询某工种已绑定的部门</summary>
|
||||
public record GetWorkTypeDepartmentByWorkIdQuery(long WorkTypeId) : IRequest<List<WorkTypeDepartmentReadDto_Cache>>;
|
||||
|
||||
public class GetWorkTypeDepartmentByWorkIdQueryHandler(IWorkTypeReadRepository readRepository)
|
||||
: IRequestHandler<GetWorkTypeDepartmentByWorkIdQuery, List<WorkTypeDepartmentReadDto_Cache>>
|
||||
{
|
||||
public async Task<List<WorkTypeDepartmentReadDto_Cache>> Handle(GetWorkTypeDepartmentByWorkIdQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetDepartmentsAsync(query.WorkTypeId);
|
||||
}
|
||||
|
||||
/// <summary>查询某工种已关联的角色</summary>
|
||||
public record GetWorkTypeRoleByWorkIdQuery(long WorkTypeId) : IRequest<List<WorkTypeRoleReadDto_Cache>>;
|
||||
|
||||
public class GetWorkTypeRoleByWorkIdQueryHandler(IWorkTypeReadRepository readRepository)
|
||||
: IRequestHandler<GetWorkTypeRoleByWorkIdQuery, List<WorkTypeRoleReadDto_Cache>>
|
||||
{
|
||||
public async Task<List<WorkTypeRoleReadDto_Cache>> Handle(GetWorkTypeRoleByWorkIdQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetRolesAsync(query.WorkTypeId);
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
using F9WebAiTest.Application.Common.Exceptions;
|
||||
using F9WebAiTest.Application.Interfaces.Repositories.SYS.WuziMulus;
|
||||
using F9WebAiTest.Application.Interfaces.SnowflakeID;
|
||||
using F9WebAiTest.Domain.Entities.SYS.WuziMulus;
|
||||
using F9WebAiTest.Domain.Enums.SYS.Departments;
|
||||
using F9WebAiTest.Domain.Enums.SYS.WuziMulus;
|
||||
using F9WebAiTest.Domain.Interfaces.SYS.WuziMulus;
|
||||
using MediatR;
|
||||
|
||||
namespace F9WebAiTest.Application.CQRS.SYS.WuziMulus.Commands;
|
||||
|
||||
// ==================== 物资分组 ====================
|
||||
|
||||
/// <summary>新增物资分组(编号由前端调用 new-code 预生成后提交)</summary>
|
||||
public record WuziGroup_CreateCommand(long ParentId, WuziBusiness_Type_Enum BusinessType,
|
||||
Department_DutyType_Enum DepartmentType, string Code, string Name, int SortOrder, string Description) : IRequest<long>;
|
||||
|
||||
public class CreateWuziGroupCommandHandler(
|
||||
IWuziGroupWriteRepository repository,
|
||||
IWuziGroupReadRepository readRepository,
|
||||
ISnowflakeIdGenerator snowflakeIdGenerator,
|
||||
IPublisher eventBus) : IRequestHandler<WuziGroup_CreateCommand, long>
|
||||
{
|
||||
public async Task<long> Handle(WuziGroup_CreateCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(command.Name)) throw new F9OperationException("分组名称不能为空");
|
||||
|
||||
var code = (command.Code ?? "").Trim();
|
||||
if (string.IsNullOrEmpty(code)) code = await readRepository.GetNewCodeAsync(command.ParentId);
|
||||
|
||||
var entity = new WuziGroup(snowflakeIdGenerator.CreateId(), command.BusinessType, command.DepartmentType,
|
||||
code, command.Name.Trim(), command.ParentId, command.SortOrder, command.Description ?? string.Empty);
|
||||
|
||||
var result = await repository.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 WuziGroup_UpdateCommand(long Id, WuziBusiness_Type_Enum BusinessType,
|
||||
Department_DutyType_Enum DepartmentType, string Name, int SortOrder, string Description) : IRequest<bool>;
|
||||
|
||||
public class UpdateWuziGroupCommandHandler(
|
||||
IWuziGroupWriteRepository repository,
|
||||
IPublisher eventBus) : IRequestHandler<WuziGroup_UpdateCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(WuziGroup_UpdateCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("物资分组不存在");
|
||||
if (string.IsNullOrWhiteSpace(command.Name)) throw new F9OperationException("分组名称不能为空");
|
||||
|
||||
entity.Update(command.BusinessType, command.DepartmentType, command.Name.Trim(), command.SortOrder,
|
||||
command.Description ?? string.Empty);
|
||||
|
||||
var result = await repository.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 WuziGroup_DelCommand(long Id) : IRequest<bool>;
|
||||
|
||||
public class DelWuziGroupCommandHandler(
|
||||
IWuziGroupWriteRepository repository,
|
||||
IWuziGroupReadRepository readRepository,
|
||||
IPublisher eventBus) : IRequestHandler<WuziGroup_DelCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(WuziGroup_DelCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("物资分组不存在");
|
||||
|
||||
if (await readRepository.ExistChildAsync(command.Id)) throw new F9OperationException("存在下级分组,不能删除");
|
||||
if (await readRepository.ExistMuluAsync(command.Id)) throw new F9OperationException("分组下存在物资,不能删除");
|
||||
|
||||
var result = await repository.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;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 物资目录 ====================
|
||||
|
||||
/// <summary>新增物资</summary>
|
||||
public record WuziMulu_CreateCommand(long GroupId, string Name, string Code, string Unit, string Guige,
|
||||
string Xinghao, string PinyinName, decimal Kucunyujing, int SortOrder, bool IsYujing, decimal SaleRate) : IRequest<long>;
|
||||
|
||||
public class CreateWuziMuluCommandHandler(
|
||||
IWuziMuluWriteRepository repository,
|
||||
IWuziMuluReadRepository readRepository,
|
||||
ISnowflakeIdGenerator snowflakeIdGenerator,
|
||||
IPublisher eventBus) : IRequestHandler<WuziMulu_CreateCommand, long>
|
||||
{
|
||||
public async Task<long> Handle(WuziMulu_CreateCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
if (command.GroupId <= 0) throw new F9OperationException("请选择所属分组");
|
||||
if (string.IsNullOrWhiteSpace(command.Name)) throw new F9OperationException("物资名称不能为空");
|
||||
|
||||
var code = (command.Code ?? "").Trim();
|
||||
if (string.IsNullOrEmpty(code)) code = await readRepository.GetNewCodeAsync(command.GroupId);
|
||||
|
||||
var entity = new WuziMulu(snowflakeIdGenerator.CreateId(), command.GroupId, command.Name.Trim(), code,
|
||||
command.Unit ?? string.Empty, command.Guige ?? string.Empty, command.Xinghao ?? string.Empty,
|
||||
command.PinyinName ?? string.Empty, command.Kucunyujing, command.SortOrder, command.IsYujing, command.SaleRate);
|
||||
|
||||
var result = await repository.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 WuziMulu_UpdateCommand(long Id, long GroupId, string Name, string Unit, string Guige,
|
||||
string Xinghao, string PinyinName, decimal Kucunyujing, int SortOrder, bool IsYujing, decimal SaleRate) : IRequest<bool>;
|
||||
|
||||
public class UpdateWuziMuluCommandHandler(
|
||||
IWuziMuluWriteRepository repository,
|
||||
IPublisher eventBus) : IRequestHandler<WuziMulu_UpdateCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(WuziMulu_UpdateCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("物资不存在");
|
||||
if (command.GroupId <= 0) throw new F9OperationException("请选择所属分组");
|
||||
if (string.IsNullOrWhiteSpace(command.Name)) throw new F9OperationException("物资名称不能为空");
|
||||
|
||||
entity.Update(command.GroupId, command.Name.Trim(), command.Unit ?? string.Empty, command.Guige ?? string.Empty,
|
||||
command.Xinghao ?? string.Empty, command.PinyinName ?? string.Empty, command.Kucunyujing,
|
||||
command.SortOrder, command.IsYujing, command.SaleRate);
|
||||
|
||||
var result = await repository.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 WuziMulu_DelCommand(long Id) : IRequest<bool>;
|
||||
|
||||
public class DelWuziMuluCommandHandler(
|
||||
IWuziMuluWriteRepository repository,
|
||||
IPublisher eventBus) : IRequestHandler<WuziMulu_DelCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(WuziMulu_DelCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("物资不存在");
|
||||
|
||||
var result = await repository.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,91 @@
|
||||
using F9WebAiTest.Application.Common;
|
||||
using F9WebAiTest.Application.Dtos.SYS.WuziMulus;
|
||||
using F9WebAiTest.Application.Interfaces.Repositories.SYS.WuziMulus;
|
||||
using MediatR;
|
||||
|
||||
namespace F9WebAiTest.Application.CQRS.SYS.WuziMulus.Queries;
|
||||
|
||||
// ==================== 物资分组 ====================
|
||||
|
||||
/// <summary>全部物资分组(用于构建分组树)</summary>
|
||||
public record GetWuziGroupAllQuery() : IRequest<List<WuziGroupReadDto_View>>;
|
||||
|
||||
public class GetWuziGroupAllQueryHandler(IWuziGroupReadRepository readRepository)
|
||||
: IRequestHandler<GetWuziGroupAllQuery, List<WuziGroupReadDto_View>>
|
||||
{
|
||||
public async Task<List<WuziGroupReadDto_View>> Handle(GetWuziGroupAllQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetAllAsync();
|
||||
}
|
||||
|
||||
/// <summary>按 Id 查询分组(编辑回显)</summary>
|
||||
public record GetWuziGroupByIdQuery(long Id) : IRequest<WuziGroupReadDto_Edit>;
|
||||
|
||||
public class GetWuziGroupByIdQueryHandler(IWuziGroupReadRepository readRepository)
|
||||
: IRequestHandler<GetWuziGroupByIdQuery, WuziGroupReadDto_Edit>
|
||||
{
|
||||
public async Task<WuziGroupReadDto_Edit> Handle(GetWuziGroupByIdQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetByIdForEditAsync(query.Id);
|
||||
}
|
||||
|
||||
/// <summary>分组新编号</summary>
|
||||
public record GetWuziGroupNewCodeQuery(long ParentId) : IRequest<string>;
|
||||
|
||||
public class GetWuziGroupNewCodeQueryHandler(IWuziGroupReadRepository readRepository)
|
||||
: IRequestHandler<GetWuziGroupNewCodeQuery, string>
|
||||
{
|
||||
public async Task<string> Handle(GetWuziGroupNewCodeQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetNewCodeAsync(query.ParentId);
|
||||
}
|
||||
|
||||
/// <summary>是否存在下级(删除前校验)</summary>
|
||||
public record GetWuziGroupExistChildQuery(long Id) : IRequest<bool>;
|
||||
|
||||
public class GetWuziGroupExistChildQueryHandler(IWuziGroupReadRepository readRepository)
|
||||
: IRequestHandler<GetWuziGroupExistChildQuery, bool>
|
||||
{
|
||||
public async Task<bool> Handle(GetWuziGroupExistChildQuery query, CancellationToken ct)
|
||||
=> await readRepository.ExistChildAsync(query.Id);
|
||||
}
|
||||
|
||||
// ==================== 物资目录 ====================
|
||||
|
||||
/// <summary>按分组分页查询物资</summary>
|
||||
public record GetWuziMuluPagedQuery(long GroupId = 0, string Keyword = "", int PageIndex = 1, int PageSize = 20)
|
||||
: IRequest<PageResult<WuziMuluReadDto_View>>;
|
||||
|
||||
public class GetWuziMuluPagedQueryHandler(IWuziMuluReadRepository readRepository)
|
||||
: IRequestHandler<GetWuziMuluPagedQuery, PageResult<WuziMuluReadDto_View>>
|
||||
{
|
||||
public async Task<PageResult<WuziMuluReadDto_View>> Handle(GetWuziMuluPagedQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetPagedAsync(query.GroupId, query.Keyword, query.PageIndex, query.PageSize);
|
||||
}
|
||||
|
||||
/// <summary>按 Id 查询物资(编辑回显)</summary>
|
||||
public record GetWuziMuluByIdQuery(long Id) : IRequest<WuziMuluReadDto_Edit>;
|
||||
|
||||
public class GetWuziMuluByIdQueryHandler(IWuziMuluReadRepository readRepository)
|
||||
: IRequestHandler<GetWuziMuluByIdQuery, WuziMuluReadDto_Edit>
|
||||
{
|
||||
public async Task<WuziMuluReadDto_Edit> Handle(GetWuziMuluByIdQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetByIdForEditAsync(query.Id);
|
||||
}
|
||||
|
||||
/// <summary>物资新编号</summary>
|
||||
public record GetWuziMuluNewCodeQuery(long GroupId) : IRequest<string>;
|
||||
|
||||
public class GetWuziMuluNewCodeQueryHandler(IWuziMuluReadRepository readRepository)
|
||||
: IRequestHandler<GetWuziMuluNewCodeQuery, string>
|
||||
{
|
||||
public async Task<string> Handle(GetWuziMuluNewCodeQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetNewCodeAsync(query.GroupId);
|
||||
}
|
||||
|
||||
/// <summary>物资选项(供其它模块选择物资)</summary>
|
||||
public record GetWuziMuluOptionsQuery(string Keyword = "", int Limit = 200) : IRequest<List<WuziMuluOptionDto>>;
|
||||
|
||||
public class GetWuziMuluOptionsQueryHandler(IWuziMuluReadRepository readRepository)
|
||||
: IRequestHandler<GetWuziMuluOptionsQuery, List<WuziMuluOptionDto>>
|
||||
{
|
||||
public async Task<List<WuziMuluOptionDto>> Handle(GetWuziMuluOptionsQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetOptionsAsync(query.Keyword, query.Limit);
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
using F9WebAiTest.Application.Common;
|
||||
using F9WebAiTest.Application.Common.Exceptions;
|
||||
using F9WebAiTest.Application.Interfaces.Repositories.SYS.YuanliaoZhuangkous;
|
||||
using F9WebAiTest.Application.Interfaces.SnowflakeID;
|
||||
using F9WebAiTest.Domain.Entities.SYS.YuanliaoZhuangkous;
|
||||
using F9WebAiTest.Domain.Enums.SYS.YuanliaoZhuangkous;
|
||||
using F9WebAiTest.Domain.Interfaces.SYS.YuanliaoZhuangkous;
|
||||
using MediatR;
|
||||
|
||||
namespace F9WebAiTest.Application.CQRS.SYS.YuanliaoZhuangkous.Commands;
|
||||
|
||||
/// <summary>新增原料庄口(编号按年度自动生成)</summary>
|
||||
public record YuanliaoZhuangkou_CreateCommand(
|
||||
int Year, string Name, string Jibie, BendiWaidi_Enum BendiWaidi, string Chandi,
|
||||
string Canpinzhong, long WzmlId, string Zhandian, int Pici) : IRequest<long>;
|
||||
|
||||
public class CreateYuanliaoZhuangkouCommandHandler(
|
||||
IYuanliaoZhuangkouWriteRepository repository,
|
||||
IYuanliaoZhuangkouReadRepository readRepository,
|
||||
ISnowflakeIdGenerator snowflakeIdGenerator,
|
||||
IPublisher eventBus) : IRequestHandler<YuanliaoZhuangkou_CreateCommand, long>
|
||||
{
|
||||
public async Task<long> Handle(YuanliaoZhuangkou_CreateCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(command.Name)) throw new F9OperationException("庄口名称不能为空");
|
||||
if (command.Year <= 0) throw new F9OperationException("年度不能为空");
|
||||
if (string.IsNullOrWhiteSpace(command.Chandi)) throw new F9OperationException("产地不能为空");
|
||||
if (string.IsNullOrWhiteSpace(command.Zhandian)) throw new F9OperationException("站点不能为空");
|
||||
if (string.IsNullOrWhiteSpace(command.Jibie)) throw new F9OperationException("季别不能为空");
|
||||
if (string.IsNullOrWhiteSpace(command.Canpinzhong)) throw new F9OperationException("蚕品种不能为空");
|
||||
if (command.WzmlId <= 0) throw new F9OperationException("请选择物资(茧别)");
|
||||
if (string.IsNullOrEmpty(await readRepository.GetWuziNameAsync(command.WzmlId)))
|
||||
throw new F9OperationException("所选物资不存在,请重新选择");
|
||||
|
||||
var code = await GenerateCodeAsync(readRepository, command.Year);
|
||||
|
||||
var entity = new YuanliaoZhuangkou(snowflakeIdGenerator.CreateId(), command.Year, command.Name.Trim(), code,
|
||||
command.Jibie.Trim(), command.BendiWaidi, command.Chandi.Trim(), command.Canpinzhong.Trim(),
|
||||
command.WzmlId, command.Zhandian.Trim(), command.Pici);
|
||||
|
||||
var result = await repository.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>生成编号:{年度} + 3 位流水(如 2025001)</summary>
|
||||
private static async Task<string> GenerateCodeAsync(IYuanliaoZhuangkouReadRepository readRepository, int year)
|
||||
{
|
||||
var codes = await readRepository.GetCodesByYearAsync(year);
|
||||
var maxSeq = 0;
|
||||
foreach (var code in codes)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(code) || code.Length <= 4) continue;
|
||||
if (int.TryParse(code.Substring(4), out var seq) && seq > maxSeq) maxSeq = seq;
|
||||
}
|
||||
return $"{year}{maxSeq + 1:000}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>修改原料庄口(编号不随修改变化)</summary>
|
||||
public record YuanliaoZhuangkou_UpdateCommand(
|
||||
long Id, int Year, string Name, string Jibie, BendiWaidi_Enum BendiWaidi, string Chandi,
|
||||
string Canpinzhong, long WzmlId, string Zhandian, int Pici) : IRequest<bool>;
|
||||
|
||||
public class UpdateYuanliaoZhuangkouCommandHandler(
|
||||
IYuanliaoZhuangkouWriteRepository repository,
|
||||
IYuanliaoZhuangkouReadRepository readRepository,
|
||||
IPublisher eventBus) : IRequestHandler<YuanliaoZhuangkou_UpdateCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(YuanliaoZhuangkou_UpdateCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("原料庄口不存在");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(command.Name)) throw new F9OperationException("庄口名称不能为空");
|
||||
if (string.IsNullOrWhiteSpace(command.Chandi)) throw new F9OperationException("产地不能为空");
|
||||
if (string.IsNullOrWhiteSpace(command.Zhandian)) throw new F9OperationException("站点不能为空");
|
||||
if (string.IsNullOrWhiteSpace(command.Jibie)) throw new F9OperationException("季别不能为空");
|
||||
if (string.IsNullOrWhiteSpace(command.Canpinzhong)) throw new F9OperationException("蚕品种不能为空");
|
||||
if (command.WzmlId <= 0) throw new F9OperationException("请选择物资(茧别)");
|
||||
if (string.IsNullOrEmpty(await readRepository.GetWuziNameAsync(command.WzmlId)))
|
||||
throw new F9OperationException("所选物资不存在,请重新选择");
|
||||
|
||||
entity.Update(command.Year, command.Name.Trim(), command.Jibie.Trim(), command.BendiWaidi,
|
||||
command.Chandi.Trim(), command.Canpinzhong.Trim(), command.WzmlId, command.Zhandian.Trim(), command.Pici);
|
||||
|
||||
var result = await repository.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 YuanliaoZhuangkou_DelCommand(long Id) : IRequest<bool>;
|
||||
|
||||
public class DelYuanliaoZhuangkouCommandHandler(
|
||||
IYuanliaoZhuangkouWriteRepository repository,
|
||||
IPublisher eventBus) : IRequestHandler<YuanliaoZhuangkou_DelCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(YuanliaoZhuangkou_DelCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await repository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("原料庄口不存在");
|
||||
|
||||
var result = await repository.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;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
using F9WebAiTest.Application.Common;
|
||||
using F9WebAiTest.Application.Dtos.SYS.WuziMulus;
|
||||
using F9WebAiTest.Application.Dtos.SYS.YuanliaoZhuangkous;
|
||||
using F9WebAiTest.Application.Interfaces.Repositories.SYS.YuanliaoZhuangkous;
|
||||
using MediatR;
|
||||
|
||||
namespace F9WebAiTest.Application.CQRS.SYS.YuanliaoZhuangkous.Queries;
|
||||
|
||||
/// <summary>原料庄口分页查询(年度 + 产地/站点/季别 + 关键字)</summary>
|
||||
public record GetYuanliaoZhuangkouPagedQuery(
|
||||
int Year = 0, string Chandi = "", string Zhandian = "", string Jibie = "", string Like = "",
|
||||
int PageIndex = 1, int PageSize = 20) : IRequest<PageResult<YuanliaoZhuangkouReadDto_Table>>;
|
||||
|
||||
public class GetYuanliaoZhuangkouPagedQueryHandler(IYuanliaoZhuangkouReadRepository readRepository)
|
||||
: IRequestHandler<GetYuanliaoZhuangkouPagedQuery, PageResult<YuanliaoZhuangkouReadDto_Table>>
|
||||
{
|
||||
public async Task<PageResult<YuanliaoZhuangkouReadDto_Table>> Handle(GetYuanliaoZhuangkouPagedQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetPagedAsync(query.Year, query.Chandi, query.Zhandian, query.Jibie,
|
||||
query.Like, query.PageIndex, query.PageSize);
|
||||
}
|
||||
|
||||
/// <summary>按 Id 查询原料庄口(编辑回显)</summary>
|
||||
public record GetYuanliaoZhuangkouByIdQuery(long Id) : IRequest<YuanliaoZhuangkouReadDto_Edit>;
|
||||
|
||||
public class GetYuanliaoZhuangkouByIdQueryHandler(IYuanliaoZhuangkouReadRepository readRepository)
|
||||
: IRequestHandler<GetYuanliaoZhuangkouByIdQuery, YuanliaoZhuangkouReadDto_Edit>
|
||||
{
|
||||
public async Task<YuanliaoZhuangkouReadDto_Edit> Handle(GetYuanliaoZhuangkouByIdQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetByIdForEditAsync(query.Id);
|
||||
}
|
||||
|
||||
/// <summary>物资(茧别)下拉选项:来自物资目录中名称含"茧"的物资,支持关键字过滤</summary>
|
||||
public record GetYuanliaoZhuangkouWuziOptionsQuery(string Keyword = "") : IRequest<List<WuziMuluOptionDto>>;
|
||||
|
||||
public class GetYuanliaoZhuangkouWuziOptionsQueryHandler(IYuanliaoZhuangkouReadRepository readRepository)
|
||||
: IRequestHandler<GetYuanliaoZhuangkouWuziOptionsQuery, List<WuziMuluOptionDto>>
|
||||
{
|
||||
public async Task<List<WuziMuluOptionDto>> Handle(GetYuanliaoZhuangkouWuziOptionsQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetWuziOptionsAsync(query.Keyword);
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
using F9WebAiTest.Application.Common.Exceptions;
|
||||
using F9WebAiTest.Application.Interfaces.SnowflakeID;
|
||||
using F9WebAiTest.Domain.Entities.SYS.Zq;
|
||||
using F9WebAiTest.Domain.Interfaces.SYS.Zq;
|
||||
using MediatR;
|
||||
|
||||
namespace F9WebAiTest.Application.CQRS.SYS.Zq.Commands;
|
||||
|
||||
/// <summary>新增账期</summary>
|
||||
public record Zhangqi_CreateCommand(int Year, int Month, DateTime StartDate, DateTime EndDate) : IRequest<long>;
|
||||
|
||||
public class CreateZhangqiCommandHandler(
|
||||
IZhangqiWriteRepository zhangqiRepository,
|
||||
ISnowflakeIdGenerator snowflakeIdGenerator,
|
||||
IPublisher eventBus) : IRequestHandler<Zhangqi_CreateCommand, long>
|
||||
{
|
||||
public async Task<long> Handle(Zhangqi_CreateCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
if (command.StartDate > command.EndDate) throw new F9OperationException("开始日期不能大于截止日期");
|
||||
|
||||
var entity = new Zhangqi(snowflakeIdGenerator.CreateId(), command.Year, command.Month,
|
||||
command.StartDate, command.EndDate);
|
||||
|
||||
var result = await zhangqiRepository.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 Zhangqi_UpdateCommand(long Id, int Year, int Month, DateTime StartDate, DateTime EndDate) : IRequest<bool>;
|
||||
|
||||
public class UpdateZhangqiCommandHandler(
|
||||
IZhangqiWriteRepository zhangqiRepository,
|
||||
IPublisher eventBus) : IRequestHandler<Zhangqi_UpdateCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(Zhangqi_UpdateCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
if (command.StartDate > command.EndDate) throw new F9OperationException("开始日期不能大于截止日期");
|
||||
|
||||
var entity = await zhangqiRepository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("账期不存在");
|
||||
|
||||
if (entity.IsZhaZhang) throw new F9OperationException("账期已扎帐,请先取消扎帐后再修改");
|
||||
|
||||
entity.Update(command.Year, command.Month, command.StartDate, command.EndDate);
|
||||
|
||||
var result = await zhangqiRepository.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 Zhangqi_DelCommand(long Id) : IRequest<bool>;
|
||||
|
||||
public class DelZhangqiCommandHandler(
|
||||
IZhangqiWriteRepository zhangqiRepository,
|
||||
IPublisher eventBus) : IRequestHandler<Zhangqi_DelCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(Zhangqi_DelCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await zhangqiRepository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("账期不存在");
|
||||
|
||||
if (entity.IsZhaZhang) throw new F9OperationException("账期已扎帐,请先取消扎帐后再删除");
|
||||
|
||||
var result = await zhangqiRepository.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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>扎帐 / 取消扎帐(扎帐后账期内业务数据禁止修改)</summary>
|
||||
public record Zhangqi_ZhaZhangCommand(long Id, bool IsZhaZhang) : IRequest<bool>;
|
||||
|
||||
public class ZhaZhangCommandHandler(
|
||||
IZhangqiWriteRepository zhangqiRepository,
|
||||
IPublisher eventBus) : IRequestHandler<Zhangqi_ZhaZhangCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(Zhangqi_ZhaZhangCommand command, CancellationToken cancellationToken)
|
||||
{
|
||||
var entity = await zhangqiRepository.GetByIdAsync(command.Id, cancellationToken)
|
||||
?? throw new F9NotFoundException("账期不存在");
|
||||
|
||||
if (entity.IsZhaZhang == command.IsZhaZhang)
|
||||
throw new F9OperationException(command.IsZhaZhang ? "该账期已扎帐" : "该账期未扎帐");
|
||||
|
||||
entity.SetZhaZhang(command.IsZhaZhang);
|
||||
|
||||
var result = await zhangqiRepository.SetZhaZhangAsync(command.Id, command.IsZhaZhang);
|
||||
if (result == false) throw new F9OperationException(command.IsZhaZhang ? "扎帐" : "取消扎帐", "操作");
|
||||
|
||||
foreach (var de in entity.DomainEvents) await eventBus.Publish(de, cancellationToken);
|
||||
entity.ClearDomainEvents();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using F9WebAiTest.Application.Common;
|
||||
using F9WebAiTest.Application.Dtos.SYS.Zq;
|
||||
using F9WebAiTest.Application.Interfaces.Repositories.SYS.Zq;
|
||||
using F9WebAiTest.Application.Interfaces.SnowflakeID;
|
||||
using F9WebAiTest.Domain.Entities.SYS.Zq;
|
||||
using F9WebAiTest.Domain.Interfaces.SYS.Zq;
|
||||
using MediatR;
|
||||
|
||||
namespace F9WebAiTest.Application.CQRS.SYS.Zq.Queries;
|
||||
|
||||
/// <summary>账期分页查询(按年度筛选)</summary>
|
||||
public record GetZhangqiPagedQuery(int? Year = null, string Keyword = "", int PageIndex = 1, int PageSize = 20)
|
||||
: IRequest<PageResult<ZhangqiReadDto_View>>;
|
||||
|
||||
public class GetZhangqiPagedQueryHandler(IZhangqiReadRepository readRepository)
|
||||
: IRequestHandler<GetZhangqiPagedQuery, PageResult<ZhangqiReadDto_View>>
|
||||
{
|
||||
public async Task<PageResult<ZhangqiReadDto_View>> Handle(GetZhangqiPagedQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetPagedAsync(query.Year, query.Keyword, query.PageIndex, query.PageSize);
|
||||
}
|
||||
|
||||
/// <summary>按 Id 查询账期(编辑回显)</summary>
|
||||
public record GetZhangqiByIdQuery(long Id) : IRequest<ZhangqiReadDto_Edit>;
|
||||
|
||||
public class GetZhangqiByIdQueryHandler(IZhangqiReadRepository readRepository)
|
||||
: IRequestHandler<GetZhangqiByIdQuery, ZhangqiReadDto_Edit>
|
||||
{
|
||||
public async Task<ZhangqiReadDto_Edit> Handle(GetZhangqiByIdQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetByIdForEditAsync(query.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按日期取所属账期:不存在时按"每月 28 日"划分规则自动创建
|
||||
/// (日期 ≤ 28 号:上月 29 日 ~ 本月 28 日;日期 > 28 号:本月 29 日 ~ 下月 28 日)。
|
||||
/// </summary>
|
||||
public record GetZhangqiByDateQuery(DateTime Date) : IRequest<ZhangqiReadDto_Edit>;
|
||||
|
||||
public class GetZhangqiByDateQueryHandler(
|
||||
IZhangqiReadRepository readRepository,
|
||||
IZhangqiWriteRepository writeRepository,
|
||||
ISnowflakeIdGenerator snowflakeIdGenerator) : IRequestHandler<GetZhangqiByDateQuery, ZhangqiReadDto_Edit>
|
||||
{
|
||||
public async Task<ZhangqiReadDto_Edit> Handle(GetZhangqiByDateQuery query, CancellationToken ct)
|
||||
{
|
||||
var exist = await readRepository.GetByDateAsync(query.Date);
|
||||
if (exist != null) return exist;
|
||||
|
||||
var (startDate, endDate) = CalcRange(query.Date);
|
||||
|
||||
var entity = new Zhangqi(snowflakeIdGenerator.CreateId(), endDate.Year, endDate.Month, startDate, endDate);
|
||||
await writeRepository.AddAsync(entity);
|
||||
|
||||
return new ZhangqiReadDto_Edit(entity.Id, entity.Year, entity.Month, entity.StartDate, entity.EndDate, entity.IsZhaZhang);
|
||||
}
|
||||
|
||||
/// <summary>按 28 日边界推算账期区间(截止日期取当天 23:59:59)</summary>
|
||||
private static (DateTime StartDate, DateTime EndDate) CalcRange(DateTime date)
|
||||
{
|
||||
DateTime startDate;
|
||||
DateTime endDay;
|
||||
|
||||
if (date.Day <= 28)
|
||||
{
|
||||
var lastMonth = date.AddMonths(-1);
|
||||
startDate = new DateTime(lastMonth.Year, lastMonth.Month, 28).AddDays(1);
|
||||
endDay = new DateTime(date.Year, date.Month, 28);
|
||||
}
|
||||
else
|
||||
{
|
||||
var nextMonth = date.AddMonths(1);
|
||||
startDate = new DateTime(date.Year, date.Month, 28).AddDays(1);
|
||||
endDay = new DateTime(nextMonth.Year, nextMonth.Month, 28);
|
||||
}
|
||||
|
||||
return (startDate, endDay.Date.AddDays(1).AddSeconds(-1));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>指定年月是否已扎帐</summary>
|
||||
public record GetZhangqiIsZhaZhangQuery(int Year, int Month) : IRequest<bool>;
|
||||
|
||||
public class GetZhangqiIsZhaZhangQueryHandler(IZhangqiReadRepository readRepository)
|
||||
: IRequestHandler<GetZhangqiIsZhaZhangQuery, bool>
|
||||
{
|
||||
public async Task<bool> Handle(GetZhangqiIsZhaZhangQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetIsZhaZhangAsync(query.Year, query.Month);
|
||||
}
|
||||
|
||||
/// <summary>指定日期所属账期是否已扎帐</summary>
|
||||
public record GetZhangqiIsZhaZhangByDateQuery(DateTime Date) : IRequest<bool>;
|
||||
|
||||
public class GetZhangqiIsZhaZhangByDateQueryHandler(IZhangqiReadRepository readRepository)
|
||||
: IRequestHandler<GetZhangqiIsZhaZhangByDateQuery, bool>
|
||||
{
|
||||
public async Task<bool> Handle(GetZhangqiIsZhaZhangByDateQuery query, CancellationToken ct)
|
||||
=> await readRepository.GetIsZhaZhangByDateAsync(query.Date);
|
||||
}
|
||||
Reference in New Issue
Block a user