using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using Aspose.Cells.Drawing; using JNPF.Common.Contracts; 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 Mapster; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.CodeAnalysis; 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.Entities.Dto; using Tnb.WarehouseMgr.Entities.Enums; 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; } /// /// 库房业务,入库、出库申请新增修改功能 /// /// /// [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(); var wmsInstockCodes = input.InstockCodes.Adapt>(); wmsInstockCodes.ForEach(x => { if (x.id.IsNullOrWhiteSpace()) { x.id = SnowflakeIdHelper.NextId(); } }); isOk = await _update(wmsInstockD, wmsInstockCodes); break; case EnumInOutStockType.Out: var wmsOutstockD = input.Adapt(); var wmsOutstockCodes = input.InstockCodes.Adapt>(); wmsOutstockCodes.ForEach(x => { if (x.id.IsNullOrWhiteSpace()) { x.id = SnowflakeIdHelper.NextId(); } }); isOk = await _update(wmsOutstockD, wmsOutstockCodes); break; } if (!isOk) throw Oops.Oh(ErrorCode.COM1001); } /// /// 根据明细Id获取出入库明细信息 /// /// /// [HttpGet] public async Task GetInOutStockCodesById([FromQuery] InOutStockDetailQuery input) { dynamic result = null; switch (input.inoutStockType) { case EnumInOutStockType.In: result = await _db.Queryable() .Where(a => a.id == input.bill_d_id) .Select(a => new InStockDetailOutput { bill_id = a.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, CodeDetails = SqlFunc.Subqueryable().Where(it => it.bill_d_id == a.id).ToList(), }).ToListAsync(); break; case EnumInOutStockType.Out: result = await _db.Queryable().Where(it => it.bill_d_id == input.bill_d_id).ToListAsync(); break; } return result; } 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(); isOk = await _db.Updateable(entities).ExecuteCommandHasChangeAsync(); await _db.Ado.CommitTranAsync(); } catch (Exception) { await _db.Ado.RollbackTranAsync(); } return isOk; } /// /// 路径算法 /// /// /// /// [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]; } } } }