本票审核

usertest
嵇文龙 6 months ago
parent b5b9eb693b
commit d9db8f5e47

@ -336,6 +336,7 @@ namespace DS.WMS.Core.Fee.Dtos
////public string ProfitReduction { get; set; }
}
public class FeeAudit
{
/// <summary>
@ -417,7 +418,6 @@ namespace DS.WMS.Core.Fee.Dtos
/// </summary>
public string Remark { get; set; }
/// <summary>
/// Desc:佣金比率
/// </summary>

@ -19,8 +19,28 @@ namespace DS.WMS.Core.Fee.Dtos
/// </summary>
public long[] Ids { get; set; }
public long? Id { get; set; }
public BusinessType BusinessType { get; set; }
}
public class FeeBizAuditRequest
{
/// <summary>
/// 审核结果1=通过2=驳回
/// </summary>
public int Result { get; set; }
/// <summary>
/// 审批备注
/// </summary>
public string Remark { get; set; }
public List<BizAudit> Items { get; set; }
}
public class BizAudit
{
public long Id { get; set; }
public BusinessType BusinessType { get; set; } = BusinessType.OceanShippingExport;
public BusinessType BusinessType { get; set; }
}
}

@ -26,11 +26,26 @@ namespace DS.WMS.Core.Fee.Interface
/// <returns></returns>
DataResult Audit(int yesOrNo, string remark, params long[] idArray);
/// <summary>
/// 本票审核(一键审核当前登录用户的所有待审核项)
/// </summary>
/// <param name="yesOrNo">审批结果1=通过2=驳回</param>
/// <param name="remark">备注</param>
/// <returns></returns>
DataResult AuditBusiness(int yesOrNo, string remark);
/// <summary>
/// 整单费用状态审核
/// </summary>
/// <param name="request"></param>
DataResult AuditBusiness(FeeBizAuditRequest request);
/// <param name="id">业务ID</param>
/// <param name="businessType">业务类型</param>
/// <summary>
/// 设置业务费用锁定状态
/// </summary>
/// <param name="items">业务信息</param>
/// <returns></returns>
DataResult AuditBusiness(int yesOrNo, string remark, long id, BusinessType businessType);
DataResult SetFeeLocking(IEnumerable<BusinessFeeStatus> items);
/// <summary>
/// 根据审批结果更新审批状态

