Files
tnb.server/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs
2023-06-27 16:43:16 +08:00

735 lines
32 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
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.Systems.Entitys.Dto.Module;
using JNPF.Systems.Interfaces.System;
using Mapster;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.CodeAnalysis;
using NPOI.OpenXmlFormats.Wordprocessing;
using Polly.Timeout;
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.Enums;
using Tnb.WarehouseMgr.Interfaces;
namespace Tnb.WarehouseMgr
{
/// <summary>
/// 库房业务类(出入库)
/// </summary>
public class WareHouseService : BaseWareHouseService, IWareHouseService
{
private readonly ISqlSugarClient _db;
private readonly IDictionaryDataService _dictionaryDataService;
private readonly IBillRullService _billRullService;
private readonly IUserManager _userManager;
public WareHouseService(ISqlSugarRepository<WmsInstockH> repository, IDictionaryDataService dictionaryDataService, IBillRullService billRullService, IUserManager userManager)
{
_db = repository.AsSugarClient();
_dictionaryDataService = dictionaryDataService;
_billRullService = billRullService;
_userManager = userManager;
}
/// <summary>
/// 根据载具Id带出库位、仓库信息
/// </summary>
/// <param name="carryId">载具id</param>
/// <remarks>
/// returns:
/// <br/>{
/// <br/> carry_id:载具Id
/// <br/> carry_name:载具名称
/// <br/> location_id:库位Id
/// <br/> location_name:库位名称
/// <br/> warehouse_id:库房Id
/// <br/> warehouse_name库房名称
/// <br/>}
/// </remarks>
[HttpGet]
public async Task<dynamic> GetLocationAndWorkHouseByCarryId([FromRoute] string carryId)
{
var items = await _db.Queryable<WmsCarryH>().LeftJoin<BasLocation>((a, b) => a.location_id == b.id)
.LeftJoin<BasWarehouse>((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;
}
/// <summary>
/// 库房业务,入库、出库申请新增修改功能
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task ApplyFor(InOutStockApplyforUpInput input)
{
// bill_line,location_id,delivery_date,carry_id,carry_code
if (input == null) throw new ArgumentNullException("input");
var isOk = false;
switch (input.inoutStockType)
{
case EnumInOutStockType.In:
var wmsInstockD = input.Adapt<WmsInstockD>();
var wmsInstockCodes = input.InstockCodes.Adapt<List<WmsInstockCode>>();
if (wmsInstockCodes?.Count > 0)
{
wmsInstockCodes.ForEach(x =>
{
if (x.id.IsNullOrWhiteSpace())
{
x.id = SnowflakeIdHelper.NextId();
}
x.bill_d_id = wmsInstockD.id;
});
}
isOk = await _update(wmsInstockD, wmsInstockCodes);
break;
case EnumInOutStockType.Out:
var wmsOutstockD = input.Adapt<WmsOutstockD>();
var wmsOutstockCodes = input.InstockCodes.Adapt<List<WmsOutstockCode>>();
if (wmsOutstockCodes?.Count > 0)
{
wmsOutstockCodes.ForEach(x =>
{
if (x.id.IsNullOrWhiteSpace())
{
x.id = SnowflakeIdHelper.NextId();
}
x.bill_d_id = wmsOutstockD.id;
});
}
isOk = await _update(wmsOutstockD, wmsOutstockCodes);
break;
}
if (!isOk) throw Oops.Oh(ErrorCode.COM1001);
}
/// <summary>
/// 根据明细Id获取出入库明细信息
/// </summary>
/// <param name="billDId"></param>
/// <returns></returns>
[HttpGet]
public async Task<dynamic> GetInOutStockCodesById([FromQuery] InOutStockDetailQuery input)
{
dynamic result = null;
var dic = await _dictionaryDataService.GetDictionaryByTypeId(WmsWareHouseConst.WMS_INSTOCK_D_BILL_STATUS_TYPEID);
switch (input.inoutStockType)
{
case EnumInOutStockType.In:
result = await _db.Queryable<WmsInstockD>()
.Where(a => a.id == input.bill_d_id)
.Select(a => new InStockDetailOutput
{
id = a.id,
bill_id = a.bill_id,
unit_id = a.unit_id,
code_batch = a.code_batch,
warehouse_id = a.warehouse_id,
line_status = a.line_status,
reason = a.reason,
pr_qty = a.pr_qty,
qty = a.qty,
price = a.price,
tax_price = a.tax_price,
print_qty = a.print_qty,
scan_qty = a.scan_qty,
material_code = a.material_code,
amount = a.amount,
all_amount = a.all_amount,
CodeDetails = SqlFunc.Subqueryable<WmsInstockCode>().Where(it => it.bill_d_id == a.id).ToList(),
})
.Mapper(it => it.line_status = dic.ContainsKey(it.line_status) ? dic[it.line_status]?.ToString()! : "")
.ToListAsync();
break;
case EnumInOutStockType.Out:
result = await _db.Queryable<WmsOutstockD>()
.Where(a => a.id == input.bill_d_id)
.Select(a => new OutStockDetailOutput
{
id = a.id,
bill_id = a.bill_id,
unit_id = a.unit_id,
code_batch = a.code_batch,
warehouse_id = a.warehouse_id,
line_status = a.line_status,
price = a.price,
tax_price = a.tax_price,
material_code = a.material_code,
amount = a.amount,
all_amount = a.all_amount,
CodeDetails = SqlFunc.Subqueryable<WmsOutstockCode>().Where(it => it.bill_d_id == a.id).ToList(),
})
.Mapper(it => it.line_status = dic.ContainsKey(it.line_status) ? dic[it.line_status]?.ToString()! : "")
.ToListAsync();
break;
}
return result;
}
/// <summary>
/// 入库策略
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<List<BasLocation>> InStockStrategy([FromQuery] InStockStrategyQuery input)
{
var items = new List<BasLocation>();
try
{
//var stauts = (int)EnumCarryStatus.空闲;
items = await _db.Queryable<BasLocation>().Where(it => it.wh_id == input.warehouse_id && it.is_lock == 0 && it.is_type == "0" && it.is_use == (int)EnumCarryStatus.).OrderBy(it => new { it.layers, it.loc_line, it.loc_column }, OrderByType.Asc).ToListAsync();
}
catch (Exception ex)
{
throw;
}
return items.Take(input.Size).ToList();
}
/// <summary>
/// 出库策略
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<dynamic> OutStockStrategy()
{
return Task.FromResult<dynamic>(true);
}
/// <summary>
/// 生成任务执行
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task GenTaskExecute()
{
//任务链属性处理内部函数
async Task _taskChainAttrHandle(List<WmsDistaskH> items, List<WmsPretaskH> areaPreTasks, int moveNum)
{
await Task.Run(() =>
{
if (moveNum == 1 || (moveNum > areaPreTasks.Count && areaPreTasks.Count == 1))
{
items.ForEach(x =>
{
x.is_chain = 0;
});
}
else if ((moveNum > areaPreTasks.Count && areaPreTasks.Count > 1) || moveNum < areaPreTasks.Count)
{
items.ForEach(x => x.is_chain = 1);
//items[0].chain_type = "1";
//for (int i = 0; i < items.Count; i++)
//{
// if (i == 0 || i == items.Count - 1) continue;
// items[i].chain_type = "2";
//}
//items[^1].chain_type = "3";
}
});
}
//获取所有未下发的预任务申请
var preTasks = await _db.Queryable<WmsPretaskH>().InnerJoin<WmsCarryH>((a, b) => a.startlocation_id == b.location_id)
.InnerJoin<WmsAreaH>((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();
if (preTasks.Count > 0)
{
//根据预任务管理区分组,获取到所有分组后的预任务,遍历每个预任务 是否为任务链通过管理区ID
var preTaskGroups = preTasks.GroupBy(g => g.area_code).ToList();
List<WmsDistaskH> disTasks = new();
foreach (var itGroup in preTaskGroups)
{
var moveNum = itGroup.First().move_num;
var items = itGroup.Adapt<List<WmsDistaskH>>();
items.ForEach(x =>
{
x.status = WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID;
x.bill_code = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_TASK_EXECUTE_ENCODE).GetAwaiter().GetResult();
});
var areaPreTasks = itGroup.ToList();
if (moveNum == 1)
{
items.ForEach(x =>
{
x.is_chain = 0;
x.chain_type = "3";
});
}
else if (moveNum > 1)
{
//搬运数量==预任务数,可以生成任务执行,为任务链
if (moveNum == areaPreTasks.Count)
{
await _taskChainAttrHandle(items, areaPreTasks, moveNum);
}
else if (moveNum > areaPreTasks.Count && areaPreTasks.Count == 1) //搬运数量>预任务数且预任务数等于1不是任务链预任务数据平替到任务执行
{
await _taskChainAttrHandle(items, areaPreTasks, moveNum);
}
else if (moveNum > areaPreTasks.Count && areaPreTasks.Count > 1) //搬运数量>预任务数且预任务数大于1可以执行时可以生成任务执行为任务链
{
await _taskChainAttrHandle(items, areaPreTasks, moveNum);
}
else if (false) //搬运数量>预任务数且预任务数大于1不可以执行时先空着
{
}
else if (moveNum < areaPreTasks.Count) //搬运数量<预任务数, 按照预任务先后顺序,生成对应搬运数量的任务组
{
await _taskChainAttrHandle(items, areaPreTasks, moveNum);
}
}
disTasks.AddRange(items);
}
try
{
await _db.Ado.BeginTranAsync();
disTasks.ForEach(x => x.id = SnowflakeIdHelper.NextId());
var row = await _db.Insertable(disTasks).ExecuteCommandAsync();
if (row > 0)
{
var preTaskIds = preTasks.Select(x => x.id).ToList();
row = await _db.Updateable<WmsPretaskH>().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_YXF_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync();
}
await _db.Ado.CommitTranAsync();
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
}
}
}
/// <summary>
/// 任务执行
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[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<WmsDistaskH>().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<WmsDistaskH>().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID }).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync();
}
//await _db.Updateable<WmsDistaskH>().SetColumns(it => setColVal).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync();
}
var preTaskIds = await _db.Queryable<WmsDistaskH>().Where(it => input.disTaskIds.Contains(it.id)).Select(it => it.pretask_id).ToListAsync();
if (preTaskIds.Count > 0)
{
//更预任务申请表状态
await _db.Updateable<WmsPretaskH>().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;
}
}
/// <summary>
/// 任务执行取操作返回(后续操作)
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task TaskExecuteAfter(TaskExecuteAfterUpInput input)
{
//更新任务执行表单据状态
try
{
await _db.Ado.BeginTranAsync();
await _db.Updateable<WmsDistaskH>().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_RUNING_ID }).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync();
//清空载具库位数据
var carryIds = await _db.Queryable<WmsDistaskH>().Where(it => input.disTaskIds.Contains(it.id)).Select(it => it.carry_id).ToListAsync();
if (carryIds?.Count > 0)
{
await _db.Updateable<WmsCarryH>().SetColumns(it => new WmsCarryH { location_id = null, location_code = null }).Where(it => carryIds.Contains(it.id)).ExecuteCommandAsync();
}
var startLocationIds = await _db.Queryable<WmsDistaskH>().Where(it => input.disTaskIds.Contains(it.id)).Select(it => it.startlocation_id).ToListAsync();
//更新起始库位,状态改为空闲、锁定状态,未锁定
if (startLocationIds?.Count > 0)
{
await _db.Updateable<BasLocation>().SetColumns(it => new BasLocation { is_use = (int)EnumCarryStatus., is_lock = 0 }).Where(it => startLocationIds.Contains(it.id)).ExecuteCommandAsync();
}
await _db.Ado.CommitTranAsync();
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
}
}
/// <summary>
/// 任务完成
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task TaskComplate(TaskCompleUpInput input)
{
try
{
await _db.Ado.BeginTranAsync();
//更新任务执行表,单据状态为 完成
await _db.Updateable<WmsDistaskH>().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID }).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync();
//更新预任务申请表,单据状态为 已完成
var disTasks = await _db.Queryable<WmsDistaskH>().InnerJoin<WmsCarryH>((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<WmsPretaskH>().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_COMPLE_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync();
}
//更新载具,锁定状态为未锁定,更新载具的库位当前任务的目标库位
if (disTasks?.Count > 0)
{
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<WmsCarryH>().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();
}
}
//更新库位信息,使用状态为 使用,锁定状态为未锁定
if (disTasks?.Count > 0)
{
var destLocIds = disTasks.Select(it => it.endlocation_id).ToList();
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.)
{
carryStatus = (int)EnumCarryStatus.;
}
await _db.Updateable<BasLocation>().SetColumns(it => new BasLocation { is_use = carryStatus, is_lock = 0 }).Where(it => it.id == multis[i].endlocation_id).ExecuteCommandAsync();
}
//更新业务主表的单据状态
if (disTasks?.Count > 0)
{
foreach (var dt in disTasks)
{
var disTaskCodes = await _db.Queryable<WmsDistaskCode>().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 ex)
{
await _db.Ado.RollbackTranAsync();
}
}
/// <summary>
/// 生成预任务
/// </summary>
/// <param name="preTasks">预任务集合</param>
/// <param name="preTaskCodes">预任务编码集合</param>
/// <returns></returns>
public async Task<bool> GenPreTask(List<WmsPretaskH> preTasks, List<WmsPretaskCode> 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];
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();
}
return row > 0;
}
/// <summary>
/// 生成预任务后续处理
/// </summary>
/// <returns></returns>
[NonAction]
public async Task GenInStockTaskHandleAfter(GenPreTaskUpInput input, Expression<Func<WmsCarryH, WmsCarryH>> setCarryColumnsExp, Expression<Func<BasLocation, BasLocation>> 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)
{
if (input.CarryIds?.Count > 0)
{
await _db.Updateable<WmsCarryH>().SetColumns(setCarryColumnsExp).Where(it => input.CarryIds.Contains(it.id)).ExecuteCommandAsync();
}
else
{
await _db.Updateable<WmsCarryH>().SetColumns(setCarryColumnsExp).Where(it => it.id == input.CarryId).ExecuteCommandAsync();
}
}
//根据所有库位更新库位的锁定状态为“锁定”
if (setLocaionColumbExp != null)
{
await _db.Updateable<BasLocation>().SetColumns(setLocaionColumbExp).Where(it => input.LocationIds.Contains(it.id)).ExecuteCommandAsync();
}
await _db.Ado.CommitTranAsync();
}
catch (Exception)
{
await _db.Ado.RollbackTranAsync();
}
}
/// <summary>
/// 路径算法
/// </summary>
/// <param name="pStartId"></param>
/// <param name="pEndId"></param>
/// <returns></returns>
[NonAction]
public async Task<List<WmsPointH>> PathAlgorithms(string pStartId, string pEndId)
{
var roads = await _db.Queryable<WmsRoad>().ToListAsync();
var points = await LocPathCalcAlgorithms(pStartId, pEndId, roads);
return points;
}
#region PrivateMethods
private async Task<List<WmsPointH>> LocPathCalcAlgorithms(string pStartId, string pEndId, List<WmsRoad> roads)
{
var points = await _db.Queryable<WmsPointH>().ToListAsync();
List<WmsPointH> results = new();
Dictionary<string, bool> isVisited = roads.Select(x => x.startpoint_id).Distinct().ToDictionary(x => x, x => false);
List<string> pointIds = new();
List<string> 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;
#region dijkstra
//var points = await _db.Queryable<WmsPointH>().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;
//}
////MatchPoint(results, roads, shortestPathPoints, isVisited, pStartId, pEndId);
//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<WmsPointH> vertexs = new() { startObj };
//pG.CalcDijkstra(sIndex, prev, dist);
//var pointIds = points.Select(p => p.id).ToList();
//List<string> result = new();
//GetPoints(pointIds, prev, result, eIndex);
//var items =new List<string>();
//foreach (var item in prev.Where(x=>x!=0))
//{
// if (points[item] != null)
// {
// items.Add(points[item].point_code);
// }
//}
//var @strings = string.Join(",", items.OrderBy(o=>o));
//var shortestPathPoints = points.FindAll(x => result.Contains(x.id));
//if (shortestPathPoints.IndexOf(startObj) < 0)
//{
// shortestPathPoints.Add(startObj);
//}
//List<WmsPointH> results = new() { startObj };
//var isVisited = shortestPathPoints.ToDictionary(x => x.id, x => false);
//var isVisited2 = shortestPathPoints.ToDictionary(x => x.id, x => false);
//isVisited[pStartId] = true;
//MatchPoint(results, roads, shortestPathPoints, isVisited, pStartId, pEndId);
//results.Add(endObj);
#endregion
}
/// <summary>
/// 获取匹配的最短路径节点
/// </summary>
/// <param name="results"></param>
/// <param name="roads"></param>
/// <param name="shortestPathPoints"></param>
/// <param name="isVisited"></param>
/// <param name="pStartId"></param>
/// <param name="pEndId"></param>
private void MatchPoint(List<WmsPointH> results, List<WmsRoad> roads, List<WmsPointH> shortestPathPoints, Dictionary<string, bool> 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);
}
}
}
/// <summary>
/// 根据终止节点获取最短路径顶点
/// </summary>
/// <param name="pointIds"></param>
/// <param name="prev"></param>
/// <param name="result"></param>
/// <param name="eIdx"></param>
private static void GetPoints(List<string> pointIds, int[] prev, List<string> result, int eIdx)
{
var index = eIdx;
while (index != 0)
{
result.Add(pointIds[index]);
index = prev[index];
}
}
private async Task<bool> _update<T1, T2>(T1 entity, List<T2> entities) where T1 : BaseEntity<string>, new() where T2 : BaseEntity<string>, 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;
}
#endregion
}
}