|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|