@ -21,8 +21,14 @@ namespace DS.WMS.Core.Fee.Method
/// </summary>
public class FeeAuditService : IFeeAuditService
{
//待审核的状态值
/// <summary>
/// 待审核的状态值
/// </summary>
public static readonly FeeStatus[] AuditStatusArray = [FeeStatus.AuditSubmitted, FeeStatus.ApplyDeletion, FeeStatus.ApplyModification];
/// <summary>
/// 工作流运行状态值
/// </summary>
public static readonly int RunningStatus = (int)FlowStatusEnum.Running;
readonly IServiceProvider _serviceProvider;
@ -54,10 +60,43 @@ namespace DS.WMS.Core.Fee.Method
DataResult<List<FeeAuditBusiness>>.PageList(0, null, MultiLanguageConst.DataQuerySuccess);
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var queryList = GetDataQuery(tenantDb);
var bidList = flowList.Select(x => x.BusinessId);
queryList = queryList.Where(x => bidList.Contains(x.Id));
List<IConditionalModel> whereList = null;
if (!request.QueryCondition.IsNullOrEmpty())
whereList = db.ConfigQuery.Context.Utilities.JsonToConditionalModels(request.QueryCondition);
if (whereList != null)
queryList = queryList.Where(whereList);
var result = queryList.ToQueryPage(request.PageCondition);
if (result.Data.Count > 0)
{
//关联用户名称
var userIds = result.Data.Where(x => x.OperatorId.HasValue).Select(x => x.OperatorId.Value)
.Union(result.Data.Select(x => x.CreateBy))
.Distinct();
var users = db.Queryable<SysUser>().Where(x => userIds.Contains(x.Id)).Select(x => new { x.Id, x.UserName }).ToList();
foreach (var item in result.Data)
{
item.CreateByName = users.Find(x => x.Id == item.CreateBy)?.UserName;
if (item.OperatorId.HasValue)
{
item.Operator = users.Find(x => x.Id == item.OperatorId.Value)?.UserName;
}
}
}
return result;
}
//获取各项业务数据的查询并集
internal static ISugarQueryable<FeeAuditBusiness> GetDataQuery(SqlSugarScopeProvider tenantDb)
{
//海运出口
var query1 = tenantDb.Queryable<SeaExport, BusinessFeeStatus, FeeRecord>((s, b, f) => new JoinQueryInfos(
JoinType.Left, s.Id == b.BusinessId && b.BusinessType == BusinessType.OceanShippingExport,
@ -121,35 +160,9 @@ namespace DS.WMS.Core.Fee.Method
Yard = s.Yard
});
var queryList = tenantDb.UnionAll(new List<ISugarQueryable<FeeAuditBusiness>> { query1 });
var bidList = flowList.Select(x => x.BusinessId);
queryList = queryList.Where(x => bidList.Contains(x.Id));
if (whereList != null)
queryList = queryList.Where(whereList);
var result = queryList.ToQueryPage(request.PageCondition);
if (result.Data.Count > 0)
{
//关联用户名称
var userIds = result.Data.Where(x => x.OperatorId.HasValue).Select(x => x.OperatorId.Value)
.Union(result.Data.Select(x => x.CreateBy))
.Distinct();
var users = db.Queryable<SysUser>().Where(x => userIds.Contains(x.Id)).Select(x => new { x.Id, x.UserName }).ToList();
foreach (var item in result.Data)
{
item.CreateByName = users.Find(x => x.Id == item.CreateBy)?.UserName;
if (item.OperatorId.HasValue)
{
item.Operator = users.Find(x => x.Id == item.OperatorId.Value)?.UserName;
}
}
}
//海运进口
return result;
return tenantDb.UnionAll(new List<ISugarQueryable<FeeAuditBusiness>> { query1 });
}
/// <summary>
@ -180,15 +193,7 @@ namespace DS.WMS.Core.Fee.Method
return DataResult.Failed("提交数据中包含不在待审批状态的费用");
var flowIds = fees.Select(x => x.FlowId.GetValueOrDefault());
var flows = db.Queryable<FlowInstance>().Where(x => flowIds.Contains(x.Id)).Select(x => new
{
x.Id,
x.ActivityId,
x.BusinessId,
x.BusinessType,
x.MakerList
}).ToList();
var flows = db.Queryable<FlowInstance>().Where(x => flowIds.Contains(x.Id)).ToList();
if (flows.Count == 0)
return DataResult.Failed("未能获取审批工作流");
@ -204,10 +209,9 @@ namespace DS.WMS.Core.Fee.Method
continue;
}
var result = flowService.AuditFlowInstance(new FlowInstanceAuditReq
var result = flowService.AuditFlowInstance(new FlowAuditInfo
{
Id = flow.Id,
NodeId = flow.ActivityId,
Instance = flow,
Status = yesOrNo,
AuditNote = remark
});
@ -225,57 +229,101 @@ namespace DS.WMS.Core.Fee.Method
}
/// <summary>
/// 整单审批
/// 本票审核(一键审核当前登录用户的所有待审核项)
/// </summary>
/// <param name="yesOrNo">审批结果1=通过2=驳回</param>
/// <param name="remark">备注</param>
/// <param name="id">业务ID</param>
/// <param name="businessType">业务类型</param>
/// <returns></returns>
public DataResult AuditBusiness(int yesOrNo, string remark, long id, BusinessType businessType)
public DataResult AuditBusiness(int yesOrNo, string remark)
{
var flowList = db.Queryable<FlowInstance>().Where(x => x.FlowStatus == RunningStatus && x.MakerList.Contains(user.UserId))
.Select(x => new { x.BusinessId, x.BusinessType }).ToList();
//没有待审批的列表直接返回不再执行后续查询
if (flowList.Count == 0)
return DataResult.Failed("当前暂无待审批的费用");
var request = new FeeBizAuditRequest
{
Items = flowList.Select(x => new BizAudit { Id = x.BusinessId, BusinessType = x.BusinessType }).ToList(),
Remark = remark,
Result = yesOrNo
};
return AuditBusiness(request);
}
/// <summary>
/// 整单审批
/// </summary>
/// <param name="request">审批请求</param>
/// <returns></returns>
public DataResult AuditBusiness(FeeBizAuditRequest request)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
var biz = tenantDb.Queryable<BusinessFeeStatus>().Where(x => x.BusinessId == id && x.BusinessType == businessType)
var gpList = request.Items.GroupBy(x => x.BusinessType).ToList();
foreach (var gp in gpList)
{
var bIdArr = gp.Select(x => x.Id).ToArray();
var bizList = tenantDb.Queryable<BusinessFeeStatus>().Where(x => bIdArr.Contains(x.BusinessId) && x.BusinessType == gp.Key)
.Select(x => new
{
x.Id,
x.BillAuditStatus,
x.FlowId
}).First();
}).ToList();
if (biz == null)
return DataResult.Failed("未能获取业务信息");
if (bizList.Count == 0)
return DataResult.Failed("未能获取业务信息");
if (!biz.FlowId.HasValue)
return DataResult.Failed("业务未处于审批流程中");
if (!bizList.Any(x => x.FlowId.HasValue))
return DataResult.Failed("业务未处于审批流程中");
if (biz.BillAuditStatus != BillAuditStatus.AuditSubmitted)
return DataResult.Failed("业务的审批状态不正确");
if (bizList.Any(x => x.BillAuditStatus != BillAuditStatus.AuditSubmitted))
return DataResult.Failed("业务的审批状态不正确");
var flow = db.Queryable<FlowInstance>().Where(x => x.Id == biz.FlowId.Value).Select(x => new
{
x.Id,
x.ActivityId,
x.BusinessId,
x.BusinessType,
x.MakerList
}).First();
var fIdArr = bizList.Select(x => x.FlowId).ToArray();
var flows = db.Queryable<FlowInstance>().Where(x => fIdArr.Contains(x.Id)).ToList();
if (flow == null)
return DataResult.Failed("未能获取审批工作流");
if (flows.Count == 0)
return DataResult.Failed("未能获取审批工作流");
if (!flow.MakerList.Contains(user.UserId))
return DataResult.Failed("所选费用包含不属于当前用户权限范围内的审批,禁止提交");
if (flows.Any(x => !x.MakerList.Contains(user.UserId)))
return DataResult.Failed("所选项包含不属于当前用户权限范围内的审批,禁止提交");
var result = flowService.AuditFlowInstance(new FlowInstanceAuditReq
{
Id = flow.Id,
NodeId = flow.ActivityId,
Status = yesOrNo,
AuditNote = remark
});
foreach (var flow in flows)
{
var result = flowService.AuditFlowInstance(new FlowAuditInfo
{
Instance = flow,
Status = request.Result,
AuditNote = request.Remark
});
return result;
if (!result.Succeeded)
{
//todo:记录未能成功审核的数据
}
}
}
return DataResult.Success;
}
/// <summary>
/// 设置业务费用锁定状态
/// </summary>
/// <param name="items">业务信息</param>
/// <returns></returns>
public DataResult SetFeeLocking(IEnumerable<BusinessFeeStatus> items)
{
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
int rows = tenantDb.Updateable<BusinessFeeStatus>(items)
.WhereColumns(x => new { x.BusinessId, x.BusinessType })
.UpdateColumns(x => new { x.IsFeeLocking })
.ExecuteCommand();
return rows > 0 ? DataResult.Success : DataResult.Failed("更新失败");
}
/// <summary>
@ -288,17 +336,17 @@ namespace DS.WMS.Core.Fee.Method
var auditType = callback.AuditType.ToEnum<FeeAuditType>();
var tenantDb = saasService.GetBizDbScopeById(user.TenantId);
FeeRecord fee = null;
BusinessFeeStatus businessFee = null;
BusinessFeeStatus biz = null;
if (auditType == FeeAuditType.Business)
{
businessFee = tenantDb.Queryable<BusinessFeeStatus>().Where(x => x.Id == callback.BusinessId && x.BusinessType == callback.BusinessType)
biz = tenantDb.Queryable<BusinessFeeStatus>().Where(x => x.Id == callback.BusinessId && x.BusinessType == callback.BusinessType)
.Select(x => new BusinessFeeStatus
{
Id = x.Id,
BusinessId = x.BusinessId,
BillAuditStatus = x.BillAuditStatus
}).First();
if (businessFee == null)
if (biz == null)
return DataResult.Failed("未能找到业务信息,更新状态失败", MultiLanguageConst.Operation_Failed);
}
else
@ -419,28 +467,28 @@ namespace DS.WMS.Core.Fee.Method
FeeStatus status = FeeStatus.RejectSubmission;
if (callback.FlowStatus == FlowStatusEnum.Approve)
{
businessFee.BillAuditStatus = BillAuditStatus.AuditPassed;
biz.BillAuditStatus = BillAuditStatus.AuditPassed;
status = FeeStatus.AuditPassed;
}
else if (callback.FlowStatus == FlowStatusEnum.Reject)
{
businessFee.BillAuditStatus = BillAuditStatus.Rejected;
biz.BillAuditStatus = BillAuditStatus.Rejected;
}
tenantDb.Updateable(businessFee).UpdateColumns(x => new
tenantDb.Updateable(biz).UpdateColumns(x => new
{
x.BillAuditStatus,
x.FlowId
}).ExecuteCommand();
tenantDb.Updateable<FeeRecord>()
.SetColumns(x => x.FeeStatus == status)
.SetColumns(x => x.FlowId == null)
.SetColumns(x => x.AuditBy == userId)
.SetColumns(x => x.AuditOperator == user.UserName)
.SetColumns(x => x.AuditDate == dtNow)
.Where(x => x.BusinessId == businessFee.BusinessId && x.BusinessType == callback.BusinessType &&
.Where(x => x.BusinessId == biz.BusinessId && x.BusinessType == callback.BusinessType &&
(x.FeeStatus == FeeStatus.Entering || x.FeeStatus == FeeStatus.RejectSubmission)).ExecuteCommand();
break;
@ -455,7 +503,7 @@ namespace DS.WMS.Core.Fee.Method
{
Id = callback.InstanceId,
Deleted = true,
DeleteBy = long.Parse(user.UserId),
DeleteBy = 0,
DeleteTime = DateTime.Now
}).UpdateColumns(x => new { x.Deleted, x.DeleteBy, x.DeleteTime }).ExecuteCommand();
}

