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#

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 TaskBaseTypeEnum[] AuditTypes = [TaskBaseTypeEnum.APPLICATION_PAYMENT_AUDIT];
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();
}
}
}