You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
8.0 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using DS.Module.Core;
using DS.WMS.Core.Application.Entity;
using DS.WMS.Core.Application.Interface;
using DS.WMS.Core.Fee.Dtos;
using DS.WMS.Core.Fee.Method;
using DS.WMS.Core.Flow.Dtos;
using DS.WMS.Core.Flow.Entity;
using DS.WMS.Core.Flow.Interface;
using Microsoft.Extensions.DependencyInjection;
namespace DS.WMS.Core.Application.Method
{
/// <summary>
/// 申请单审核服务
/// </summary>
public class ApplicationAuditService<TEntity> : FeeServiceBase, IApplicationAuditService<TEntity>
where TEntity : ApplicationForm, new()
{
internal static readonly string[] AuditTypes = [AuditType.PaidApplication.ToString()];
readonly IClientFlowInstanceService flowService;
/// <summary>
/// 初始化
/// </summary>
/// <param name="serviceProvider"></param>
public ApplicationAuditService(IServiceProvider serviceProvider) : base(serviceProvider)
{
flowService = serviceProvider.GetRequiredService<IClientFlowInstanceService>();
}
/// <summary>
/// 一键审核当前登录用户的所有待审核项
/// </summary>
/// <param name="yesOrNo">审批结果1=通过2=驳回</param>
/// <param name="remark">备注</param>
/// <returns></returns>
public async Task<DataResult> AuditAsync(int yesOrNo, string? remark)
{
var recordIds = await GetCurrentFlowsQuery(AuditTypes).Select(x => x.BusinessId).ToArrayAsync();
//没有待审批的列表直接返回不再执行后续查询
if (recordIds.Length == 0)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NoAuditItems));
return await AuditAsync(new AuditRequest { Ids = recordIds, Remark = remark, Result = yesOrNo });
}
/// <summary>
/// 申请单审核
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<DataResult> AuditAsync(AuditRequest request)
{
var apps = await TenantDb.Queryable<TEntity>().Where(x => request.Ids.Contains(x.Id)).Select(x => new TEntity
{
Id = x.Id,
ApplicationNO = x.ApplicationNO,
Status = x.Status,
FlowId = x.FlowId
}).ToListAsync();
if (apps.Count == 0)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData));
if (apps.Exists(x => !x.FlowId.HasValue))
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.NotInFlows));
var result = PreAudit(apps);
if (!result.Succeeded)
return result;
var flowIds = apps.Select(x => x.FlowId.GetValueOrDefault());
var flows = await Db.Queryable<FlowInstance>().Where(x => flowIds.Contains(x.Id)).ToListAsync();
if (flows.Count == 0)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.FlowNotFound));
if (flows.Exists(x => !x.MakerList.Contains(User.UserId)))
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.AuditUnauthorization));
List<string> list = [];
foreach (var app in apps)
{
var flow = flows.Find(x => x.Id == app.FlowId.Value);
if (flow == null)
continue;
result = flowService.AuditFlowInstance(new FlowAuditInfo
{
Instance = flow,
Status = request.Result,
AuditNote = request.Remark
});
if (!result.Succeeded)
list.Add(app.ApplicationNO);
}
if (list.Count > 0)
return DataResult.Failed($"{MultiLanguageConst.Operation_Failed}{string.Join("", list)}");
return DataResult.Success;
}
/// <summary>
/// 在执行审批前调用,用于检查申请单状态
/// </summary>
/// <param name="applications">申请单</param>
/// <returns></returns>
protected virtual DataResult PreAudit(List<TEntity> applications)
{
return DataResult.Success;
}
/// <summary>
/// 将申请单重置为未打印状态
/// </summary>
/// <param name="ids">申请单ID</param>
/// <returns></returns>
public async Task<DataResult> SetUnPrinted(params long[] ids)
{
if (typeof(TEntity).IsSubclassOf(typeof(ApplicationForm)))
throw new NotSupportedException($"不支持的类型,泛型参数需要继承自类:{typeof(ApplicationForm).AssemblyQualifiedName}");
int rows = await TenantDb.Updateable<TEntity>()
.SetColumns(nameof(ApplicationForm.IsPrinted), false)
.SetColumns(nameof(ApplicationForm.PrintTimes), 0)
.SetColumns(nameof(ApplicationForm.PrinterId), null)
.SetColumns(nameof(ApplicationForm.PrinterName), null)
.SetColumns(nameof(ApplicationForm.PrintTime), null)
.Where(x => ids.Contains(x.Id)).ExecuteCommandAsync();
return rows > 0 ? DataResult.Success : DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
/// <summary>
/// 根据审批结果更新申请单状态
/// </summary>
/// <param name="callback">回调信息</param>
/// <returns></returns>
public async Task<DataResult> UpdateStatusAsync(FlowCallback callback)
{
var app = await TenantDb.Queryable<TEntity>().Where(x => x.Id == callback.BusinessId)
.Select(x => new TEntity
{
Id = x.Id,
Status = x.Status
}).FirstAsync();
if (app == null)
{
await new ApplicationException($"未能获取ID={callback.BusinessId}的申请单,回调更新失败").LogAsync(Db);
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData));
}
DateTime dtNow = DateTime.Now;
app.AuditerId = long.Parse(User.UserId);
app.AuditerName = User.UserName;
app.AuditTime = dtNow;
app.Reason = callback.RejectReason;
await TenantDb.Ado.BeginTranAsync();
try
{
await OnUpdateStatusAsync(callback, app);
//驳回申请则逻辑删除关联工作流
if (callback.FlowStatus == FlowStatusEnum.Reject)
{
await Db.Updateable(new FlowInstance
{
Id = callback.InstanceId,
Deleted = true,
DeleteBy = 0,
DeleteTime = DateTime.Now
}).UpdateColumns(x => new { x.Deleted, x.DeleteBy, x.DeleteTime }).ExecuteCommandAsync();
}
await TenantDb.Ado.CommitTranAsync();
return DataResult.Success;
}
catch (Exception ex)
{
await TenantDb.Ado.RollbackTranAsync();
await ex.LogAsync(Db);
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.Operation_Failed));
}
}
/// <summary>
/// 在审批完成时调用,用于更新申请单的审批状态
/// </summary>
/// <param name="callback">回调参数</param>
/// <param name="application">申请单</param>
/// <returns></returns>
protected virtual async Task OnUpdateStatusAsync(FlowCallback callback, TEntity application)
{
await TenantDb.Updateable(application).UpdateColumns(x => new
{
x.Status,
x.AuditerId,
x.AuditerName,
x.AuditTime,
x.Reason,
x.FlowId
}).ExecuteCommandAsync();
}
}
}