@ -460,7 +460,7 @@ namespace DS.WMS.Core.Fee.Method
item.SubmitBy = long.Parse(user.UserId);
item.SubmitDate = dtNow;
item.FlowId = instance.Id;
item.Note = reason;
item.Reason = reason;
}
}
@ -523,6 +523,7 @@ namespace DS.WMS.Core.Fee.Method
//fee.SubmitBy = long.Parse(user.UserId);
//fee.SubmitDate = dtNow;
fee.FlowId = instance.Id;
fee.Reason = items.FirstOrDefault(x => x.FeeRecordId == fee.Id)?.Reason;
}
}

@ -1,3 +1,5 @@
using DS.WMS.Core.Flow.Entity;
namespace DS.WMS.Core.Flow.Dtos;
/// <summary>
@ -8,13 +10,13 @@ public class FlowInstanceAuditReq
/// <summary>
/// 实例ID
/// </summary>
public long Id { get; set; }
public long Id { get; set; }
/// <summary>
/// 节点Id
/// </summary>
public string NodeId { get; set; }
/// <summary>
/// 审核状态 1 同意 2 不同意
/// </summary>
@ -24,4 +26,19 @@ public class FlowInstanceAuditReq
/// 审批备注
/// </summary>
public string AuditNote { get; set; } = "";
}
public class FlowAuditInfo
{
public FlowInstance Instance { get; set; }
/// <summary>
/// 审核状态 1 同意 2 不同意
/// </summary>
public int Status { get; set; }
/// <summary>
/// 审批备注
/// </summary>
public string AuditNote { get; set; }
}

