| | |
| | | |
| | | using AngleSharp.Dom; |
| | | using Magicodes.ExporterAndImporter.Core; |
| | | using Magicodes.ExporterAndImporter.Excel; |
| | | using Mapster; |
| | | using Masuit.Tools; |
| | | using SqlSugar; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using System.Drawing.Printing; |
| | | using System.Linq.Expressions; |
| | | using System.Threading.Tasks; |
| | | using WIDESEA_Cache; |
| | | using WIDESEA_Common; |
| | | using WIDESEA_Core; |
| | | using WIDESEA_IStorageBasicService; |
| | | using WIDESEA_Model.Models.BasicModel; |
| | | |
| | | namespace WIDESEA_StorageBasicService; |
| | | |
| | | public class StockInfoService : ServiceBase<DtStockInfo, IStockInfoRepository>, IStockInfoService |
| | | { |
| | | public StockInfoService(IStockInfoRepository BaseDal) : base(BaseDal) |
| | | |
| | | private readonly ISimpleCacheService _simpleCacheService; |
| | | private readonly ILocationStatusChangeRecordRepository _locationStatusChangeRecordRepository; |
| | | private readonly IStockInfoDetailRepository _IStockInfoDetailRepository; |
| | | public StockInfoService(IStockInfoRepository BaseDal, ISimpleCacheService simpleCacheService, ILocationStatusChangeRecordRepository locationStatusChangeRecordRepository, IStockInfoDetailRepository stockInfoDetailService) : base(BaseDal) |
| | | { |
| | | _simpleCacheService = simpleCacheService; |
| | | _locationStatusChangeRecordRepository = locationStatusChangeRecordRepository; |
| | | _IStockInfoDetailRepository = stockInfoDetailService; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 分页 |
| | | /// </summary> |
| | | /// <param name="options"></param> |
| | | /// <returns></returns> |
| | | public override PageGridData<DtStockInfo> GetPageData(PageDataOptions options) |
| | | { |
| | | var data = base.GetPageData(options); |
| | | foreach (var item in data.Rows) |
| | | string wheres = ValidatePageOptions(options); |
| | | //获取排序字段 |
| | | Dictionary<string, SqlSugar.OrderByType> orderbyDic = GetPageDataSort(options, TProperties); |
| | | List<OrderByModel> orderByModels = new List<OrderByModel>(); |
| | | foreach (var item in orderbyDic) |
| | | { |
| | | if (item.IsFull) |
| | | item.Remark = item.StockInfoDetails.Count().ToString(); |
| | | else |
| | | item.Remark = "0"; |
| | | OrderByModel orderByModel = new() |
| | | { |
| | | FieldName = item.Key, |
| | | OrderByType = item.Value |
| | | }; |
| | | orderByModels.Add(orderByModel); |
| | | } |
| | | return data; |
| | | |
| | | |
| | | int totalCount = 0; |
| | | List<SearchParameters> searchParametersList = new List<SearchParameters>(); |
| | | if (!string.IsNullOrEmpty(options.Wheres)) |
| | | { |
| | | try |
| | | { |
| | | searchParametersList = options.Wheres.DeserializeObject<List<SearchParameters>>(); |
| | | options.Filter = searchParametersList; |
| | | } |
| | | catch { } |
| | | } |
| | | |
| | | Expression<Func<DtStockInfo, bool>> locationStatus = null; |
| | | Expression<Func<DtStockInfo, bool>> roadwayNo = null; |
| | | Expression<Func<DtStockInfo, bool>> materielCode = null; |
| | | foreach (var item in searchParametersList) |
| | | { |
| | | if (item.Name.Contains("locationStatus")) |
| | | { |
| | | locationStatus = x => x.LocationInfo.LocationStatus == Convert.ToInt32(item.Value); |
| | | } |
| | | else if (item.Name.Contains("roadwayNo")) |
| | | { |
| | | roadwayNo = x => x.LocationInfo.RoadwayNo.Contains(item.Value); |
| | | } |
| | | else if (item.Name.Contains("materielCode")) |
| | | { |
| | | materielCode = x => x.StockInfoDetails.Any(d => d.MaterielCode.Contains(item.Value)); |
| | | } |
| | | } |
| | | //.IncludesAllFirstLayer() |
| | | var data = BaseDal.Db.Queryable<DtStockInfo>() |
| | | .Includes(x => x.StockInfoDetails) |
| | | .Includes(x => x.LocationInfo) |
| | | .WhereIF(!wheres.IsNullOrEmpty(), wheres) |
| | | .WhereIF(locationStatus != null, locationStatus) |
| | | .WhereIF(roadwayNo != null, roadwayNo) |
| | | .WhereIF(materielCode != null, materielCode) |
| | | .OrderBy(orderByModels) |
| | | .ToPageList(options.Page, options.Rows, ref totalCount); |
| | | new PageGridData<DtStockInfo>(totalCount, data); |
| | | return new PageGridData<DtStockInfo>(totalCount, data); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 批量删除 |
| | | /// </summary> |
| | | /// <param name="keys"></param> |
| | | /// <returns></returns> |
| | | public override WebResponseContent DeleteData(object[] keys) |
| | | { |
| | | try |
| | | { |
| | | List<DtStockInfo_Hty> stockInfos = new List<DtStockInfo_Hty>(); |
| | | List<DtLocationInfo> locationInfos = new List<DtLocationInfo>(); |
| | | |
| | | |
| | | var stocks = new List<string>(); |
| | | |
| | | foreach (var item in keys) |
| | | { |
| | | var stock = BaseDal.QueryFirstNavAsync(x => x.Id == item.ObjToInt()).Result; |
| | | var stockHty = stock.Adapt<DtStockInfo_Hty>(); |
| | | stockInfos.Add(stockHty); |
| | | |
| | | var location = SqlSugarHelper.DbWMS.Queryable<DtLocationInfo>().FirstAsync(x => x.Id == stock.LocationId).Result; |
| | | var lastStatus = location.LocationStatus; |
| | | location.LocationStatus = (int)LocationEnum.Free; |
| | | locationInfos.Add(location); |
| | | stocks.Add(stock.PalletCode); |
| | | _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(location, lastStatus, (int)StatusChangeTypeEnum.ManualOperation, 0); |
| | | } |
| | | |
| | | //_simpleCacheService.HashDel<DtStockInfo>(CacheConst.Cache_DtStockInfo, stocks.ToArray()); |
| | | //var hty = BaseDal.Db.InsertNav(stockInfos) |
| | | // .Include(x => x.StockInfoDetails) |
| | | // .ExecuteCommand(); |
| | | |
| | | //var locationd = SqlSugarHelper.DbWMS.Updateable(locationInfos).ExecuteCommandHasChange(); |
| | | //return base.DeleteData(keys); |
| | | |
| | | var hty = BaseDal.Db.InsertNav(stockInfos) |
| | | .Include(x => x.StockInfoDetails) |
| | | .ExecuteCommand(); |
| | | |
| | | var locationd = SqlSugarHelper.DbWMS.Updateable(locationInfos).ExecuteCommandHasChange(); |
| | | return base.DeleteData(keys); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | return WebResponseContent.Instance.Error(ex.Message); |
| | | } |
| | | } |
| | | |
| | | // 根据传入库存类型获取不同巷道的库存 |
| | | public async Task<Dictionary<string, int>> GetLocationByStockType(bool stockType, string areaCode) |
| | | { |
| | | var stockInfos = await BaseDal.Db.Queryable<DtStockInfo>().Where(x => x.IsFull == stockType && x.AreaCode == areaCode) |
| | | .Includes(x => x.LocationInfo).ToListAsync(); |
| | | |
| | | var result = stockInfos |
| | | .GroupBy(x => x.LocationInfo.RoadwayNo) |
| | | .ToDictionary(x => x.Key, x => x.Count()); |
| | | return result; |
| | | } |
| | | public override WebResponseContent Export(PageDataOptions options) |
| | | { |
| | | WebResponseContent content = new WebResponseContent(); |
| | | try |
| | | { |
| | | // 1. 构建主表查询条件和排序 |
| | | string wheres = ValidatePageOptions(options); |
| | | Dictionary<string, OrderByType> orderbyDic = GetPageDataSort(options, TProperties); |
| | | |
| | | // 2. 查询主表数据 |
| | | List<DtStockInfo> mainList = BaseDal.QueryData(wheres, orderbyDic); |
| | | if (!mainList.Any()) |
| | | { |
| | | return WebResponseContent.Instance.OK("无数据可导出"); |
| | | } |
| | | |
| | | // 3. 批量查询子表数据(通过主表Id关联) |
| | | var mainIds = mainList.Select(m => m.Id).Distinct().ToList(); |
| | | List<DtStockInfoDetail> detailList = _IStockInfoDetailRepository.Db |
| | | .Queryable<DtStockInfoDetail>() |
| | | .Where(d => mainIds.Contains(d.StockId)) |
| | | .ToList(); |
| | | |
| | | // 4. 关联主表和子表数据(只取子表第一条) |
| | | var exportData = new List<PalletWithDetailExportModel>(); |
| | | foreach (var main in mainList) |
| | | { |
| | | // 只取当前主表数据关联的子表第一条(可通过OrderBy指定排序,确保取到想要的第一条) |
| | | var firstDetail = detailList |
| | | .Where(d => d.StockId == main.Id) |
| | | .OrderBy(d => d.Id) // 可选:按子表Id排序,确保结果稳定(可替换为其他字段) |
| | | .FirstOrDefault(); |
| | | |
| | | var exportModel = new PalletWithDetailExportModel |
| | | { |
| | | Id = main.Id, |
| | | PalletCode = main.PalletCode, |
| | | LocationCode = main.LocationCode, |
| | | IsFull = main.IsFull, |
| | | Remark = main.Remark, |
| | | Creater = main.Creater, |
| | | CreateDate = main.CreateDate, |
| | | OutboundTime = (DateTime)main.OutboundTime, |
| | | // 有子表数据则取第一条的物料编码,无则为空 |
| | | MaterielCode = firstDetail?.MaterielCode ?? "" |
| | | }; |
| | | exportData.Add(exportModel); |
| | | } |
| | | |
| | | // 5. 导出数据(逻辑不变) |
| | | string savePath = AppDomain.CurrentDomain.BaseDirectory + "ExcelExport"; |
| | | IExporter exporter = new ExcelExporter(); |
| | | byte[] data = exporter.ExportAsByteArray(exportData).Result; |
| | | |
| | | string fileName = "托盘及物料编码数据.xlsx"; |
| | | FileHelper.WriteFile(savePath, fileName, data); |
| | | |
| | | content = WebResponseContent.Instance.OK(data: Path.Combine(savePath, fileName)); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | content = WebResponseContent.Instance.Error(ex.Message); |
| | | } |
| | | return content; |
| | | } |
| | | |
| | | //public override WebResponseContent UpdateData(DtStockInfo entity) |
| | | //{ |
| | | // return base.UpdateData(entity); |
| | | //} |
| | | } |