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.

514 lines
24 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.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
{
/// <summary>
/// 任务分配设置维护服务
/// </summary>
public class TaskAllocationService : ITaskAllocationService
{
private readonly IUser user;
private readonly ILogger<TaskManageBCService> logger;
private readonly ISaasDbService saasDbService;
private readonly ISysCacheService sysCacheService;
public TaskAllocationService(IUser user,
ILogger<TaskManageBCService> logger,
ISaasDbService saasDbService,
ISysCacheService sysCacheService)
{
this.user = user;
this.logger = logger;
this.saasDbService = saasDbService;
this.sysCacheService = sysCacheService;
}
/// <summary>
/// 获取任务分配列表
/// </summary>
/// <param name="carrierId">船公司Id可选</param>
public async Task<DataResult<TaskAllocationtSetQueryListDto>> GetList(long? carrierId)
{
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
carrierId = null;
var list = await tenantDb.Queryable<TaskAllocationtSet>()
.Where(x => x.CarrierId == carrierId &&
(x.IsAllotCustomerService
|| x.IsAllotOperator
|| x.IsAllotSale
|| x.IsAllotVouchingClerk))
.ToListAsync();
Func<TaskAllocationtSet, TaskTypeInfoDto> 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<TaskAllocationtSetQueryListDto>.Success(result);
}
/// <summary>
/// 获取任务分配列表中已存在的船公司列表(用于查询)
/// </summary>
public async Task<DataResult<List<CarrierInfoDto>>> GetContainsCarrierList()
{
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
var carrierList = await tenantDb.Queryable<TaskAllocationtSet>().Select(x => new CarrierInfoDto()
{
CarrierId = x.CarrierId,
Carrier = x.Carrier,
CarrierCode = x.CarrierCode
}).Where(x => x.CarrierId != null).Distinct().ToListAsync();
return DataResult<List<CarrierInfoDto>>.Success(carrierList);
}
/// <summary>
/// 保存任务分配设置
/// </summary>
public async Task<DataResult> 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<TaskAllocationtSet>().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<TaskAllocationtSet>()
.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<TaskAllocationtSet>()
.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)));
}
/// <summary>
/// 获取任务分配数据
/// </summary>
/// <param name="isFromCache">是否从缓存提取 true-从缓存读取 false-从数据库读取</param>
/// <returns>返回任务分配数据列表</returns>
public async Task<DataResult<List<TaskAllocationtSetDto>>> GetAllList(bool isFromCache = true)
{
List<TaskAllocationtSetDto> list = new List<TaskAllocationtSetDto>();
bool isLoad = false;
// 因为设置界面还没有实现,所以先注释掉,防止改库后数据不变
//if (isFromCache)
//{
// var rlt = await sysCacheService.GetAllCommonCodeFromCache<TaskAllocationtSetDto>(SysCacheCategoryEnum.TaskAllocationtSet, "DS8");
// if (rlt.Succeeded)
// return rlt;
// isLoad = true;
//}
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
list = await tenantDb.Queryable<TaskAllocationtSet>()
.Select<TaskAllocationtSetDto>()
.ToListAsync();
if (list.Count > 0)
{
if (isLoad)
{
await sysCacheService.SetCommonCode(list, Sys.Method.SysCacheCategoryEnum.TaskAllocationtSet, "DS8");
}
return DataResult<List<TaskAllocationtSetDto>>.Success(list);
}
return DataResult<List<TaskAllocationtSetDto>>.FailedData(list);
}
/// <summary>
/// (单个任务类型)根据任务类型+海运出口订单Id查询任务分配的人员列表
/// </summary>
/// <param name="taskType">任务类型</param>
/// <param name="seaExportId">海运出口订单Id</param>
/// <param name="dataContext">数据上下文(规则匹配时用到的数据来源)</param>
/// <returns>任务接收人列表</returns>
public async Task<DataResult<List<RecvUserInfo>>> 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,1816779333432381440,1780891904372772864)
order by id desc
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(1813475270208917504,1813509723408961536,1816277472539447296)
order by id desc
*/
var allotSetList = await GetAllList();
if (!allotSetList.Succeeded || allotSetList.Data?.Any() != true)
{
return DataResult<List<RecvUserInfo>>.Success($"未查询到任一类型的任务分配规则", [], MultiLanguageConst.DataQueryNoData);
}
var allotList = allotSetList.Data.Where(x => x.TaskTypeCode == taskType.ToString()).OrderBy(x => x.Id).ToList();
if (allotList.Count == 0)
{
return DataResult<List<RecvUserInfo>>.Success($"对于{taskType}任务未配置任务分配规则", [], MultiLanguageConst.DataQueryNoData);
}
// 匹配分配规则
List<TaskAllocationtSetDto> allotTargetList = new();
foreach (var item in allotList)
{
if (string.IsNullOrEmpty(item.Condition) || dataContext == null)
{
allotTargetList.Add(item);
}
else
{
var contitionContent = JsonConvert.DeserializeObject<ConditionContent>(item.Condition)!;
if (ConditionHelper.IsPass(contitionContent, dataContext))
{
allotTargetList.Add(item);
}
}
}
allotTargetList = allotTargetList.DistinctBy(x => x.Id).ToList();
if (allotTargetList.Count == 0)
{
return DataResult<List<RecvUserInfo>>.Success($"对于{taskType}任务未匹配到任务分配规则", [], MultiLanguageConst.DataQueryNoData);
}
// 查出涉及到的订单
SeaExportRes? order = null;
var tenantDb = saasDbService.GetBizDbScopeById(user.TenantId);
if (dataContext != null && dataContext.ContainsKey(TaskFlowDataNameConst.Business))
{
order = dataContext.Get<SeaExportRes>(TaskFlowDataNameConst.Business);
}
else
{
order = await tenantDb.Queryable<SeaExport>()
.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<List<RecvUserInfo>>.Success($"根据海运出口订单Id{seaExportId}未查询到海运出口订单", [], MultiLanguageConst.DataQueryNoData);
}
List<RecvUserInfo> 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<List<RecvUserInfo>>.Success($"查询成功", result, MultiLanguageConst.OperationSuccess);
}
/// <summary>
/// (多个任务类型)根据任务类型列表+海运出口订单Id查询任务分配的人员列表
/// </summary>
/// <param name="taskTypeList">任务类型列表</param>
/// <param name="seaExportId">海运出口订单Id</param>
/// <param name="dataContext">数据上下文(规则匹配时用到的数据来源)</param>
/// <returns>指定任务类型对应的任务接收人列表</returns>
public async Task<DataResult<Dictionary<TaskBaseTypeEnum, List<RecvUserInfo>>>> GetAllotUserBySeaExportId(List<TaskBaseTypeEnum> 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,1816779333432381440,1780891904372772864)
order by id desc
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(1813475270208917504,1813509723408961536,1816277472539447296)
order by id desc
*/
var allotSetList = await GetAllList();
if (!allotSetList.Succeeded || allotSetList.Data?.Any() != true)
{
return DataResult<Dictionary<TaskBaseTypeEnum, List<RecvUserInfo>>>.Success($"未查询到任一类型的任务分配规则", [], MultiLanguageConst.DataQueryNoData);
}
if (taskTypeList == null || taskTypeList.Count == 0)
{
return DataResult<Dictionary<TaskBaseTypeEnum, List<RecvUserInfo>>>.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<Dictionary<TaskBaseTypeEnum, List<RecvUserInfo>>>.Success($"对于任务列表:{string.Join(',', taskTypeStrList)}未配置任务分配规则", [], MultiLanguageConst.DataQueryNoData);
}
var groupAllotList = allotList.GroupBy(x => x.TaskTypeCode);
// 匹配分配规则
Dictionary<TaskBaseTypeEnum, List<TaskAllocationtSetDto>> allotTargetList = new();
foreach (var groupAllotItem in groupAllotList)
{
var itemResult = new List<TaskAllocationtSetDto>();
foreach (var allotItem in groupAllotItem)
{
if (string.IsNullOrEmpty(allotItem.Condition) || dataContext == null)
{
itemResult.Add(allotItem);
}
else
{
var contitionContent = JsonConvert.DeserializeObject<ConditionContent>(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<SeaExportRes>(TaskFlowDataNameConst.Business);
}
else
{
order = await tenantDb.Queryable<SeaExport>()
.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<Dictionary<TaskBaseTypeEnum, List<RecvUserInfo>>>.Success($"根据海运出口订单Id{seaExportId}未查询到海运出口订单", [], MultiLanguageConst.DataQueryNoData);
}
var result = new Dictionary<TaskBaseTypeEnum, List<RecvUserInfo>>();
foreach (var targetList in allotTargetList)
{
var userList = new List<RecvUserInfo>();
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<Dictionary<TaskBaseTypeEnum, List<RecvUserInfo>>>.Success($"查询成功", result, MultiLanguageConst.OperationSuccess);
}
}
}