chenyong
5 天以前 8b3377273709a6abd89af0e5b2ff9618c167146e
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageBasicServices/Stock/StockInfoService.cs
@@ -1,42 +1,230 @@

using AngleSharp.Dom;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Excel;
using Mapster;
using WIDESEA_Core.HttpContextUser;
using WIDESEA_Core.Seed;
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)
    {
        List<DtStockInfo_Hty> stockInfos = new List<DtStockInfo_Hty>();
        foreach (var item in keys)
        try
        {
            var stock =  BaseDal.QueryFirstNavAsync(x => x.Id == item.ObjToInt()).Result;
            var stockHty = stock.Adapt<DtStockInfo_Hty>();
            stockInfos.Add(stockHty);
        }
        var hty = BaseDal.Db.InsertNav(stockInfos)
            .Include(x => x.StockInfoDetails)
            .ExecuteCommand();
            List<DtStockInfo_Hty> stockInfos = new List<DtStockInfo_Hty>();
            List<DtLocationInfo> locationInfos = new List<DtLocationInfo>();
        return base.DeleteData(keys);
            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);
    //}
}