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.

220 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 : ApplicationBase, 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.Failed("当前暂无待审批的费用");
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.Failed("未能获取申请单信息");
if (apps.Exists(x => !x.FlowId.HasValue))
return DataResult.Failed("提交数据中包含不在审批流程中的申请单");
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 (apps.Count == 0)
return DataResult.Failed("未能获取审批工作流");
if (flows.Exists(x => !x.MakerList.Contains(User.UserId)))
return DataResult.Failed("所选申请单包含不属于当前用户权限范围内的审批,禁止提交");
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($"下列申请单审批失败:{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)
{
var list = ids.Select(x => new TEntity
{
Id = x,
IsPrinted = false,
PrintTimes = 0,
//PrinterId = null,
//PrinterName = null,
//PrintTime = null
}).ToList();
int rows = await TenantDb.Updateable(list).UpdateColumns(x => new
{
x.IsPrinted,
x.PrintTimes,
x.PrinterId,
x.PrinterName,
x.PrintTime
}).ExecuteCommandAsync();
return rows > 0 ? DataResult.Success : DataResult.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.Failed("无法获取申请单信息,回调更新失败");
}
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.Successed("提交成功!", MultiLanguageConst.DataUpdateSuccess);
}
catch (Exception ex)
{
await TenantDb.Ado.RollbackTranAsync();
await ex.LogAsync(Db);
return DataResult.Failed("提交失败!", 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();
}
}
}