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 { /// /// 申请单审核服务 /// public class ApplicationAuditService : FeeServiceBase, IApplicationAuditService where TEntity : ApplicationForm, new() { internal static readonly string[] AuditTypes = [AuditType.PaidApplication.ToString()]; readonly IClientFlowInstanceService flowService; /// /// 初始化 /// /// public ApplicationAuditService(IServiceProvider serviceProvider) : base(serviceProvider) { flowService = serviceProvider.GetRequiredService(); } /// /// 一键审核当前登录用户的所有待审核项 /// /// 审批结果:1=通过,2=驳回 /// 备注 /// public async Task 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 }); } /// /// 申请单审核 /// /// /// public async Task AuditAsync(AuditRequest request) { var apps = await TenantDb.Queryable().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().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 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; } /// /// 在执行审批前调用,用于检查申请单状态 /// /// 申请单 /// protected virtual DataResult PreAudit(List applications) { return DataResult.Success; } /// /// 将申请单重置为未打印状态 /// /// 申请单ID /// public async Task SetUnPrinted(params long[] ids) { if (typeof(TEntity).IsSubclassOf(typeof(ApplicationForm))) throw new NotSupportedException($"不支持的类型,泛型参数需要继承自类:{typeof(ApplicationForm).AssemblyQualifiedName}"); int rows = await TenantDb.Updateable() .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)); } /// /// 根据审批结果更新申请单状态 /// /// 回调信息 /// public async Task UpdateStatusAsync(FlowCallback callback) { var app = await TenantDb.Queryable().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)); } } /// /// 在审批完成时调用,用于更新申请单的审批状态 /// /// 回调参数 /// 申请单 /// 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(); } } }