Files
tnb.server/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs
2023-06-07 16:01:32 +08:00

255 lines
11 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.Linq;
using System.Text;
using System.Threading.Tasks;
using Aspose.Cells.Drawing;
using JNPF.Common.Extension;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extras.CollectiveOAuth.Config;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using NPOI.OpenXmlFormats.Wordprocessing;
using Polly.Timeout;
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.Interfaces;
namespace Tnb.WarehouseMgr
{
/// <summary>
/// 库房业务类(出入库)
/// </summary>
[ApiDescriptionSettings(Tag = ModuleConsts.Tag, Area = ModuleConsts.Area, Order = 700)]
[Route("api/[area]/[controller]/[action]")]
public class WareHouseService : IWareHouseService, IDynamicApiController, ITransient
{
private readonly ISqlSugarClient _db;
public WareHouseService(ISqlSugarRepository<WmsInstockH> repository)
{
_db = repository.AsSugarClient();
}
/// <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>
/// <remarks>
/// returns:
/// <br/>{
/// <br/> carry_id:载具Id
/// <br/> carry_code:载具编号
/// <br/> carry_name:载具名称
/// <br/> location_id:库位id
/// <br/> location_code:库位编码
/// <br/> location_name:库位名称
/// <br/>}
/// </remarks>
[HttpGet]
public async Task<dynamic> GetCarryInfo()
{
var locationTypes = new[] { (int)EnumLocationType., (int)EnumLocationType., (int)EnumLocationType. };
var items = await _db.Queryable<WmsCarryH>().LeftJoin<BasLocation>((a, b) => a.location_id == b.id)
.Where((a, b) => a.status == 0 && a.is_lock == 0 && !locationTypes.Contains(Convert.ToInt32(b.is_type)))
.Select((a, b) => new
{
carry_id = a.id,
carry_code = a.carry_code,
carry_name = a.carry_name,
location_id = b.id,
location_code = b.location_code,
location_name = b.location_name,
})
.ToListAsync();
return items;
}
/// <summary>
/// 获取库位信息(入库业务) 库位不能为存储库位,出库库位,分拣库位;未锁定
/// </summary>
/// <remarks>
/// returns
/// <br/>{
/// <br/> location_id:库位Id
/// <br/> location_code库位编号
/// <br/> location_name:库位名称
/// <br/> layers:楼层
/// <br/>}
/// </remarks>
[HttpGet]
public async Task<dynamic> GetLocationInfo()
{
var locationTypes = new[] { (int)EnumLocationType., (int)EnumLocationType., (int)EnumLocationType. };
var items = await _db.Queryable<BasLocation>().Where(it => it.is_lock == 0 && !locationTypes.Contains(Convert.ToInt32(it.is_type)))
.Select(it => new
{
location_id = it.id,
location_code = it.location_code,
location_name = it.location_name,
layers = it.layers,
})
.ToListAsync();
return items;
}
/// <summary>
/// 出库查询目标库位信息,覆盖过滤条件
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<dynamic> GetOutStoreDestLocation()
{
var locationTypes = new[] { (int)EnumLocationType., (int)EnumLocationType. };
var items = await _db.Queryable<BasLocation>().Where(it => it.is_lock == 0 && !locationTypes.Contains(Convert.ToInt32(it.is_type)))
.Select(it => new
{
location_id = it.id,
location_code = it.location_code,
})
.ToListAsync();
return items;
}
/// <summary>
/// 出库申请-查询载具信息
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<dynamic> GetOutStoreLocation()
{
var items = await _db.Queryable<WmsCarryH>().LeftJoin<BasLocation>((a, b) => a.location_id == b.id)
.Where((a, b) => a.status == 0 && a.is_lock == 0 && Convert.ToInt32(b.is_type) == (int)EnumLocationType.)
.Select((a, b) => new
{
carry_id = a.id,
carry_code = a.carry_code,
carry_name = a.carry_name,
location_id = b.id,
location_code = b.location_code,
location_name = b.location_name,
})
.ToListAsync();
return items;
}
/// <summary>
/// 路径算法
/// </summary>
/// <param name="pStartId"></param>
/// <param name="pEndId"></param>
/// <returns></returns>
[HttpGet]
public async Task PathAlgorithms(string pStartId, string pEndId)
{
var roads = await _db.Queryable<WmsRoad>().ToListAsync();
await LocPathCalcAlgorithms(pStartId, pEndId, roads);
}
private async Task LocPathCalcAlgorithms(string pStartId, string pEndId, List<WmsRoad> roads)
{
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);
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<WmsPointH> 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 shortestPathPoints = points.FindAll(x => result.Contains(x.id));
shortestPathPoints.Add(points.Find(x => x.id == pStartId));
List<WmsPointH> 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);
string str = null;
}
/// <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];
}
}
}
}