@ -1,5 +1,6 @@
using DS.Module.Core;
using DS.WMS.Core.Flow.Dtos;
using DS.WMS.Core.Flow.Entity;
using DS.WMS.Core.Op.Entity;
namespace DS.WMS.Core.Flow.Interface;
@ -47,6 +48,13 @@ public interface IClientFlowInstanceService
/// <returns></returns>
DataResult AuditFlowInstance(FlowInstanceAuditReq req);
/// <summary>
/// 工作流审批
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
DataResult AuditFlowInstance(FlowAuditInfo info);
/// <summary>
/// 撤销工作流
/// </summary>

@ -68,6 +68,13 @@ public class ClientFlowInstanceService : FlowInstanceService, IClientFlowInstanc
return new FlowRuntime(instance, db, saasService, user);
}
/// <summary>
/// 获取指定类型的工作流实例
/// </summary>
/// <param name="businessId">业务ID</param>
/// <param name="businessType">业务类型</param>
/// <param name="type">模板类型</param>
/// <returns></returns>
public DataResult<FlowInstanceRes> GetFlowInstance(long businessId, BusinessType businessType, string type)
{
var entity = db.Queryable<FlowInstance>().Where(x => x.BusinessId == businessId && x.BusinessType == businessType && x.AuditType == type)
@ -75,4 +82,20 @@ public class ClientFlowInstanceService : FlowInstanceService, IClientFlowInstanc
var result = entity == null ? null : entity.Adapt<FlowInstanceRes>();
return DataResult<FlowInstanceRes>.Success(result);
}
/// <summary>
/// 工作流审批
/// </summary>
/// <param name="info">工作流实例</param>
/// <returns></returns>
public DataResult AuditFlowInstance(FlowAuditInfo info)
{
if (info == null)
return DataResult.Failed("该工作流不存在!", MultiLanguageConst.FlowInstanceNotExist);
if (info.Instance.FlowStatus == FlowStatusEnum.Approve.ToEnumInt())
return DataResult.Failed("该工作流已完成!", MultiLanguageConst.FlowInstanceFinished);
return AuditFlowCore(info.Status, info.AuditNote, info.Instance);
}
}

