using FlexJobApi.Core; using FlexJobApi.Core.Models; using Furion.DatabaseAccessor; using Mapster; using MediatR; using Microsoft.EntityFrameworkCore; using NetTopologySuite.Index.HPRtree; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace FlexJobApi.UserServer.Application { /// /// 合同模板查询处理器 /// public class ContractTemplateQueryHandler( IRepository rep, IRepository repEnterprise, IRepository repUser, IRepository repDbAuditLog ) : IRequestHandler, IRequestHandler, IRequestHandler, IRequestHandler { private readonly IRepository rep = rep; private readonly IRepository repEnterprise = repEnterprise; private readonly IRepository repUser = repUser; private readonly IRepository repDbAuditLog = repDbAuditLog; /// /// 查询运营端协议管理列表 /// /// /// /// public async Task Handle(GetContractTemplateEnterprisesQuery request, CancellationToken cancellationToken) { var q = repEnterprise.AsQueryable().AsNoTracking(); if (request.Keywords.IsNotNull()) { q = q.Where(it => it.EnterpriseName.Contains(request.Keywords)); } if (request.Status.HasValue) { if (request.Status == EnumContractTemplateStatus.Wait) { q = q.Where(it => it.ContractTemplates.Any(ct => ct.Status == EnumContractTemplateStatus.Wait)); } else { q = q.Where(it => it.ContractTemplates.Any() && it.ContractTemplates.All(ct => ct.Status == EnumContractTemplateStatus.Completed)); } } var s = q .Select(it => new GetContractTemplateEnterprisesQueryResultItem { Id = it.Id, EnterpriseName = it.EnterpriseName, Contacts = it.Contacts, ContactPhoneNumber = it.ContactPhoneNumber, Total = it.ContractTemplates.Count(it => !it.IsDisabled), WaitCount = it.ContractTemplates.Count(it => !it.IsDisabled && it.Status == EnumContractTemplateStatus.Wait), }); return await request.PageModel.GetPagedListAsync(s, cancellationToken); } /// /// 查询企业合同模板 /// /// /// /// public async Task Handle(GetEnterpriseContractTemplatesQuery request, CancellationToken cancellationToken) { var logier = JwtUtils.GetCurrentLogier(); if (logier.Type == EnumUserType.Enterprise) { request.EnterpriseId = logier.EnterpriseId; } var q = rep.AsQueryable().AsNoTracking() .Where(it => it.EnterpriseId == request.EnterpriseId && !it.IsDisabled); if (request.Keywords.IsNotNull()) { q = q.Where(it => it.Name.Contains(request.Keywords) || it.TemplateId.Contains(request.Keywords) || it.Code.Contains(request.Keywords)); } if (request.CreatedTimeBegin.HasValue && request.CreatedTimeEnd.HasValue) { q = q.Where(it => request.CreatedTimeBegin <= it.CreatedTime && it.CreatedTime <= request.CreatedTimeEnd); } if (request.CompletedTimeBegin.HasValue && request.CompletedTimeEnd.HasValue) { q = q.Where(it => request.CompletedTimeBegin <= it.CompletedTime && it.CreatedTime <= request.CompletedTimeEnd); } if (request.Status.HasValue) { q = q.Where(it => it.Status == request.Status); } var s = from t in q join cu in repUser.AsQueryable().AsNoTracking() on t.CreatedUserId equals cu.Id join uu in repUser.AsQueryable().AsNoTracking() on t.UpdatedUserId equals uu.Id into uug from uugi in uug.DefaultIfEmpty() select new GetEnterpriseContractTemplatesQueryResultItem { Id = t.Id, Name = t.Name, CreatedTime = t.CreatedTime, TemplateId = t.TemplateId, Access = t.Access, Code = t.Code, File = t.File, Status = t.Status, CompletedTime = t.CompletedTime, Operator = uugi == null ? cu.Name : uugi.Name }; return await request.PageModel.GetPagedListAsync(s, cancellationToken); } /// /// 查询企业合同模板日志分页列表数据 /// /// /// /// public async Task Handle(GetEnterpriseContractTemplateLogsQuery request, CancellationToken cancellationToken) { var tableName = nameof(ContractTemplate); var q = repDbAuditLog.AsQueryable().AsNoTracking() .Where(it => it.TableName == tableName && it.PrimaryKey == request.Id) .ProjectToType(); var result = await request.PageModel.GetPagedListAsync(q, cancellationToken); if (result.Data.IsNotNull()) { var type = typeof(ContractTemplate); var xmlDoc = await XmlDocUtils.GetXmlDocAsync(); var ignorePropertyNames = new List { "Id", "EnterpriseId", "IsDisabled", "Sort", "TraceId", "CreatedTime", "CreatedUserId", "CreatedEnterpriseId", "UpdatedTime", "UpdatedUserId", "IsDeleted", "Values", "TemplateId", }; var properties = type.GetProperties().Where(it => !ignorePropertyNames.Contains(it.Name)).ToList(); var traceIds = result.Data.DistinctSelect(it => it.TraceId); tableName = nameof(ContractTemplateValue); var valueType = typeof(ContractTemplateValue); var valueProperties = valueType.GetProperties().Where(it => !ignorePropertyNames.Contains(it.Name)).ToList(); var valueLogs = await repDbAuditLog.AsQueryable().AsNoTracking() .Where(it => it.TableName == tableName && traceIds.Contains(it.TraceId)) .Select(it => new GetEnterpriseContractTemplateLogsQueryResultItem { TraceId = it.TraceId, Operate = it.Operate, OldValues = it.OldValues, NewValues = it.NewValues }) .ToListAsync(); var userIds = result.Data.DistinctSelect(it => it.CreatedUserId); var users = await repUser.AsQueryable().AsNoTracking() .Where(it => userIds.Contains(it.Id)) .Select(it => new { it.Id, it.Name }) .ToListAsync(); foreach (var item in result.Data) { item.CreatedUser = users.FirstOrDefault(it => it.Id == item.CreatedUserId)?.Name; await AddContractTemplateLogsAsync(item, properties, xmlDoc); var traceValueLogs = valueLogs.Where(it => it.TraceId == item.TraceId).ToList(); await AddContractTemplateValueLogsAsync(item, traceValueLogs, valueProperties, xmlDoc); } } return result; } /// /// 查询合同模板详情 /// /// /// /// public async Task Handle(GetContractTemplateQuery request, CancellationToken cancellationToken) { return await rep.AsQueryable().AsNoTracking() .Where(it => it.Id == request.Id) .GetDetail(cancellationToken); } private async Task AddContractTemplateLogsAsync( GetEnterpriseContractTemplateLogsQueryResultItem item, List properties, XmlDoc xmlDoc) { var oldEntity = item.OldValues?.JsonTo(); var newEntity = item.NewValues?.JsonTo(); foreach (var property in properties) { var propertySummary = await property.GetXmlDocMemberAsync(xmlDoc); var oldValue = await GetLogValue(oldEntity, property, xmlDoc); var newValue = await GetLogValue(newEntity, property, xmlDoc); if (item.Operate == EnumDbAuditOperate.Added && newValue != null) { item.Content.Add($"{propertySummary?.Summary ?? property.Name}:{newValue}"); } else if (item.Operate == EnumDbAuditOperate.Modified && oldValue != newValue) { item.Content.Add($"{propertySummary?.Summary ?? property.Name}:由 {oldValue} 改为 {newValue}"); } } } private async Task AddContractTemplateValueLogsAsync( GetEnterpriseContractTemplateLogsQueryResultItem item, List traceValueLogs, List properties, XmlDoc xmlDoc) { foreach (var traceValueLog in traceValueLogs) { var oldEntity = traceValueLog.OldValues?.JsonTo(); var newEntity = traceValueLog.NewValues?.JsonTo(); if (traceValueLog.Operate == EnumDbAuditOperate.Added) { item.Content.Add("新增变量:"); } else if (traceValueLog.Operate == EnumDbAuditOperate.Modified) { item.Content.Add("编辑变量:"); } foreach (var property in properties) { var propertySummary = await property.GetXmlDocMemberAsync(xmlDoc); var oldValue = await GetLogValue(oldEntity, property, xmlDoc); var newValue = await GetLogValue(newEntity, property, xmlDoc); if (traceValueLog.Operate == EnumDbAuditOperate.Added && newValue != null) { item.Content.Add($"--{propertySummary?.Summary ?? property.Name}:{newValue}"); } else if (traceValueLog.Operate == EnumDbAuditOperate.Modified && oldValue != newValue) { item.Content.Add($"--{propertySummary?.Summary ?? property.Name}:由 {oldValue} 改为 {newValue}"); } } if (traceValueLog.Operate == EnumDbAuditOperate.Deleted) { var property = properties.First(it => it.Name == nameof(ContractTemplateValue.Label)); var oldValue = oldEntity != null ? property.GetValue(oldEntity) : null; var propertySummary = await property.GetXmlDocMemberAsync(xmlDoc); item.Content.Add($"删除变量:{oldValue}"); } } } private async Task GetLogValue(object? entity, PropertyInfo property, XmlDoc xmlDoc) { if (entity == null) return null; var propertyType = property.PropertyType; if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) { propertyType = propertyType.GetGenericArguments()[0]; } var value = property.GetValue(entity); if (propertyType.IsEnum && value != null) { var model = await propertyType.GetModel(); var item = model.Items.FirstOrDefault(it => it.Value == (int)value); return item?.Description; } else if (value is bool boolValue) { return boolValue ? "是" : "否"; } else { return value?.ToString(); } } } }