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)
{
var model = await rep.AsQueryable().AsNoTracking()
.Where(it => it.Id == request.Id)
.GetDetail(cancellationToken);
model.IsEnterpriseUserCreated = await repUser.AsQueryable().AsNoTracking()
.Where(it => it.Id == model.CreatedUserId)
.Select(it => it.Type == EnumUserType.Enterprise)
.FirstOrDefaultAsync();
return model;
}
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();
}
}
}
}