using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Aop.Api.Domain;
using Aspose.Cells.Drawing;
using Dm;
using JNPF.Common.Contracts;
using JNPF.Common.Core.Manager;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Security;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extras.CollectiveOAuth.Config;
using JNPF.FriendlyException;
using JNPF.Logging;
using JNPF.Systems.Entitys.Dto.Module;
using JNPF.Systems.Interfaces.System;
using Mapster;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.CodeAnalysis;
using NPOI.HPSF;
using NPOI.OpenXmlFormats.Wordprocessing;
using NPOI.SS.Formula.Functions;
using Polly.Timeout;
using Senparc.NeuChar.Helpers;
using Senparc.Weixin.Work.AdvancedAPIs.OaDataOpen;
using Spire.Pdf.Widget;
using SqlSugar;
using Tnb.BasicData.Entities;
using Tnb.BasicData.Entities.Enums;
using Tnb.Common.Utils;
using Tnb.WarehouseMgr.Entities;
using Tnb.WarehouseMgr.Entities.Consts;
using Tnb.WarehouseMgr.Entities.Dto;
using Tnb.WarehouseMgr.Entities.Dto.Inputs;
using Tnb.WarehouseMgr.Entities.Entity;
using Tnb.WarehouseMgr.Entities.Enums;
using Tnb.WarehouseMgr.Interfaces;
namespace Tnb.WarehouseMgr
{
///
/// 库房业务类(出入库)
///
public class WareHouseService : BaseWareHouseService, IWareHouseService
{
private readonly ISqlSugarClient _db;
private readonly IDictionaryDataService _dictionaryDataService;
private readonly IBillRullService _billRullService;
private readonly IUserManager _userManager;
public WareHouseService(ISqlSugarRepository repository, IDictionaryDataService dictionaryDataService, IBillRullService billRullService, IUserManager userManager)
{
_db = repository.AsSugarClient();
_dictionaryDataService = dictionaryDataService;
_billRullService = billRullService;
_userManager = userManager;
}
///
/// 根据载具Id带出库位、仓库信息
///
/// 载具id
///
/// returns:
///
{
///
carry_id:载具Id
///
carry_name:载具名称
///
location_id:库位Id
///
location_name:库位名称
///
warehouse_id:库房Id
///
warehouse_name:库房名称
///
}
///
[HttpGet]
public async Task GetLocationAndWorkHouseByCarryId([FromRoute] string carryId)
{
var items = await _db.Queryable().LeftJoin((a, b) => a.location_id == b.id)
.LeftJoin((a, b, c) => b.wh_id == c.id)
.Where(a => a.id == carryId)
.Select((a, b, c) => new
{
carry_id = a.id,
carry_name = a.carry_name,
location_id = b.id,
location_name = b.location_name,
warehouse_id = c.id,
warehouse_name = c.whname,
})
.ToListAsync();
return items ?? Enumerable.Empty();
}
///
/// 库房业务,入库、出库申请新增修改功能
///
///
///
[HttpPost]
public async Task ApplyFor(InOutStockApplyforUpInput input)
{
if (input == null) throw new ArgumentNullException(nameof(input));
async Task _updateLocalFunc(InOutStockApplyforUpInput input)
where TStockD : BaseEntity, new()
where TStockCode : BaseEntity, IInOutStockCode, new()
{
var instockD = input.Adapt();
var stockCodes = input.InstockCodes?.Adapt>();
if (stockCodes?.Count > 0)
{
stockCodes.ForEach(x =>
{
if (x.id.IsNullOrWhiteSpace())
{
x.id = SnowflakeIdHelper.NextId();
}
x.bill_d_id = instockD.id;
});
}
return await Update(instockD, stockCodes!);
}
var isOk = input.inoutStockType switch
{
EnumInOutStockType.In => await _updateLocalFunc(input),
EnumInOutStockType.Out => await _updateLocalFunc(input),
_ => throw new ArgumentOutOfRangeException(nameof(input.inoutStockType), $"Not expected EnumInOutStockType value: {input.inoutStockType}"),
};
if (!isOk) throw Oops.Oh(ErrorCode.COM1001);
}
///
/// 根据明细Id获取出入库明细信息
///
///
[HttpGet]
public async Task GetInOutStockCodesById([FromQuery] InOutStockDetailQuery input)
{
dynamic? result = input.inoutStockType switch
{
EnumInOutStockType.In => await FetchInOutStockCodesById(input.bill_d_id),
EnumInOutStockType.Out => await FetchInOutStockCodesById(input.bill_d_id),
_ => throw new ArgumentOutOfRangeException(nameof(input.inoutStockType), $"Not expected EnumInOutStockType value: {input.inoutStockType}"),
};
return result ?? Enumerable.Empty();
}
///
/// 入库策略
///
///
[HttpGet]
public async Task> InStockStrategy([FromQuery] InStockStrategyQuery input)
{
var items = new List();
try
{
var policy = await _db.Queryable().Where(it => it.status == 1).FirstAsync();
if (policy == null) throw new AppFriendlyException("没有可用的策略", 500);
var whereExp = Expressionable.Create()
.And(it => it.wh_id == input.warehouse_id)
.And(it => it.is_lock == 0)
.And(it => it.is_type == ((int)EnumLocationType.存储库位).ToString())
.And(it => it.is_use == ((int)EnumCarryStatus.空闲).ToString())
.ToExpression();
items = await _db.Queryable().Where(whereExp).OrderBy(policy.policy).ToListAsync();
}
catch (Exception)
{
throw;
}
return items.Take(input.Size).ToList();
}
///
/// 出库策略
///
///
[HttpGet]
public async Task> OutStockStrategy([FromQuery] OutStockStrategyQuery input)
{
var whereExprable = Expressionable.Create()
.And((a, b, c) => a.is_lock == 0)
.And((a, b, c) => !string.IsNullOrEmpty(a.location_id))
.And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString())
.And((a, b, c) => a.out_status == "0")
.And((a, b, c) => c.wh_id == input.warehouse_id)
.AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id)
.AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch);
Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace()
? (a, b, c) => a.status == (int)EnumCarryStatus.占用
: (a, b, c) => a.status == (int)EnumCarryStatus.空闲;
whereExprable.And(carryStatusFilterExp);
var whereExpr = whereExprable.ToExpression();
var policy = await _db.Queryable().Where(it => it.status == 1).FirstAsync();
if (policy == null) throw new AppFriendlyException("没有可用策略", 500);
var items = await _db.Queryable().InnerJoin((a, b) => a.id == b.carry_id)
.InnerJoin((a, b, c) => a.location_id == c.id)
.Where(whereExpr)
.OrderBy(policy.policy)
.Select()
.ToListAsync();
return input.Size > 0 ? items.Take(input.Size).ToList() : items;
}
///
/// 生成任务执行
///
///
[HttpPost]
public async Task GenTaskExecute(CancellationTokenSource? cts = default)
{
Stopwatch sw = Stopwatch.StartNew();
var db = _db.CopyNew();
try
{
//获取所有未下发的预任务申请
var preTasks = await db.Queryable().InnerJoin((a, b) => a.startlocation_id == b.location_id && a.carry_id == b.id)
.InnerJoin((a, b, c) => a.area_id == c.id)
.Where(a => a.status == WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID)
.OrderBy(a => new { priority = SqlFunc.Desc(a.priority), a.bill_code })
.Select((a, b, c) => new WmsPretaskH
{
move_num = c.move_num
}, true)
.ToListAsync();
var ids = preTasks.Select(x => x.id).Distinct().ToList();
var preTaskCodes = await db.Queryable().Where(it => ids.Contains(it.bill_id)).ToListAsync();
if (preTasks.Count > 0)
{
//根据预任务管理区分组,获取到所有分组后的预任务,遍历每个预任务 是否为任务链,通过管理区ID
var preTaskGroups = preTasks.GroupBy(g => g.area_code).ToList();
List disTasks = new();
List distaskCodes = new();
foreach (var itGroup in preTaskGroups)
{
var items = itGroup.Adapt>();
for (int i = 0, cnt = items.Count; i < cnt; i++)
{
items[i].id = SnowflakeIdHelper.NextId();
items[i].status = WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID;
}
var moveNum = itGroup.First().move_num;
var itemsCount = items.Count;
var mod = itemsCount % moveNum > 0 ? itemsCount / moveNum + 1 : itemsCount / moveNum;
var arrary = items.ToArray();
for (int i = 1; i <= mod; i++)
{
var groupCode = await _billRullService.GetBillNumber(WmsWareHouseConst.WMS_TASK_EXECUTE_ENCODE);
if (moveNum >= 1)
{
var areaPreTasks = itGroup.ToList();
if (moveNum == 1 || (moveNum > areaPreTasks.Count && areaPreTasks.Count == 1))
{
items.ForEach(x =>
{
x.is_chain = 0;
});
items[0].groups = groupCode;
items[0].bill_code = $"{groupCode}-1";
}
else if ((moveNum >= areaPreTasks.Count && areaPreTasks.Count > 1) || moveNum < areaPreTasks.Count)
{
items.ForEach(x => x.is_chain = 1);
var start = 0;
var end = Math.Min(itemsCount, moveNum);
var arrList = new List(mod);
while (start < itemsCount)
{
var subArray = arrary[start..end];
arrList.Add(subArray);
start = end;
end = Math.Min((end + moveNum), arrary.Length);
}
foreach (var arr in arrList)
{
for (int j = 1, len = arr.Length; j <= len; j++)
{
arr[j - 1].groups = groupCode;
arr[j - 1].bill_code = $"{groupCode}-{j}";
}
}
}
}
}
if (preTaskCodes?.Count > 0)
{
foreach (var disTask in items)
{
var curPreTaskCodes = preTaskCodes.FindAll(x => x.bill_id == disTask.pretask_id);
var curDisTaskCodes = curPreTaskCodes.Adapt>();
curDisTaskCodes.ForEach(x =>
{
x.id = SnowflakeIdHelper.NextId();
x.bill_id = disTask.id;
x.create_time = DateTime.Now;
});
distaskCodes.AddRange(curDisTaskCodes);
}
}
disTasks.AddRange(items);
}
await db.Ado.BeginTranAsync();
//disTasks.ForEach(x => x.id = SnowflakeIdHelper.NextId());
var row = await db.Insertable(disTasks).ExecuteCommandAsync();
if (preTaskCodes?.Count > 0)
{
row = await db.Insertable(distaskCodes).ExecuteCommandAsync();
}
if (row > 0)
{
var preTaskIds = preTasks.Select(x => x.id).ToList();
row = await db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_YXF_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync();
}
//调用AGV创建任务链接口
var taskChainCodeDic = disTasks.Where(t => !t.groups.IsNullOrWhiteSpace()).GroupBy(g => g.groups!)
.ToDictionary(x => x.Key, x => x.Select(it => new
{
taskCode = it.bill_code,
sourceName = it.startlocation_code,
targetName = it.endlocation_code
}));
dynamic reqBody = new ExpandoObject();
sw.Stop();
JNPF.Logging.Log.Information($"程序运行耗时{sw.ElapsedMilliseconds}ms");
await db.Ado.CommitTranAsync();
}
}
catch (Exception ex)
{
JNPF.Logging.Log.Error("生成预任务执行时出现错误",ex);
await db.Ado.RollbackTranAsync();
cts?.Cancel();
throw;
}
finally
{
cts?.Dispose();
}
}
///
/// 任务执行
///
///
///
[HttpPost]
public async Task TaskExecute(TaskExecuteUpInput input)
{
try
{
await _db.Ado.BeginTranAsync();
//更任务执行
for (int i = 0, cnt = input.disTaskIds.Count; i < cnt; i++)
{
if (input.EqpIds?.Count > 0)
{
await _db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID, device_id = input.EqpIds[i] }).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync();
}
else
{
await _db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID }).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync();
}
//await _db.Updateable().SetColumns(it => setColVal).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync();
}
var preTaskIds = await _db.Queryable().Where(it => input.disTaskIds.Contains(it.id)).Select(it => it.pretask_id).ToListAsync();
if (preTaskIds.Count > 0)
{
//更预任务申请表状态
await _db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_START_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync();
}
await _db.Ado.CommitTranAsync();
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
throw;
}
}
///
/// 任务执行取操作返回(后续操作)
///
///
[HttpPost]
public async Task TaskExecuteAfter(TaskExecuteAfterUpInput input)
{
//更新任务执行表单据状态
try
{
await _db.Ado.BeginTranAsync();
await _db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_RUNING_ID }).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync();
//清空载具库位数据
var carryAndLocIds = await _db.Queryable().Where(it => input.disTaskIds.Contains(it.id)).Select(it => new { it.carry_id, it.startlocation_id }).ToListAsync();
if (carryAndLocIds?.Count > 0)
{
var carryIds = carryAndLocIds.Select(x => x.carry_id).ToList();
await _db.Updateable().SetColumns(it => new WmsCarryH { location_id = null, location_code = null }).Where(it => carryIds.Contains(it.id)).ExecuteCommandAsync();
}
//更新起始库位,状态改为空闲、锁定状态,未锁定
if (carryAndLocIds?.Count > 0)
{
var startLocationIds = carryAndLocIds.Select(x => x.startlocation_id).ToList();
await _db.Updateable().SetColumns(it => new BasLocation { is_use = ((int)EnumCarryStatus.空闲).ToString(), is_lock = 0 }).Where(it => startLocationIds.Contains(it.id)).ExecuteCommandAsync();
}
await _db.Ado.CommitTranAsync();
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
}
}
///
/// 任务完成
///
///
[HttpPost]
public async Task TaskComplate(TaskCompleUpInput input)
{
try
{
await _db.Ado.BeginTranAsync();
//更新任务执行表,单据状态为 完成
await _db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID }).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync();
var disTasks = await _db.Queryable().InnerJoin((a, b) => a.carry_id == b.id).Where(a => input.disTaskIds.Contains(a.id)).Select((a, b) => new WmsDistaskH { carry_status = b.carry_status }, true).ToListAsync();
if (disTasks?.Count > 0)
{
// 更新预任务申请表,单据状态为 已完成
var preTaskIds = disTasks.Select(x => x.pretask_id).ToList();
await _db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_COMPLE_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync();
//更新电梯任务数量
var eles = await _db.Queryable().Where(it => disTasks.Select(x => x.area_code).Contains(it.area_code)).ToListAsync();
if (eles?.Count > 0)
await _db.Updateable(eles).ReSetValue(it => it.task_nums--).ExecuteCommandAsync();
//更新载具,锁定状态为未锁定,更新载具的库位当前任务的目标库位
var multiList = disTasks.Select(it => (it.carry_id, it.endlocation_id, it.endlocation_code)).ToList();
for (int i = 0; i < multiList.Count; i++)
{
await _db.Updateable().SetColumns(it => new WmsCarryH { is_lock = 0, location_id = multiList[i].endlocation_id, location_code = multiList[i].endlocation_code }).Where(it => it.id == multiList[i].carry_id).ExecuteCommandAsync();
//更新条码的库位和仓库信息
var carryCodes = await _db.Queryable().Where(it => it.id == multiList[i].carry_id).ToListAsync();
if (carryCodes?.Count > 0)
{
var loc = await _db.Queryable().SingleAsync(it => it.id == multiList[i].endlocation_id);
await _db.Updateable().SetColumns(it => new WmsCarryCode { warehouse_id = loc.wh_id, location_id = multiList[i].endlocation_id, location_code = multiList[i].endlocation_code }).Where(it => it.id == multiList[i].carry_id).ExecuteCommandAsync();
}
}
//更新库位信息,使用状态为 使用,锁定状态为未锁定
var multis = disTasks.Select(it => (it.endlocation_id, it.carry_status)).ToList();
for (int i = 0; i < multis.Count; i++)
{
var carryStatus = multis[i].carry_status;
if (multis[i].carry_status == ((int)EnumCarryStatus.空闲).ToString())
{
carryStatus = ((int)EnumCarryStatus.占用).ToString();
}
var cStatus = carryStatus.ParseToInt();
await _db.Updateable().SetColumns(it => new BasLocation { is_use = cStatus.ToString(), is_lock = 0 }).Where(it => it.id == multis[i].endlocation_id).ExecuteCommandAsync();
}
//更新业务主表的单据状态
foreach (var dt in disTasks)
{
var disTaskCodes = await _db.Queryable().Where(it => it.bill_id == dt.id).ToListAsync();
var upInput = new WareHouseUpInput { bizTypeId = dt.biz_type, requireId = dt.require_id!, distaskCodes = disTaskCodes, carryIds = disTasks.Select(x => x.carry_id).ToList() };
upInput.loginType = !_userManager.LoginType.IsNullOrEmpty() ? "app" : "web";
if (dt.is_sign == 1 && dt.chain_type == "3")
{
await DoUpdate(upInput);
}
}
}
await _db.Ado.CommitTranAsync();
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
throw;
}
}
///
/// 出入库策略启用、禁用状态修改
///
///
///
[HttpPost]
public async Task ModifyPoliciesStatus(ModifyPoliciesStatusInput input)
{
async Task _updateStatus(ModifyPoliciesStatusInput input) where T : BaseEntity, IUpdatePoliciesStatus, new()
{
T obj = new() { status = input.status };
await _db.Updateable(obj).UpdateColumns(it => it.status).Where(it => input.ids.Contains(it.id)).ExecuteCommandAsync();
}
switch (input.strategyType)
{
case EnumInOutStockType.In:
await _updateStatus(input);
break;
case EnumInOutStockType.Out:
await _updateStatus(input);
break;
}
}
///
/// 生成预任务
///
/// 预任务集合
/// 预任务编码集合
///
public async Task GenPreTask(List preTasks, List preTaskCodes)
{
var grpList = preTasks.OrderBy(o => o.bill_code).GroupBy(g => g.carry_id).ToList();
if (grpList?.Count > 0)
{
foreach (var grp in grpList)
{
var arr = grp.ToArray();
if (arr.Length > 1)
{
var subArr = arr[..^1];
System.Array.ForEach(subArr, a => a.chain_type = "1");
}
}
}
var row = await _db.Insertable(preTasks).ExecuteCommandAsync();
if (preTaskCodes?.Count > 0)
{
row = await _db.Insertable(preTaskCodes).ExecuteCommandAsync();
}
var eleP = preTasks.Find(x => x.area_code.Contains("ELE"));
if (eleP != null)
{
row = await _db.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1).Where(it => it.area_code == eleP.area_code).ExecuteCommandAsync();
}
return row > 0;
}
///
/// 生成预任务后续处理
///
///
[NonAction]
public async Task GenInStockTaskHandleAfter(GenPreTaskUpInput input, Expression> setCarryColumnsExp, Expression> setLocaionColumbExp)
{
try
{
await _db.Ado.BeginTranAsync();
//根据生成的预任务,插入预任务操作记录
if (input.PreTaskRecord != null)
{
await _db.Insertable(input.PreTaskRecord).ExecuteCommandAsync();
}
if (input.PreTaskHandleCodes.Count > 0)
{
await _db.Insertable(input.PreTaskHandleCodes).ExecuteCommandAsync();
}
//根据载具ID,更新是否锁定和赋值起始库位
if (setCarryColumnsExp != null)
{
Expression> whereExp = input.CarryIds?.Count > 0 ? it => input.CarryIds.Contains(it.id) : it => it.id == input.CarryId;
await _db.Updateable().SetColumns(setCarryColumnsExp).Where(whereExp).ExecuteCommandAsync();
}
//根据所有库位更新库位的锁定状态为“锁定”
if (setLocaionColumbExp != null && input.LocationIds?.Count > 0)
{
await _db.Updateable().SetColumns(setLocaionColumbExp).Where(it => input.LocationIds.Contains(it.id)).ExecuteCommandAsync();
}
await _db.Ado.CommitTranAsync();
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
throw;
}
}
///
/// 路径算法
///
///
///
///
[NonAction]
public async Task> PathAlgorithms(string pStartId, string pEndId)
{
var roads = await _db.Queryable().ToListAsync();
var points = await LocPathCalcAlgorithms(pStartId, pEndId, roads);
try
{
if (points.FindAll(x => x.location_code != null && x.location_code.Contains("ELE"))?.Count > 0)
{
//查询当前电梯点
var curEleDs = await _db.Queryable().Where(it => points.Select(x => x.id).Contains(it.point_id)).ToListAsync();
//如果有电梯点,则会进行电梯的均匀分配
if (curEleDs?.Count > 0)
{
//当前电梯
var curEle = await _db.Queryable().SingleAsync(it => it.id == curEleDs.First().bill_id && it.status == 1);
if (curEle == null) throw new AppFriendlyException("电梯被禁用或未配置", 500);
//同电梯组电梯
var sGpEle = await _db.Queryable().Where(it => it.elevator_group == curEle.elevator_group && it.id != curEle.id && it.status == 1).ToListAsync();
//判断电梯组中各电梯任务数
if (sGpEle.FindAll(x => Math.Abs(x.task_nums - curEle.task_nums) % 2 == 1)?.Count > 0)
{
var sGpDs = await _db.Queryable().Where(it => it.bill_id == sGpEle.First().id).ToListAsync();
if (sGpDs?.Count > 0)
{
var sGpPoints = await _db.Queryable().Where(it => sGpDs.Select(x => x.point_id).Contains(it.id)).ToListAsync();
var sFEndId = sGpDs.Single(x => x.floor == curEleDs.First().floor).point_id;
var eFStartId = sGpDs.Single(x => x.floor == curEleDs.Last().floor).point_id;
var sFPoints = await LocPathCalcAlgorithms(pStartId, sFEndId, roads);
List elePoints = new();
foreach (var pt in curEleDs)
{
var elePoint = sGpPoints.Find(x => x.floor == pt.floor);
if (elePoint != null)
elePoints.Add(elePoint);
}
var eFPoints = await LocPathCalcAlgorithms(eFStartId, pEndId, roads);
elePoints.Remove(elePoints.First());
elePoints.Remove(elePoints.Last());
points.Clear();
points.AddRange(sFPoints);
points.AddRange(elePoints);
points.AddRange(eFPoints);
}
}
}
}
}
catch (Exception)
{
throw;
}
return points;
}
#region PrivateMethods
private async Task> LocPathCalcAlgorithms(string pStartId, string pEndId, List roads)
{
#region dp
//List results = new();
//var points = await _db.Queryable().ToListAsync();
//Dictionary isVisited = roads.Select(x => x.startpoint_id).Distinct().ToDictionary(x => x, x => false);
//List pointIds = new();
//List codes = new();
//Dp dp = new();
//dynamic obj = new ExpandoObject();
//obj.isArrivedEpoint = false;
//dp.DpFunc(roads, pointIds, isVisited, pStartId, pEndId, obj);
//foreach (var pid in pointIds)
//{
// var point = points.Find(x => x.id == pid);
// if (point != null)
// {
// results.Add(point);
// }
//}
//return results;
#endregion
#region dijkstra
var points = await _db.Queryable().ToListAsync();
var startObj = points.Find(x => x.id == pStartId);
var endObj = points.Find(x => x.id == pEndId);
var sIndex = points.IndexOf(startObj);
var eIndex = points.IndexOf(endObj);
if (eIndex < sIndex)
{
var tempIndex = sIndex;
sIndex = eIndex;
eIndex = tempIndex;
var temp = points[sIndex];
points[sIndex] = points[eIndex];
points[eIndex] = temp;
}
var vexs = points.Select(p => p.id).ToArray();
EData[] edges = new EData[roads.Count];
for (int i = 0; i < edges.Length; i++)
{
var start = roads[i].startpoint_id;
var end = roads[i].endpoint_id;
var weight = roads[i].distance;
edges[i] = new EData(start, end, weight);
}
Dijkstra pG = new(vexs, edges);
int[] prev = new int[pG.mVexs.Length];
int[] dist = new int[pG.mVexs.Length];
List vertexs = new() { startObj };
pG.CalcDijkstra(sIndex, prev, dist);
var pointIds = points.Select(p => p.id).ToList();
Stack result = new();
GetPoints(pointIds, prev, result, eIndex);
List results = new() { startObj };
if (points?.Count > 0)
{
//points.Where(it => result.Contains(it.id));
foreach (var i in result)
{
WmsPointH? point = points?.Find(x => x.id == i);
if (point != null)
{
results.Add(point);
}
}
}
return results;
#endregion
}
///
/// 获取匹配的最短路径节点
///
///
///
///
///
///
///
private void MatchPoint(List results, List roads, List shortestPathPoints, Dictionary isVisited, string pStartId, string pEndId)
{
var sRoads = roads.Where(x => x.startpoint_id == pStartId).ToList();
for (int j = 0; j < sRoads.Count; j++)
{
var sPoint = shortestPathPoints.Find(x => x.id == sRoads[j].endpoint_id);
if (sPoint != null && isVisited.ContainsKey(sPoint.id) && !isVisited[sPoint.id] && sPoint.id != pEndId)
{
var code = sPoint.point_code;
results.Add(sPoint);
isVisited[sPoint.id] = true;
MatchPoint(results, roads, shortestPathPoints, isVisited, sPoint.id, pEndId);
}
}
}
///
/// 根据终止节点获取最短路径顶点
///
///
///
///
///
private static void GetPoints(List pointIds, int[] prev, Stack result, int eIdx)
{
var index = eIdx;
while (index != 0)
{
result.Push(pointIds[index]);
index = prev[index];
}
}
private async Task Update(T1 entity, List entities) where T1 : BaseEntity, new() where T2 : BaseEntity, new()
{
var isOk = false;
try
{
await _db.Ado.BeginTranAsync();
isOk = await _db.Updateable(entity).ExecuteCommandHasChangeAsync();
if (entities?.Count > 0)
{
var row = await _db.Storageable(entities).ExecuteCommandAsync();
isOk = row > 0;
}
await _db.Ado.CommitTranAsync();
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
}
return isOk;
}
///
/// 根据明细Id获取出入库明细信息
///
/// 出入库明细
/// 明细输出类
/// 出入库条码
/// 明细Id
///
private async Task FetchInOutStockCodesById(string billDId)
where TStockD : BaseEntity, new()
where TOutput : IInOutStockDetail, new()
where TStockCode : BaseEntity, IInOutStockCode, new()
{
var dic = await _dictionaryDataService.GetDictionaryByTypeId(WmsWareHouseConst.WMS_INSTOCK_D_BILL_STATUS_TYPEID);
var data = await _db.Queryable()
.Where(a => a.id == billDId)
.Select(a => new TOutput
{
CodeDetails = SqlFunc.Subqueryable().Where(it => it.bill_d_id == a.id).ToList(),
}, true)
.Mapper(it => it.line_status = it.line_status != null && dic.ContainsKey(key: it.line_status) ? dic[it.line_status]?.ToString() : "")
.ToListAsync();
return data;
}
#endregion
}
}