sunpengfei
2025-08-07 7d64d742e52809237473e13e18faec2c23dfe3c7
FlexJobApi.Application/Dictionaries/Commands/DictionaryDataCommandHandler.cs
@@ -1,7 +1,15 @@
using FlexJobApi.Core;
using Consul;
using EFCore.BulkExtensions;
using FlexJobApi.Core;
using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.FriendlyException;
using Mapster;
using MediatR;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -11,25 +19,66 @@
    /// <summary>
    /// 数据字典命令处理器
    /// </summary>
    public class DictionaryDataCommandHandler :
    public class DictionaryDataCommandHandler(
            IRepository<DictionaryData> rep,
            IRepository<DictionaryCategory> repDictionaryCategory
        ) :
        IRequestHandler<SaveDictionaryDataCommand, Guid>,
        IRequestHandler<SetDictionaryDataIsDisabledCommand, int>
        IRequestHandler<SetDictionaryDataIsDisabledCommand, int>,
        IRequestHandler<SyncHumanResourcesAreaDictionaryDataCommand, int>
    {
        private readonly IRepository<DictionaryData> rep = rep;
        private readonly IRepository<DictionaryCategory> repDictionaryCategory = repDictionaryCategory;
        /// <summary>
        /// 保存数据字典
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public Task<Guid> Handle(SaveDictionaryDataCommand request, CancellationToken cancellationToken)
        public async Task<Guid> Handle(SaveDictionaryDataCommand request, CancellationToken cancellationToken)
        {
            return request.SaveData<DictionaryData, SaveDictionaryDataCommand>(
                (q, e, r) => q.Any(it =>
            var category = await repDictionaryCategory
                .Where(it => it.Id == request.CategoryId || it.Code == request.CategoryCode)
                .Select(it => new
                {
                    it.Id,
                    it.Code
                })
                .FirstOrDefaultAsync();
            if (category == null) throw Oops.Oh(EnumErrorCodeType.s404, "数据字典类别");
            request.CategoryId = category.Id;
            if (!request.Code.StartsWith($"{category.Code}-")) throw Oops.Oh(EnumErrorCodeType.s400, "编号开头需要包含类别编号-");
            var parent = request.ParentId.HasValue
                ? await rep.AsQueryable().AsNoTracking()
                    .FirstOrDefaultAsync(it => it.Id == request.ParentId)
                : null;
            return await request.SaveData<DictionaryData, SaveDictionaryDataCommand>(
                null,
                it =>
                    it.CategoryId == request.CategoryId
                    && it.ParentId == request.ParentId
                    && it.Code == request.Code
                    && it.Content == request.Content), cancellationToken);
                    && it.Id != request.Id,
                (entity) =>
                {
                    entity.Path = DbUtils.GetTreeDataPath<DictionaryData>(request.ParentId, cancellationToken).Result;
                    if (request.Id.HasValue)
                    {
                        if (entity.Code != request.Code) throw Oops.Oh(EnumErrorCodeType.s400, "编号不可修改");
                        if (entity.ParentId != request.ParentId) throw Oops.Oh(EnumErrorCodeType.s400, "上级Id不可修改");
                        //DbUtils.UpdateTreeDataChildrenPath<DictionaryData>(
                        //   $"{entity.Path}/{entity.Code}/",
                        //   $"{entity.Path}/{request.Code}/",
                        //   cancellationToken).Wait();
                    }
                    else
                    {
                        entity.Deep = request.ParentId == null ? 1 : parent.Deep + 1;
                    }
                    request.Adapt(entity);
                },
                cancellationToken);
        }
        /// <summary>
@@ -40,7 +89,84 @@
        /// <returns></returns>
        public Task<int> Handle(SetDictionaryDataIsDisabledCommand request, CancellationToken cancellationToken)
        {
            return request.SetIsDisable<DictionaryData>(cancellationToken: cancellationToken);
            return request.SetIsDisabled<DictionaryData>(cancellationToken: cancellationToken);
        }
        /// <summary>
        /// 同步人力资源地区字典数据
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<int> Handle(SyncHumanResourcesAreaDictionaryDataCommand request, CancellationToken cancellationToken)
        {
            var repHumanResourcesBaseArea = Db.GetRepository<BaseArea, HumanResourcesDbContextLocator>();
            var areas = await repHumanResourcesBaseArea.AsQueryable().AsNoTracking()
                .OrderBy(it => it.AreaCode)
                .ToListAsync();
            var entities = new List<DictionaryData>();
            var categoryId = new Guid("B21FE000-BB7F-4498-08E9-08DDD572EF73");
            await "DELETE FROM DictionaryData WHERE CategoryId = @CategoryId".SqlNonQueryAsync(new
            {
                CategoryId = categoryId
            });
            var parentAreas = areas.Where(it => it.ParentId == 0).ToList();
            LoopSyncHumanResourcesAreaDictionaryData(categoryId, entities, areas, parentAreas);
            await rep.Context.BulkInsertAsync(entities);
            return entities.Count;
        }
        /// <summary>
        /// 递归同步人力资源地区字典数据
        /// </summary>
        /// <param name="categoryId"></param>
        /// <param name="entities"></param>
        /// <param name="all"></param>
        /// <param name="areas"></param>
        /// <param name="deep"></param>
        private void LoopSyncHumanResourcesAreaDictionaryData(Guid categoryId, List<DictionaryData> entities, List<BaseArea> all, List<BaseArea> areas, int deep = 1)
        {
            if (areas.IsNotNull())
            {
                foreach (var area in areas)
                {
                    var entity = new DictionaryData();
                    entity.CategoryId = categoryId;
                    entity.Id = area.Id;
                    if (area.ParentId != 0)
                    {
                        var parent = entities.FirstOrDefault(it => it.Field1 == area.ParentId.ToString());
                        if (parent == null)
                        {
                            var parentArea = areas.FirstOrDefault(it => it.AreaCode == area.ParentId);
                            if (parentArea != null)
                            {
                                throw Oops.Oh(EnumErrorCodeType.s404, "上级地区");
                            }
                            continue;
                        }
                        entity.ParentId = parent.Id;
                        entity.Path = $"{parent.Path}{parent.Code}/";
                    }
                    else
                    {
                        entity.Path = "/";
                    }
                    entity.Code = $"70-{area.AreaCode}";
                    entity.Content = area.AreaName;
                    entity.Field1 = area.AreaCode.ToString();
                    entity.Field2 = area.QuickQuery;
                    entity.Field3 = area.SimpleSpelling;
                    entity.Field4 = area.Layer.ToString();
                    entity.Field5 = area.Description;
                    entity.Deep = deep;
                    entity.Sort = area.Sort ?? 0;
                    entities.Add(entity);
                    var children = all.Where(it => it.ParentId == area.AreaCode).ToList();
                    LoopSyncHumanResourcesAreaDictionaryData(categoryId, entities, all, children, deep + 1);
                }
            }
        }
    }
}