diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs
index c91082dc..79c77dab 100644
--- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs
+++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Org.BouncyCastle.Asn1.Mozilla;
namespace Tnb.WarehouseMgr.Entities.Consts
{
@@ -12,5 +13,21 @@ namespace Tnb.WarehouseMgr.Entities.Consts
/// 出入库单据状态TypeID
///
public const string WMS_INSTOCK_D_BILL_STATUS_TYPEID = "25065133038101";
+ ///
+ /// 预任务生成EnCode
+ ///
+ public const string WMS_PRETASK_H_ENCODE = "PreTaskGen";
+ ///
+ /// 预任务单据状态-待下发Id
+ ///
+ public const string PRETASK_BILL_STATUS_DXF_ID = "26126822610469";
+ ///
+ /// 预任务生成业务类型-载具移入Id
+ ///
+ public const string BIZTYPE_MOVEIN_ID = "26121988909861";
+ ///
+ /// 单据状态-作业中
+ ///
+ public const string BILLSTATUS_ON_ID = "25065143245845";
}
}
diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/GenPreTaskUpInput.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/GenPreTaskUpInput.cs
new file mode 100644
index 00000000..ac05cfe6
--- /dev/null
+++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/GenPreTaskUpInput.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tnb.WarehouseMgr.Entities.Dto
+{
+ ///
+ /// 生成预任务成功后输入参数
+ ///
+ public class GenPreTaskUpInput
+ {
+ ///
+ /// 预任务Id
+ ///
+ public string PreTaskId { get; set; }
+ ///
+ /// 载具Id
+ ///
+ public string CarryId { get; set; }
+ ///
+ /// 载具起始库位Id
+ ///
+ public string CarryStartLocationId { get; set; }
+ ///
+ /// 载具起始库位编号
+ ///
+ public string CarryStartLocationCode { get; set; }
+ ///
+ /// 库位IdS
+ ///
+ public List LocationIds { get; set; }
+ ///
+ /// 预任务操作记录
+ ///
+ public List PreTaskRecords { get; set; }
+ ///
+ /// 预任务条码记录
+ ///
+ public List PreTaskHandleCodes { get; set; }
+
+
+
+ }
+}
diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/IWmsRoadEntity.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/IWmsRoadEntity.cs
new file mode 100644
index 00000000..c0cd0c73
--- /dev/null
+++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/IWmsRoadEntity.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tnb.WarehouseMgr.Entities
+{
+ public interface IWmsRoadEntity
+ {
+ string startpoint_id { get; set; }
+ string endpoint_id { get; set; }
+ }
+}
diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsPretaskH.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsPretaskH.cs
index 6a45796b..7e4066e6 100644
--- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsPretaskH.cs
+++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsPretaskH.cs
@@ -134,4 +134,24 @@ public partial class WmsPretaskH : BaseEntity
///
public DateTime? timestamp { get; set; }
+ ///
+ /// 流程任务Id
+ ///
+ public string? f_flowtaskid { get; set; }
+
+ ///
+ /// 流程引擎Id
+ ///
+ public string? f_flowid { get; set; }
+
+ ///
+ /// 起始库位编号
+ ///
+ public string startlocation_code { get; set; } = string.Empty;
+
+ ///
+ /// 目标库位编号
+ ///
+ public string endlocation_code { get; set; } = string.Empty;
+
}
diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsRoad.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsRoad.cs
index 23d0a294..b37ccc2d 100644
--- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsRoad.cs
+++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Entity/WmsRoad.cs
@@ -8,7 +8,7 @@ namespace Tnb.WarehouseMgr.Entities;
/// 路段管理表
///
[SugarTable("wms_road")]
-public partial class WmsRoad : BaseEntity
+public partial class WmsRoad : BaseEntity, IWmsRoadEntity
{
public WmsRoad()
{
diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs b/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs
index af004e7e..b422285f 100644
--- a/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs
+++ b/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs
@@ -34,5 +34,11 @@ namespace Tnb.WarehouseMgr.Interfaces
///
///
Task GenPreTask(List preTasks);
+ ///
+ /// 生成预任务成功后操作
+ ///
+ ///
+ ///
+ Task GenTaskHandleAfter(GenPreTaskUpInput input);
}
}
diff --git a/WarehouseMgr/Tnb.WarehouseMgr/BaseWareHouseService.cs b/WarehouseMgr/Tnb.WarehouseMgr/BaseWareHouseService.cs
index 5ddaae56..04d0ff8e 100644
--- a/WarehouseMgr/Tnb.WarehouseMgr/BaseWareHouseService.cs
+++ b/WarehouseMgr/Tnb.WarehouseMgr/BaseWareHouseService.cs
@@ -16,5 +16,7 @@ namespace Tnb.WarehouseMgr
public class BaseWareHouseService : IOverideVisualDevService, IDynamicApiController, ITransient
{
public OverideVisualDevFunc OverideFuncs { get; } = new OverideVisualDevFunc();
+
+
}
}
diff --git a/WarehouseMgr/Tnb.WarehouseMgr/Dijkstra.cs b/WarehouseMgr/Tnb.WarehouseMgr/Dijkstra.cs
new file mode 100644
index 00000000..1f95f452
--- /dev/null
+++ b/WarehouseMgr/Tnb.WarehouseMgr/Dijkstra.cs
@@ -0,0 +1,215 @@
+//using System;
+//using System.Collections.Generic;
+//using System.Linq;
+//using System.Text;
+//using System.Threading.Tasks;
+//using JNPF.Common.Contracts;
+//using NPOI.SS.Formula.Functions;
+//using Tnb.WarehouseMgr.Entities;
+
+//namespace Tnb.WarehouseMgr
+//{
+// ///
+// /// 迪杰斯特拉(最短路径算法)
+// ///
+// public class Dijkstra where T : BaseEntity, IWmsRoadEntity, new()
+// {
+// public static int MAX = int.MaxValue;
+
+// public int mEdgNum; // 边的数量
+// public VNode[] mVexs; // 顶点数组
+// //private EData[] edges; //边的数组
+// /*
+// * 创建图
+// *
+// * 参数说明:
+// * vexs -- 顶点数组
+// * edges -- 边
+// */
+// public Dijkstra(string[] vexs, EData[] edges)
+// {
+
+// // 初始化"顶点数"和"边数"
+// int vlen = vexs.Length;
+// int elen = edges.Length;
+
+// // 初始化"顶点"
+// mVexs = new VNode[vlen];
+// for (int i = 0; i < mVexs.Length; i++)
+// {
+// mVexs[i] = new VNode();
+// mVexs[i].data = vexs[i];
+// mVexs[i].firstEdge = null;
+// }
+
+// // 初始化"边"
+// mEdgNum = elen;
+// for (int i = 0; i < elen; i++)
+// {
+// // 读取边的起始顶点和结束顶点
+// string c1 = edges[i].start;
+// string c2 = edges[i].end;
+// int weight = edges[i].weight;
+
+// // 读取边的起始顶点和结束顶点
+// int p1 = GetPosition(c1);
+// int p2 = GetPosition(c2);
+// // 初始化node1
+// ENode node1 = new ENode();
+// node1.ivex = p2;
+// node1.weight = weight;
+// // 将node1链接到"p1所在链表的末尾"
+// if (mVexs[p1].firstEdge == null)
+// mVexs[p1].firstEdge = node1;
+// else
+// LinkLast(mVexs[p1].firstEdge, node1);
+// // 初始化node2
+// ENode node2 = new ENode();
+// node2.ivex = p1;
+// node2.weight = weight;
+// // 将node2链接到"p2所在链表的末尾"
+// if (mVexs[p2].firstEdge == null)
+// mVexs[p2].firstEdge = node2;
+// else
+// LinkLast(mVexs[p2].firstEdge, node2);
+// }
+// }
+
+// /*
+// * 将node节点链接到list的最后
+// */
+// private void LinkLast(ENode list, ENode node)
+// {
+// ENode p = list;
+
+// while (p.nextEdge != null)
+// p = p.nextEdge;
+// p.nextEdge = node;
+// }
+
+// /*
+// * 返回ch位置
+// */
+// private int GetPosition(string ch)
+// {
+// for (int i = 0; i < mVexs.Length; i++)
+// if (mVexs[i].data == ch)
+// return i;
+// return -1;
+// }
+
+// /*
+// * 获取边的权值;若start和end不是连通的,则返回无穷大。
+// */
+// private int GetWeight(int start, int end)
+// {
+// if (start == end)
+// return 0;
+
+// ENode node = mVexs[start].firstEdge;
+// while (node != null)
+// {
+// if (end == node.ivex)
+// return node.weight;
+// node = node.nextEdge;
+// }
+
+// return MAX;
+// }
+
+// /*
+// * Dijkstra最短路径。
+// * 即,统计图中"起点D"到其它各个顶点的最短路径。
+// *
+// * 参数说明:
+// * vs -- 起始顶点(start vertex)。
+// * prev -- 前驱顶点数组。即,prev[i]的值是"起点D"到"顶点i"的最短路径所经历的全部顶点中,位于"顶点i"之前的那个顶点。
+// * dist -- 长度数组。即,dist[i]是"起点D"到"顶点i"的最短路径的长度。
+// */
+// public void CalcDijkstra(int vs, int[] prev, int[] dist, List roads)
+// {
+// //List vertexs = new(); //最短路径串联的点位列表
+// // flag[i]=true表示"起点D"到"顶点i"的最短路径已成功获取。
+// bool[] flag = new bool[mVexs.Length];
+
+// // 初始化
+// for (int i = 0; i < mVexs.Length; i++)
+// {
+// flag[i] = false; // 顶点i的最短路径还没获取到。
+// prev[i] = 0; // 顶点i的前驱顶点为0。
+// dist[i] = GetWeight(vs, i); // 顶点i的最短路径为"起点D"到"顶点i"的权。
+// }
+
+// // 对"起点D"自身进行初始化
+// flag[vs] = true;
+// dist[vs] = 0;
+
+// // 遍历mVexs.Length-1次;每次找出一个顶点的最短路径。
+// int k = 0;
+// for (int i = 1; i < mVexs.Length; i++)
+// {
+// // 寻找当前最小的路径
+// // 即,在未获取最短路径的顶点中,找到离起点D最近的顶点(k)。
+// int min = MAX;
+// for (int j = 0; j < mVexs.Length; j++)
+// {
+// if (flag[j] == false && dist[j] < min)
+// {
+// min = dist[j];
+// k = j;
+// }
+// }
+// // 标记"顶点k"为已经获取到最短路径
+// flag[k] = true;
+// // 更新当前最短路径和前驱顶点
+// // 即,更新"未获取最短路径的顶点的最短路径和前驱顶点"。
+// for (int j = 0; j < mVexs.Length; j++)
+// {
+// int tmp = GetWeight(k, j);
+// tmp = (tmp == MAX ? MAX : (min + tmp)); // 防止溢出
+// if (flag[j] == false && (tmp < dist[j]))
+// {
+// dist[j] = tmp;
+// prev[j] = k;
+// }
+// }
+// }
+// }
+// }
+
+// ///
+// /// 邻接表中表对应的链表的顶点
+// ///
+// public class ENode
+// {
+// public int ivex; // 该边所指向的顶点的位置
+// public int weight; // 该边的权
+// public ENode nextEdge; // 指向下一条弧的指针
+// }
+
+// ///
+// /// 邻接表中表的顶点
+// ///
+// public class VNode
+// {
+// public string data; // 顶点信息
+// public ENode firstEdge; // 指向第一条依附该顶点的弧
+// }
+
+// ///
+// /// 边的结构体
+// ///
+// public class EData
+// {
+// public string start; // 边的起点
+// public string end; // 边的终点
+// public int weight; // 边的权重
+
+// public EData(string start, string end, int weight)
+// {
+// this.start = start;
+// this.end = end;
+// this.weight = weight;
+// }
+// }
+//}
diff --git a/WarehouseMgr/Tnb.WarehouseMgr/Dp.cs b/WarehouseMgr/Tnb.WarehouseMgr/Dp.cs
new file mode 100644
index 00000000..563c7590
--- /dev/null
+++ b/WarehouseMgr/Tnb.WarehouseMgr/Dp.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using JNPF.Templates;
+using Microsoft.AspNetCore.Mvc;
+using NPOI.SS.Formula.Functions;
+using Spire.Doc;
+using Tnb.WarehouseMgr.Entities;
+
+namespace Tnb.WarehouseMgr
+{
+ ///
+ /// 动态规划类
+ ///
+ public class Dp
+ {
+ private const int Max = int.MaxValue;
+ private int Min = int.MaxValue;
+ private int Deep = 0;
+ ///
+ /// 动态规划函数
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void DpFunc(List roads, List subRoads, List pointIds, Dictionary isVisited, string sPointId, string ePointId)
+ {
+ Deep++;
+
+ var sRoads = roads.FindAll(x => x.startpoint_id == sPointId).ToList();
+ var sRoads_EPointIds = sRoads.Select(x => x.endpoint_id).ToList();
+
+ if (!isVisited[sPointId])
+ {
+ Console.WriteLine($"code={roads.Find(x => x.startpoint_id == sPointId).startpoint_code}");
+ pointIds.Add(sPointId);
+ }
+ var eSubRoads = sRoads.FindAll(x => x.endpoint_id == ePointId);
+ if (eSubRoads?.Count > 0)
+ {
+ pointIds.Add(ePointId);
+ Console.WriteLine($"Deep={Deep}");
+ foreach (var kvp in isVisited)
+ {
+ isVisited[kvp.Key] = true;
+ }
+ return;
+ }
+
+ subRoads = roads.FindAll(x => sRoads_EPointIds.Contains(x.startpoint_id)).ToList();
+ if (subRoads?.Count > 0 && !isVisited[sPointId])
+ {
+ isVisited[sPointId] = true;
+ for (int i = 0; i < subRoads.Count; i++)
+ {
+ var sIdx = subRoads[i].startpoint_id;
+ if (!isVisited[sIdx])
+ {
+ DpFunc(roads, subRoads, pointIds, isVisited, sIdx, ePointId);
+ }
+ }
+
+ }
+ }
+ }
+}
diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs
index 4cb42d8a..2bd801c2 100644
--- a/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs
+++ b/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs
@@ -30,7 +30,6 @@ 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;
@@ -224,6 +223,31 @@ namespace Tnb.WarehouseMgr
var row = await _db.Insertable(preTasks).ExecuteCommandAsync();
return row > 0;
}
+ ///
+ /// 生成预任务后续处理
+ ///
+ ///
+ [NonAction]
+ public async Task GenTaskHandleAfter(GenPreTaskUpInput input)
+ {
+ try
+ {
+ await _db.Ado.BeginTranAsync();
+ //根据载具移入Id,回更单据状态
+ await _db.Updateable().SetColumns(it => new WmsMoveInstock { status = WmsWareHouseConst.BILLSTATUS_ON_ID }).Where(it => it.id == input.PreTaskId).ExecuteCommandAsync();
+ //根据生成的预任务,插入预任务操作记录
+ await _db.Insertable(input.PreTaskRecords).ExecuteCommandAsync();
+ //根据载具ID,更新是否锁定和赋值起始库位
+ await _db.Updateable().SetColumns(it => new WmsCarryH { is_lock = 1, location_id = input.CarryStartLocationId, location_code = input.CarryStartLocationCode }).Where(it => it.id == input.CarryId).ExecuteCommandAsync();
+ //根据所有库位更新库位的锁定状态为“锁定”
+ await _db.Updateable().SetColumns(it => new BasLocation { is_lock = 1 }).Where(it => input.LocationIds.Contains(it.id)).ExecuteCommandAsync();
+ await _db.Ado.CommitTranAsync();
+ }
+ catch (Exception)
+ {
+ await _db.Ado.RollbackTranAsync();
+ }
+ }
///
/// 路径算法
@@ -243,34 +267,84 @@ namespace Tnb.WarehouseMgr
private async Task> LocPathCalcAlgorithms(string pStartId, string pEndId, List roads)
{
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);
- var vexs = points.Select(p => p.id).ToArray();
- EData[] edges = new EData[roads.Count];
- for (int i = 0; i < edges.Length; i++)
+ List results = new();
+ List subRoads = new();
+ Dictionary isVisited = roads.Select(x => x.startpoint_id).Distinct().ToDictionary(x => x, x => false);
+
+ List pointIds = new();
+ List codes = new();
+ Dp dp = new();
+
+ dp.DpFunc(roads, subRoads, pointIds, isVisited, pStartId, pEndId);
+ foreach (var pid in pointIds)
{
- var start = roads[i].startpoint_id;
- var end = roads[i].endpoint_id;
- var weight = roads[i].distance;
- edges[i] = new EData(start, end, weight);
+ var point = points.Find(x => x.id == pid);
+ results.Add(point);
}
- 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();
- List result = new();
- GetPoints(pointIds, prev, result, eIndex);
- var shortestPathPoints = points.FindAll(x => result.Contains(x.id));
- shortestPathPoints.Add(points.Find(x => x.id == pStartId));
- List results = new() { startObj };
- var isVisited = shortestPathPoints.ToDictionary(x => x.id, x => false);
- isVisited[pStartId] = true;
- MatchPoint(results, roads, shortestPathPoints, isVisited, pStartId, pEndId);
- results.Add(endObj);
+
+ #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;
+ //}
+
+ ////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 vertexs = new() { startObj };
+ //pG.CalcDijkstra(sIndex, prev, dist);
+ //var pointIds = points.Select(p => p.id).ToList();
+ //List result = new();
+ //GetPoints(pointIds, prev, result, eIndex);
+
+ //var items =new List();
+ //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 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
return results;
}
///
@@ -319,18 +393,18 @@ namespace Tnb.WarehouseMgr
var isOk = false;
try
{
- //await _db.Ado.BeginTranAsync();
+ 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();
+ await _db.Ado.CommitTranAsync();
}
catch (Exception)
{
- //await _db.Ado.RollbackTranAsync();
+ await _db.Ado.RollbackTranAsync();
}
return isOk;
}
diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryMoveInStockService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryMoveInStockService.cs
index eeabb7f2..dd757bfd 100644
--- a/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryMoveInStockService.cs
+++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryMoveInStockService.cs
@@ -3,14 +3,22 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using JNPF.Common.Core.Manager;
using JNPF.Common.Dtos.VisualDev;
+using JNPF.Common.Enums;
+using JNPF.Common.Extension;
+using JNPF.Common.Security;
+using JNPF.FriendlyException;
+using JNPF.Systems.Interfaces.System;
using JNPF.VisualDev;
using JNPF.VisualDev.Entitys;
using JNPF.VisualDev.Interfaces;
+using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using Tnb.BasicData.Entities;
using Tnb.WarehouseMgr.Entities;
+using Tnb.WarehouseMgr.Entities.Consts;
using Tnb.WarehouseMgr.Entities.Dto;
using Tnb.WarehouseMgr.Interfaces;
@@ -27,46 +35,106 @@ namespace Tnb.WarehouseMgr
private readonly IRunService _runService;
private readonly IVisualDevService _visualDevService;
private readonly IWareHouseService _wareHouseService;
+ private readonly IBillRullService _billRullService;
+ private readonly IUserManager _userManager;
public WmsCarryMoveInStockService(
ISqlSugarRepository repository,
IRunService runService,
IVisualDevService visualDevService,
- IWareHouseService wareHouseService)
+ IWareHouseService wareHouseService,
+ IUserManager userManager,
+ IBillRullService billRullService)
{
_db = repository.AsSugarClient();
_runService = runService;
_visualDevService = visualDevService;
_wareHouseService = wareHouseService;
+ _userManager = userManager;
+ _billRullService = billRullService;
OverideFuncs.CreateAsync = CarryMoveIn;
}
private async Task CarryMoveIn(VisualDevModelDataCrInput input)
{
- VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleId, true);
- await _runService.Create(templateEntity, input);
- //入库取终点
- var inStockStrategyInput = new InStockStrategyQuery { warehouse_id = input.data[nameof(InStockStrategyQuery.warehouse_id)].ToString(), Size = 1 };
- var endLocations = await _wareHouseService.InStockStrategy(inStockStrategyInput);
- WmsPointH sPoint = null;
- WmsPointH ePoint = null;
- if (input.data.ContainsKey(nameof(WmsPointH.location_id)))
+
+ try
{
- sPoint = await _db.Queryable().FirstAsync(it => it.location_id == input.data[nameof(WmsPointH.location_id)].ToString());
+ await _db.Ado.BeginTranAsync();
+
+ VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleId, true);
+ await _runService.Create(templateEntity, input);
+ //入库取终点
+ var inStockStrategyInput = new InStockStrategyQuery { warehouse_id = input.data[nameof(InStockStrategyQuery.warehouse_id)].ToString(), Size = 1 };
+ var endLocations = await _wareHouseService.InStockStrategy(inStockStrategyInput);
+ WmsPointH sPoint = null;
+ WmsPointH ePoint = null;
+ if (input.data.ContainsKey(nameof(WmsPointH.location_id)))
+ {
+ sPoint = await _db.Queryable().FirstAsync(it => it.location_id == input.data[nameof(WmsPointH.location_id)].ToString());
+ }
+ if (endLocations?.Count > 0)
+ {
+ ePoint = await _db.Queryable().FirstAsync(it => it.location_id == endLocations[0].id);
+ }
+
+ if (sPoint != null && ePoint != null)
+ {
+ var points = await _wareHouseService.PathAlgorithms(sPoint.id, ePoint.id);
+ //根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序)
+ if (points?.Count > 0)
+ {
+ if (points.Count <= 2) throw new AppFriendlyException("该路径不存在", 500);
+ var preTasks = points.Where(it => !it.location_id.IsNullOrEmpty()).GroupBy(g => g.area_code).Select(it =>
+ {
+ var sPoint = it.FirstOrDefault();
+ var ePoint = it.LastOrDefault();
+
+ WmsPretaskH preTask = new();
+ preTask.org_id = _userManager.User.OrganizeId;
+ preTask.startlocation_id = sPoint?.location_id;
+ preTask.startlocation_code = sPoint?.location_code;
+ preTask.endlocation_id = ePoint?.location_id;
+ preTask.endlocation_code = ePoint?.location_code;
+ preTask.start_floor = sPoint?.floor.ToString();
+ preTask.end_floor = ePoint?.floor.ToString();
+ preTask.bill_code = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_PRETASK_H_ENCODE).GetAwaiter().GetResult();
+ preTask.status = WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID;
+ preTask.biz_type = WmsWareHouseConst.BIZTYPE_MOVEIN_ID;
+ preTask.carry_id = input.data[nameof(preTask.carry_id)]?.ToString()!;
+ preTask.carry_code = input.data[nameof(preTask.carry_code)]?.ToString()!;
+ preTask.area_id = sPoint?.area_id;
+ preTask.area_code = it.Key;
+ preTask.require_id = input.data["ReturnIdentity"].ToString();
+ preTask.require_code = input.data[nameof(preTask.bill_code)]?.ToString()!;
+ preTask.create_id = _userManager.UserId;
+ preTask.create_time = DateTime.Now;
+ return preTask;
+ }).ToList();
+ var isOk = await _wareHouseService.GenPreTask(preTasks);
+ if (isOk)
+ {
+ var preTaskUpInput = new GenPreTaskUpInput();
+ preTaskUpInput.PreTaskId = input.data["ReturnIdentity"].ToString();
+ preTaskUpInput.CarryId = input.data[nameof(WmsCarryD.carry_id)]?.ToString()!;
+ preTaskUpInput.CarryStartLocationId = points.FirstOrDefault().location_id;
+ preTaskUpInput.CarryStartLocationCode = points.FirstOrDefault().location_code;
+ preTaskUpInput.LocationIds = points.Select(x => x.id).ToList();
+ preTaskUpInput.PreTaskRecords = preTasks.Adapt>();
+ preTaskUpInput.PreTaskRecords.ForEach(x => x.id = SnowflakeIdHelper.NextId());
+ await _wareHouseService.GenTaskHandleAfter(preTaskUpInput);
+ }
+ }
+
+ }
+
+ await _db.Ado.CommitTranAsync();
}
- if (endLocations?.Count > 0)
+ catch (Exception ex)
{
- ePoint = await _db.Queryable().FirstAsync(it => it.location_id == endLocations[0].id);
+ await _db.Ado.RollbackTranAsync();
+ throw;
}
- if (sPoint != null && ePoint != null)
- {
- var points = await _wareHouseService.PathAlgorithms(sPoint.id, ePoint.id);
- //根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序)
- //根据载具移入Id,回更单据状态
- //根据生成的预任务,插入预任务操作记录
- //根据载具ID,更新是否锁定和赋值起始库位
- //根据所有库位更新库位的锁定状态为“锁定”
- }
- return Task.FromResult(1);
+ return Task.FromResult(true);
}
}
}
diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryService.cs
index 6ccbf91d..0c5d3c2c 100644
--- a/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryService.cs
+++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryService.cs
@@ -15,7 +15,7 @@ using SqlSugar;
using Tnb.Common.Utils;
using Tnb.WarehouseMgr.Entities;
using Tnb.WarehouseMgr.Entities.Consts;
-using Tnb.WarehouseMgr.Entities.Dto.Inputs;
+using Tnb.WarehouseMgr.Entities.Dto;
using Tnb.WarehouseMgr.Entities.Enums;
using Tnb.WarehouseMgr.Interfaces;
diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsRouteMgrService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsRouteMgrService.cs
index e2ff3536..d9479ae2 100644
--- a/WarehouseMgr/Tnb.WarehouseMgr/WmsRouteMgrService.cs
+++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsRouteMgrService.cs
@@ -23,11 +23,9 @@ namespace Tnb.WarehouseMgr
///
/// 路径管理业务类
///
- [ApiDescriptionSettings(Tag = ModuleConsts.Tag, Area = ModuleConsts.Area, Order = 700)]
- [Route("api/[area]/[controller]/[action]")]
[OverideVisualDev(ModuleId)]
- public class WmsRouteMgrService : IOverideVisualDevService, IWmsRouteMgrService, IDynamicApiController, ITransient
+ public class WmsRouteMgrService : BaseWareHouseService, IWmsRouteMgrService
{
private const string ModuleId = "26100621140773";
private readonly ISqlSugarClient _db;
diff --git a/common/Tnb.Common/Utils/Dijkstra.cs b/common/Tnb.Common/Utils/Dijkstra.cs
index 183f4b13..95dcc7dc 100644
--- a/common/Tnb.Common/Utils/Dijkstra.cs
+++ b/common/Tnb.Common/Utils/Dijkstra.cs
@@ -11,13 +11,13 @@ namespace Tnb.Common.Utils
///
/// 迪杰斯特拉(最短路径算法)
///
- public class Dijkstra where T : BaseEntity, new()
+ public class Dijkstra
{
public static int MAX = int.MaxValue;
public int mEdgNum; // 边的数量
public VNode[] mVexs; // 顶点数组
-
+ private EData[] edges; //边的数组
/*
* 创建图
*
@@ -27,7 +27,7 @@ namespace Tnb.Common.Utils
*/
public Dijkstra(string[] vexs, EData[] edges)
{
-
+ this.edges = edges;
// 初始化"顶点数"和"边数"
int vlen = vexs.Length;
int elen = edges.Length;
@@ -142,7 +142,7 @@ namespace Tnb.Common.Utils
// 对"起点D"自身进行初始化
flag[vs] = true;
dist[vs] = 0;
-
+ HashSet set = new();
// 遍历mVexs.Length-1次;每次找出一个顶点的最短路径。
int k = 0;
for (int i = 1; i < mVexs.Length; i++)
@@ -154,9 +154,12 @@ namespace Tnb.Common.Utils
{
if (flag[j] == false && dist[j] < min)
{
+
min = dist[j];
k = j;
+ set.Add(j);
}
+
}
// 标记"顶点k"为已经获取到最短路径
flag[k] = true;
@@ -173,14 +176,6 @@ namespace Tnb.Common.Utils
}
}
}
-
- // 打印dijkstra最短路径的结果
- //Console.WriteLine("dijkstra({0}): \n", mVexs[vs].data);
- //for (int i = 0; i < mVexs.Length; i++)
- //{
- // Console.WriteLine("shortest({0}, {1})={2}\n", mVexs[vs].data, mVexs[i].data, dist[i]);
- //}
- //return vertexs;
}
}
@@ -189,8 +184,17 @@ namespace Tnb.Common.Utils
///
public class ENode
{
+ ///
+ /// 该边所指向的顶点的位置
+ ///
public int ivex; // 该边所指向的顶点的位置
+ ///
+ /// 该边的权
+ ///
public int weight; // 该边的权
+ ///
+ /// 指向下一条弧的指针
+ ///
public ENode nextEdge; // 指向下一条弧的指针
}