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
{
///
/// 库房业务类(出入库)
///
[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 repository)
{
_db = repository.AsSugarClient();
}
///
/// 根据载具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;
}
///
/// 获取载具信息(入库业务) 当前载具启用;未锁定;如果有库位信息,库位不能为存储库位,出库库位,分拣库位;
///
///
/// returns:
///
{
///
carry_id:载具Id
///
carry_code:载具编号
///
carry_name:载具名称
///
location_id:库位id
///
location_code:库位编码
///
location_name:库位名称
///
}
///
[HttpGet]
public async Task GetCarryInfo()
{
var locationTypes = new[] { (int)EnumLocationType.存储库位, (int)EnumLocationType.出库库位, (int)EnumLocationType.分拣库位 };
var items = await _db.Queryable().LeftJoin((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;
}
///
/// 获取库位信息(入库业务) 库位不能为存储库位,出库库位,分拣库位;未锁定
///
///
/// returns
///
{
///
location_id:库位Id
///
location_code:库位编号
///
location_name:库位名称
///
layers:楼层
///
}
///
[HttpGet]
public async Task GetLocationInfo()
{
var locationTypes = new[] { (int)EnumLocationType.存储库位, (int)EnumLocationType.出库库位, (int)EnumLocationType.分拣库位 };
var items = await _db.Queryable().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;
}
///
/// 出库查询目标库位信息,覆盖过滤条件
///
///
[HttpGet]
public async Task GetOutStoreDestLocation()
{
var locationTypes = new[] { (int)EnumLocationType.存储库位, (int)EnumLocationType.入库库位 };
var items = await _db.Queryable().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;
}
///
/// 出库申请-查询载具信息
///
///
[HttpGet]
public async Task GetOutStoreLocation()
{
var items = await _db.Queryable().LeftJoin((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;
}
///
/// 路径算法
///
///
///
///
[HttpGet]
public async Task PathAlgorithms(string pStartId, string pEndId)
{
var roads = await _db.Queryable().ToListAsync();
await LocPathCalcAlgorithms(pStartId, pEndId, roads);
}
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++)
{
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 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);
string str = null;
}
///
/// 获取匹配的最短路径节点
///
///
///
///
///
///
///
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, List result, int eIdx)
{
var index = eIdx;
while (index != 0)
{
result.Add(pointIds[index]);
index = prev[index];
}
}
}
}