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.3 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.Interface;
using DS.WMS.Core.Op.Dtos.TaskInteraction;
using DS.WMS.Core.Op.Interface.TaskInteraction;
using Masuit.Tools.Systems;
using Microsoft.Extensions.DependencyInjection;
namespace DS.WMS.Core.Application.Method
{
/// <summary>
/// 申请单审核服务
/// </summary>
public abstract class ApplicationAuditService<TEntity> : FeeServiceBase, IApplicationAuditService<TEntity>
where TEntity : ApplicationForm, new()
{
/// <summary>
/// 适用于当前申请单的审核类型
/// </summary>
public abstract TaskBaseTypeEnum AuditType { get; }
readonly IClientFlowInstanceService flowService;
readonly ITaskService taskService;
/// <summary>
/// 初始化
/// </summary>
/// <param name="serviceProvider"></param>
public ApplicationAuditService(IServiceProvider serviceProvider) : base(serviceProvider)
{
flowService = serviceProvider.GetRequiredService<IClientFlowInstanceService>();
taskService = serviceProvider.GetRequiredService<ITaskService>();
}
/// <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([AuditType]).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
}).ToListAsync();
if (apps.Count == 0)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.EmptyData));
var result = PreAudit(apps);
if (!result.Succeeded)
return result;
bool hasAuthorized = await taskService.HasAuthorizedAsync();
if (hasAuthorized)
{
result = await taskService.AuditAsync(new TaskAuditRequest
{
Ids = request.Ids,
Remark = request.Remark,
Result = request.Result,
TaskTypeName = AuditType.ToString()
});
if (!result.Succeeded)
return result;
}
else
{
var flows = await flowService.GetInstanceByBSIdAsync(AuditType, null, request.Ids);
if (flows.Count != request.Ids.Length)
return DataResult.FailedWithDesc(nameof(MultiLanguageConst.FlowNotFound));
List<string> list = [];
foreach (var item in flows)
{
result = flowService.AuditFlowInstance(new FlowAuditInfo
{
Instance = item,
Status = request.Result,
AuditNote = request.Remark
});
if (!result.Succeeded)
return result;
}
}
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)
{
if (callback.AuditType != AuditType)
return DataResult.Failed($"回调工作流类型:{callback.AuditType.GetDescription()} 与实例工作流类型:{AuditType.GetDescription()} 不一致");
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
}).ExecuteCommandAsync();
}
}
}