using DS.Module.Core; using DS.Module.Core.Condition; using DS.Module.Core.Data; using DS.Module.SqlSugar; using DS.Module.UserModule; using DS.WMS.Core.Op.Dtos; using DS.WMS.Core.Op.Entity; using DS.WMS.Core.Sys.Interface; using DS.WMS.Core.Sys.Method; using DS.WMS.Core.TaskPlat.Dtos; using DS.WMS.Core.TaskPlat.Entity; using DS.WMS.Core.TaskPlat.Interface; using LanguageExt.Pipes; using Mapster; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using SqlSugar; namespace DS.WMS.Core.TaskPlat.Method { /// /// 任务分配设置维护服务 /// public class TaskAllocationService : ITaskAllocationService { private readonly IUser user; private readonly ILogger logger; private readonly ISaasDbService saasDbService; private readonly ISysCacheService sysCacheService; public TaskAllocationService(IUser user, ILogger logger, ISaasDbService saasDbService, ISysCacheService sysCacheService) { this.user = user; this.logger = logger; this.saasDbService = saasDbService; this.sysCacheService = sysCacheService; } /// /// 获取任务分配列表 /// /// 船公司Id(可选) public async Task> GetList(long? carrierId) { var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); carrierId = null; var list = await tenantDb.Queryable() .Where(x => x.CarrierId == carrierId && (x.IsAllotCustomerService || x.IsAllotOperator || x.IsAllotSale || x.IsAllotVouchingClerk)) .ToListAsync(); Func selector = x => new TaskTypeInfoDto() { TaskTypeCode = x.TaskTypeCode, TaskTypeName = x.TaskTypeName }; TaskAllocationtSetQueryListDto result = new() { OperatorTaskTypeList = list.Where(x => x.IsAllotOperator).Select(selector).ToList(), VouchingClerkTaskTypeList = list.Where(x => x.IsAllotVouchingClerk).Select(selector).ToList(), SaleTaskTypeList = list.Where(x => x.IsAllotSale).Select(selector).ToList(), CustomerServiceTaskTypeList = list.Where(x => x.IsAllotCustomerService).Select(selector).ToList(), }; //if (carrierId != null && list.Count != 0) //{ // result.CarrierId = list.First().CarrierId; // result.Carrier = list.First().Carrier; // result.CarrierCode = list.First().CarrierCode; //} return DataResult.Success(result); } /// /// 获取任务分配列表中已存在的船公司列表(用于查询) /// public async Task>> GetContainsCarrierList() { var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); var carrierList = await tenantDb.Queryable().Select(x => new CarrierInfoDto() { CarrierId = x.CarrierId, Carrier = x.Carrier, CarrierCode = x.CarrierCode }).Where(x => x.CarrierId != null).Distinct().ToListAsync(); return DataResult>.Success(carrierList); } /// /// 保存任务分配设置 /// public async Task Save(TaskAllocationtSetSaveDto saveDto) { var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); //if (string.IsNullOrEmpty(saveDto.CarrierCode)) //{ // saveDto.CarrierCode = null; //} //if (string.IsNullOrEmpty(saveDto.Carrier)) //{ // saveDto.Carrier = null; //} //if (saveDto.CarrierId == 0) //{ // saveDto.CarrierId = null; //} saveDto.Carrier = null; saveDto.CarrierCode = null; saveDto.CarrierId = null; var fieldName = saveDto.AllocationTargetCode switch { "Operator" => nameof(TaskAllocationtSet.IsAllotOperator), "VouchingClerk" => nameof(TaskAllocationtSet.IsAllotVouchingClerk), "Sale" => nameof(TaskAllocationtSet.IsAllotSale), "CustomerService" => nameof(TaskAllocationtSet.IsAllotCustomerService), //"Custom" => nameof(TaskAllocationtSet.IsAllotCustom), //"FinancialStaff" => nameof(TaskAllocationtSet.IsAllotFinancialStaff), //"Driver" => nameof(TaskAllocationtSet.IsAllotDriver), //"Dispatcher" => nameof(TaskAllocationtSet.IsAllotDispatcher), _ => throw new NotImplementedException(), }; try { // 先查出来已有的、指定船公司的配置 var oldSettingList = await tenantDb.Queryable().Where(x => x.CarrierId == saveDto.CarrierId).Select(x => new { x.Id, x.TaskTypeCode }).ToListAsync(); var oldSettingIdList = oldSettingList.Select(x => x.Id); var oldSettingTypeCodeList = oldSettingList.Select(x => x.TaskTypeCode); await tenantDb.Ado.BeginTranAsync(); // 将原有的状态设置为未分配 await tenantDb.Updateable() .SetColumns(fieldName, false) .Where(x => oldSettingIdList.Contains(x.Id)) .ExecuteCommandAsync(); // 补充缺少的任务类型 if (saveDto.TaskTypeList?.Any() == true) { var waitAddTypeCodeList = saveDto.TaskTypeList.Select(x => x.TaskTypeCode).Except(oldSettingTypeCodeList).ToList(); if (waitAddTypeCodeList.Count > 0) { var waitAddSetList = waitAddTypeCodeList.Select(x => new TaskAllocationtSet() { CarrierId = saveDto.CarrierId, Carrier = saveDto.Carrier, CarrierCode = saveDto.CarrierCode, TaskTypeCode = x, TaskTypeName = saveDto.TaskTypeList.First(t => t.TaskTypeCode == x).TaskTypeName, }).ToList(); await tenantDb.Insertable(waitAddSetList).ExecuteCommandAsync(); } var setTaskCodeList = saveDto.TaskTypeList.Select(x => x.TaskTypeCode); // 更新指定船公司的配置 await tenantDb.Updateable() .SetColumns(fieldName, true) .Where(x => x.CarrierId == saveDto.CarrierId && setTaskCodeList.Contains(x.TaskTypeCode)) .ExecuteCommandAsync(); } await tenantDb.Ado.CommitTranAsync(); await sysCacheService.RemoveCache(SysCacheCategoryEnum.TaskAllocationtSet, "DS8"); } catch (Exception ex) { await tenantDb.Ado.RollbackTranAsync(); logger.LogError(ex, "保存任务分配设置异常"); throw; } return DataResult.Successed(MultiLanguageConst.GetDescription(nameof(MultiLanguageConst.DataUpdateSuccess))); } /// /// 获取任务分配数据 /// /// 是否从缓存提取 true-从缓存读取 false-从数据库读取 /// 返回任务分配数据列表 public async Task>> GetAllList(bool isFromCache = true) { List list = new List(); bool isLoad = false; // 因为设置界面还没有实现,所以先注释掉,防止改库后数据不变 //if (isFromCache) //{ // var rlt = await sysCacheService.GetAllCommonCodeFromCache(SysCacheCategoryEnum.TaskAllocationtSet, "DS8"); // if (rlt.Succeeded) // return rlt; // isLoad = true; //} var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); list = await tenantDb.Queryable() .Select() .ToListAsync(); if (list.Count > 0) { if (isLoad) { await sysCacheService.SetCommonCode(list, Sys.Method.SysCacheCategoryEnum.TaskAllocationtSet, "DS8"); } return DataResult>.Success(list); } return DataResult>.FailedData(list); } /// /// (单个任务类型)根据任务类型+海运出口订单Id查询任务分配的人员列表 /// /// 任务类型 /// 海运出口订单Id /// 数据上下文(规则匹配时用到的数据来源) /// 任务接收人列表 public async Task>> GetAllotUserBySeaExportId(TaskBaseTypeEnum taskType, long seaExportId, TaskFlowDataContext? dataContext = null) { /* * * 测试库测试用Sql: SELECT t.SplitOrMergeFlag,t.OperatorId,t.OperatorName,t.Doc,t.DocName,t.CustomerService,t.CustomerServiceName,t.ForeignCustomerService,t.ForeignCustomerServiceName,t.Sale,t.SaleId,t.* FROM `op_sea_export` t where Deleted=0 and id In(1816649497120477184) order by id desc */ var allotSetList = await GetAllList(); if (!allotSetList.Succeeded || allotSetList.Data?.Any() != true) { return DataResult>.Success($"未查询到任一类型的任务分配规则", [], MultiLanguageConst.DataQueryNoData); } var allotList = allotSetList.Data.Where(x => x.TaskTypeCode == taskType.ToString()).OrderBy(x => x.Id).ToList(); if (allotList.Count == 0) { return DataResult>.Success($"对于{taskType}任务未配置任务分配规则", [], MultiLanguageConst.DataQueryNoData); } // 匹配分配规则 List allotTargetList = new(); foreach (var item in allotList) { if (string.IsNullOrEmpty(item.Condition) || dataContext == null) { allotTargetList.Add(item); } else { var contitionContent = JsonConvert.DeserializeObject(item.Condition)!; if (ConditionHelper.IsPass(contitionContent, dataContext)) { allotTargetList.Add(item); } } } allotTargetList = allotTargetList.DistinctBy(x => x.Id).ToList(); if (allotTargetList.Count == 0) { return DataResult>.Success($"对于{taskType}任务未匹配到任务分配规则", [], MultiLanguageConst.DataQueryNoData); } // 查出涉及到的订单 SeaExportRes? order = null; var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); if (dataContext != null && dataContext.ContainsKey(TaskFlowDataNameConst.Business)) { order = dataContext.Get(TaskFlowDataNameConst.Business); } else { order = await tenantDb.Queryable() .Where(x => x.Id == seaExportId) .Select(x => new SeaExportRes { Id = x.Id, MBLNO = x.MBLNO, OperatorId = x.OperatorId, OperatorName = x.OperatorName, Doc = x.Doc, DocName = x.DocName, SaleId = x.SaleId, Sale = x.Sale, CustomerService = x.CustomerService, CustomerServiceName = x.CustomerServiceName, ForeignCustomerService = x.ForeignCustomerService, ForeignCustomerServiceName = x.ForeignCustomerServiceName }).FirstAsync(); } if (order == null) { return DataResult>.Success($"根据海运出口订单Id{seaExportId}未查询到海运出口订单", [], MultiLanguageConst.DataQueryNoData); } List result = new(); foreach (TaskAllocationtSetDto item in allotTargetList) { // 根据分配规则+订单,生成人员列表作为结果 if (item.IsAllotCustomerService) { if (order.CustomerService != 0 && !string.IsNullOrEmpty(order.CustomerServiceName)) { result.Add(new RecvUserInfo(order.CustomerService, order.CustomerServiceName)); } if (order.ForeignCustomerService != 0 && !string.IsNullOrEmpty(order.ForeignCustomerServiceName)) { result.Add(new RecvUserInfo(order.ForeignCustomerService, order.ForeignCustomerServiceName)); } } if (item.IsAllotOperator && order.OperatorId != 0 && !string.IsNullOrEmpty(order.OperatorName)) { result.Add(new RecvUserInfo(order.OperatorId, order.OperatorName)); } if (item.IsAllotSale && order.SaleId != 0 && !string.IsNullOrEmpty(order.Sale)) { result.Add(new RecvUserInfo(order.SaleId, order.Sale)); } if (item.IsAllotVouchingClerk && order.Doc != 0 && !string.IsNullOrEmpty(order.DocName)) { result.Add(new RecvUserInfo(order.Doc, order.DocName)); } // (后期实现)如果设置了角色Id列表,则将角色对应的人员列表合并到结果中 } // 人员列表去重 result = result.DistinctBy(x => x.RecvUserId).ToList(); return DataResult>.Success($"查询成功", result, MultiLanguageConst.OperationSuccess); } /// /// (多个任务类型)根据任务类型列表+海运出口订单Id查询任务分配的人员列表 /// /// 任务类型列表 /// 海运出口订单Id /// 数据上下文(规则匹配时用到的数据来源) /// 指定任务类型对应的任务接收人列表 public async Task>>> GetAllotUserBySeaExportId(List taskTypeList, long seaExportId, TaskFlowDataContext? dataContext = null) { /* * * 测试库测试用Sql: * SELECT t.SplitOrMergeFlag,t.OperatorId,t.OperatorName,t.Doc,t.DocName,t.CustomerService,t.CustomerServiceName,t.ForeignCustomerService,t.ForeignCustomerServiceName,t.Sale,t.SaleId,t.* FROM `op_sea_export` t where Deleted=0 and id In(1816649497120477184) order by id desc */ var allotSetList = await GetAllList(); if (!allotSetList.Succeeded || allotSetList.Data?.Any() != true) { return DataResult>>.Success($"未查询到任一类型的任务分配规则", [], MultiLanguageConst.DataQueryNoData); } if (taskTypeList == null || taskTypeList.Count == 0) { return DataResult>>.Success($"任务列表为空", [], MultiLanguageConst.DataQueryNoData); } taskTypeList = taskTypeList.Distinct().ToList(); var taskTypeStrList = taskTypeList.Select(x => x.ToString()); var allotList = allotSetList.Data.Where(x => taskTypeStrList.Contains(x.TaskTypeCode)).OrderBy(x => x.Id).ToList(); if (allotList.Count == 0) { return DataResult>>.Success($"对于任务列表:{string.Join(',', taskTypeStrList)}未配置任务分配规则", [], MultiLanguageConst.DataQueryNoData); } var groupAllotList = allotList.GroupBy(x => x.TaskTypeCode); // 匹配分配规则 Dictionary> allotTargetList = new(); foreach (var groupAllotItem in groupAllotList) { var itemResult = new List(); foreach (var allotItem in groupAllotItem) { if (string.IsNullOrEmpty(allotItem.Condition) || dataContext == null) { itemResult.Add(allotItem); } else { var contitionContent = JsonConvert.DeserializeObject(allotItem.Condition)!; if (ConditionHelper.IsPass(contitionContent, dataContext)) { itemResult.Add(allotItem); } } } if (itemResult.Count != 0 && Enum.TryParse(typeof(TaskBaseTypeEnum), groupAllotItem.Key, out object? type)) { allotTargetList.Add((TaskBaseTypeEnum)type, itemResult); // 因为前面做了去重,所以这里可以直接用Add } } // 查出涉及到的订单 SeaExportRes? order = null; var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId); if (dataContext != null && dataContext.ContainsKey(TaskFlowDataNameConst.Business)) { order = dataContext.Get(TaskFlowDataNameConst.Business); } else { order = await tenantDb.Queryable() .Where(x => x.Id == seaExportId) .Select(x => new SeaExportRes { Id = x.Id, MBLNO = x.MBLNO, OperatorId = x.OperatorId, OperatorName = x.OperatorName, Doc = x.Doc, DocName = x.DocName, SaleId = x.SaleId, Sale = x.Sale, CustomerService = x.CustomerService, CustomerServiceName = x.CustomerServiceName, ForeignCustomerService = x.ForeignCustomerService, ForeignCustomerServiceName = x.ForeignCustomerServiceName }).FirstAsync(); } if (order == null) { return DataResult>>.Success($"根据海运出口订单Id{seaExportId}未查询到海运出口订单", [], MultiLanguageConst.DataQueryNoData); } var result = new Dictionary>(); foreach (var targetList in allotTargetList) { var userList = new List(); foreach (var setItem in targetList.Value) { // 根据分配规则+订单,生成人员列表作为结果 if (setItem.IsAllotCustomerService) { if (order.CustomerService != 0 && !string.IsNullOrEmpty(order.CustomerServiceName)) { userList.Add(new RecvUserInfo(order.CustomerService, order.CustomerServiceName)); } if (order.ForeignCustomerService != 0 && !string.IsNullOrEmpty(order.ForeignCustomerServiceName)) { userList.Add(new RecvUserInfo(order.ForeignCustomerService, order.ForeignCustomerServiceName)); } } if (setItem.IsAllotOperator && order.OperatorId != 0 && !string.IsNullOrEmpty(order.OperatorName)) { userList.Add(new RecvUserInfo(order.OperatorId, order.OperatorName)); } if (setItem.IsAllotSale && order.SaleId != 0 && !string.IsNullOrEmpty(order.Sale)) { userList.Add(new RecvUserInfo(order.SaleId, order.Sale)); } if (setItem.IsAllotVouchingClerk && order.Doc != 0 && !string.IsNullOrEmpty(order.DocName)) { userList.Add(new RecvUserInfo(order.Doc, order.DocName)); } // (后期实现)如果设置了角色Id列表,则将角色对应的人员列表合并到结果中 } if (userList.Count > 0) { result.Add(targetList.Key, userList.DistinctBy(x => x.RecvUserId).ToList()); } } return DataResult>>.Success($"查询成功", result, MultiLanguageConst.OperationSuccess); } } }