@ -285,8 +285,6 @@ public class FlowInstanceService : IFlowInstanceService
public DataResult AuditFlowInstance(FlowInstanceAuditReq req)
{
var userId = user.UserId;
var userName = db.Queryable<SysUser>().First(x => x.Id == long.Parse(userId)).UserName;
var instance = db.Queryable<FlowInstance>().First(x => x.Id == req.Id);
if (instance.IsNull())
{
@ -298,18 +296,22 @@ public class FlowInstanceService : IFlowInstanceService
return DataResult.Failed("该工作流已完成!", MultiLanguageConst.FlowInstanceFinished);
}
return AuditFlowCore(req.Status, req.AuditNote, instance);
}
protected virtual DataResult AuditFlowCore(int status, string auditNote, FlowInstance instance)
{
var tag = new FlowTag
{
UserName = userName,
UserName = user.UserName,
UserId = user.UserId,
Description = req.AuditNote,
Taged = req.Status
Description = auditNote,
Taged = status
};
var runtime = CreateRuntimeService(instance);
if (runtime.CurrentNodeId != req.NodeId)
if (runtime.CurrentNodeId != instance.ActivityId)
{
return DataResult.Failed("该工作流审批节点与当前节点不一致!", MultiLanguageConst.FlowInstanceNodeIdConflict);
}
@ -355,7 +357,7 @@ public class FlowInstanceService : IFlowInstanceService
#endregion 会签
#region 一般审核
#region 或签
else
{
@ -393,7 +395,7 @@ public class FlowInstanceService : IFlowInstanceService
int nextNodeType = runtime.GetNextNodeType();
if (runtime.NextNodeType != 5 && (nextNodeType == 4 || nextNodeType == -1) && !instance.CallbackURL.IsNullOrEmpty())
{
instance.Note = req.AuditNote;
instance.Note = auditNote;
Task.Factory.StartNew(() => RunCallbackAsync(instance));
}

@ -48,13 +48,33 @@ namespace DS.WMS.FeeApi.Controllers
return _auditService.Audit(request.Result, request.Remark, request.Ids);
}
/// <summary>
/// 本票审核(一键审核当前登录用户的所有待审核项)
/// </summary>
/// <param name="status">审批结果: 1=通过 2=驳回</param>
/// <param name="remark">审批备注</param>
/// <returns></returns>
[HttpPost, Route("OneClickAudit")]
public DataResult AuditBusiness(int status, string remark)
{
if (status != 1 && status != 2)
return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest);
return _auditService.AuditBusiness(status, remark);
}
/// <summary>
/// 整单费用状态审核
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost, Route("AuditBusiness")]
public DataResult AuditBusiness(FeeAuditRequest request)
public DataResult AuditBusiness(FeeBizAuditRequest request)
{
if (request == null || !request.Id.HasValue || (request.Result != 1 && request.Result != 2))
if (request == null || (request.Result != 1 && request.Result != 2) || request.Items == null || !request.Items.Any())
return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest);
return _auditService.AuditBusiness(request.Result, request.Remark, request.Id.Value, request.BusinessType);
return _auditService.AuditBusiness(request);
}
/// <summary>

@ -1013,3 +1013,10 @@
2024-06-04 16:04:30.7166 Info Validating config: TargetNames=console, ownFile-web, ConfigItems=54, FilePath=D:\Source\Repos\DS8\ds-wms-service\DS.WMS.FeeApi\bin\Debug\net8.0\nlog.config
2024-06-04 16:04:30.7166 Warn Unused target detected. Add a rule for this target to the configuration. TargetName: allfile
2024-06-04 16:04:30.7166 Info Configuration initialized.
2024-06-04 17:02:33.6173 Info Registered target NLog.Targets.FileTarget(Name=allfile)
2024-06-04 17:02:33.6440 Info Registered target NLog.Targets.FileTarget(Name=ownFile-web)
2024-06-04 17:02:33.6440 Info Registered target NLog.Targets.ColoredConsoleTarget(Name=console)
2024-06-04 17:02:33.6570 Info NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c. File version: 5.2.8.2366. Product version: 5.2.8+f586f1341c46fa38aaaff4c641e7f0fa7e813943. GlobalAssemblyCache: False
2024-06-04 17:02:33.6570 Info Validating config: TargetNames=console, ownFile-web, ConfigItems=54, FilePath=D:\Source\Repos\DS8\ds-wms-service\DS.WMS.FeeApi\bin\Debug\net8.0\nlog.config
2024-06-04 17:02:33.6570 Warn Unused target detected. Add a rule for this target to the configuration. TargetName: allfile
2024-06-04 17:02:33.6570 Info Configuration initialized.

@ -1,31 +1,32 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:27655",
"sslPort": 0
}
{
"profiles": {
"http": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5295",
"hotReloadEnabled": false
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5295",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
},
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:27655",
"sslPort": 0
}
}
}
Loading…
Cancel
Save