leiqunqing
2026-02-06 15b3879cd259108e7ebb755fe02c190f28f1e20c
´úÂë¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/WIDESEAWCS_BasicInfoService/ScanStationService.cs
@@ -1,4 +1,6 @@
using Autofac.Core;
using OfficeOpenXml;
using Spire.Xls;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -8,7 +10,9 @@
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.BaseRepository;
using WIDESEAWCS_Core.BaseServices;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_DTO.BasicInfo;
using WIDESEAWCS_IBasicInfoService;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob;
@@ -18,14 +22,21 @@
    {
        private readonly IFormulaService _formulaService;
        private readonly IFormulaDetailService _formulaDetailService;
        private readonly IProcessInfoService _processInfoService;
        private readonly IProcessInfoDetailService _processInfoDetailService;
        public ScanStationService(IRepository<Dt_ScanStation> BaseDal,
        public ScanStationService(IRepository<Dt_ScanStation> BaseDal,
            IFormulaService formulaService,
            IFormulaDetailService formulaDetailService
            IFormulaDetailService formulaDetailService,
            IProcessInfoService processInfoService,
            IProcessInfoDetailService processInfoDetailService
            ) : base(BaseDal)
        {
            _formulaService = formulaService;
            _formulaDetailService = formulaDetailService;
            _processInfoService = processInfoService;
            _processInfoDetailService = processInfoDetailService;
        }
        public IRepository<Dt_ScanStation> Repository => BaseDal;
@@ -57,7 +68,7 @@
                var Error = device.GetValue<R_PLCDBName, bool>(R_PLCDBName.rboolError);
                if (Heart && !EMG && OnlineExecuting && !Error)
                {
                {
                    device.SetValue(W_PLCDBName.wboolAutoStart, true);
                    //暂停信号
                    device.SetValue(W_PLCDBName.wboolAutoPause, false);
@@ -89,7 +100,7 @@
                var Heart = device.GetValue<R_PLCDBName, bool>(R_PLCDBName.rboolHeart);
                var EMG = device.GetValue<R_PLCDBName, bool>(R_PLCDBName.rboolEMG);
                var Error = device.GetValue<R_PLCDBName, bool>(R_PLCDBName.rboolError);
                if(!device.GetValue<W_PLCDBName, bool>(W_PLCDBName.wboolAutoStart))
                if (!device.GetValue<W_PLCDBName, bool>(W_PLCDBName.wboolAutoStart))
                {
                    return WebResponseContent.Instance.Error("设备未启动");
                }
@@ -214,11 +225,161 @@
                }
                return WebResponseContent.Instance.Error("更新错误");
            }
            catch (Exception ex)
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error("获取数据失败");
            }
        }
        /// <summary>
        /// ä¸‹è½½æµç¨‹å¡
        /// </summary>
        /// <param name="dt_ProcessInfo"></param>
        /// <returns></returns>
        public WebResponseContent ExportData(Dt_ScanStation dt_ScanStation)
        {
            string fileName = $"{DateTime.Now.ToString("yyyyMMddHHssmm")}.xlsx";
            string templatePath = $"{AppDomain.CurrentDomain.BaseDirectory}ExprotTemplate\\发电机弹性支撑信息化流程卡.xlsx";//模板路径
            string savePath = $"{AppDomain.CurrentDomain.BaseDirectory}Download\\{fileName}";//保存文件路径
            using Stream templateStream = new FileStream(templatePath, FileMode.Open);
            using Stream saveStream = new FileStream(savePath, FileMode.Create);
            using ExcelPackage package = new ExcelPackage(saveStream, templateStream);
            ExcelWorksheet worksheet = package.Workbook.Worksheets["流程卡"];
            Dt_Formula formula = _formulaService.Repository.QueryFirst(x => x.ProductCode == dt_ScanStation.StationEndProduct);
            List<Dt_FormulaDetail> dt_FormulaDetails = _formulaDetailService.Repository.QueryData(x => x.FormulaId == formula.Id && x.IsScanned == 1).ToList();
            for (int i = dt_FormulaDetails.Count; i < 10; i++)
            {
                dt_FormulaDetails.Add(new Dt_FormulaDetail());
            }
            worksheet.Cells[3, 5].Value = dt_ScanStation.StationEndProduct;//成品编号
            worksheet.Cells[3, 17].Value = dt_ScanStation.LastProductSn.ObjToInt() - dt_ScanStation.FirstProductSn.ObjToInt() + 1;//数量;
            worksheet.Cells[3, 29].Value = dt_ScanStation.FirstProductSn + "-" + dt_ScanStation.LastProductSn;//流水号
            worksheet.Cells[4, 5].Value = DateTime.Now.ToString("yyyy/MM/dd");//组装日期
            worksheet.Cells[4, 17].Value = dt_ScanStation.AssembleUser;//组装人员
            int row = 7;
            for (int j = 0; j < 5; j++)
            {
                worksheet.Cells[row, 1].Value = dt_FormulaDetails[j].ComponentName;
                worksheet.Cells[row, 5].Value = dt_FormulaDetails[j].ComponentCode;
                worksheet.Cells[row, 12].Value = dt_FormulaDetails[j].SupplierCode;
                worksheet.Cells[row, 19].Value = dt_FormulaDetails[j + 5].ComponentName;
                worksheet.Cells[row, 23].Value = dt_FormulaDetails[j + 5].ComponentCode;
                worksheet.Cells[row, 30].Value = dt_FormulaDetails[j + 5].SupplierCode;
                row++;
            }
            row = 13;
            for (int j = 0; j < 4; j++)
            {
                worksheet.Cells[row + j, 12].Value = "☑ æ˜¯     â–¡ å¦";
                worksheet.Cells[row + j, 30].Value = "☑ æ˜¯     â–¡ å¦";
            }
            worksheet.Cells[17, 12].Value = "☑ æ˜¯     â–¡ å¦";
            worksheet.Cells[23, 5].Value = "☑ æ˜¯     â–¡ å¦";
            List<Dt_ProcessInfoDetail> dt_ProcessInfoDetails = _processInfoDetailService.Repository
                .QueryData(x => x.ProductCode == dt_ScanStation.StationEndProduct
                && x.ProductSn.CompareTo(dt_ScanStation.LastProductSn) >= 0
                && x.ProductSn.CompareTo(dt_ScanStation.LastProductSn) <= 0)
                .OrderBy(x => x.CreateDate)
                .ToList();
            row = 27;
            ExcelRange baseStyleRow = worksheet.Cells[$"{row}:{row}"];
            foreach (var item in dt_ProcessInfoDetails)
            {
                if (row > 61)
                {
                    var sourceRange = worksheet.Cells[row - 1, 1, row - 1, 36];
                    var targetRange = worksheet.Cells[row, 1, row, 36];
                    // 1. å¤åˆ¶åˆå¹¶è§„则(原有逻辑保留)
                    this.CopyCellMerge(worksheet, sourceRange, targetRange);
                    // 2. å¤åˆ¶æ ·å¼ï¼ˆå…¼å®¹æ‰€æœ‰EPPlus版本)
                    targetRange.StyleID = sourceRange.StyleID;
                    // 3. åŒæ­¥è¡Œé«˜
                    worksheet.Row(row).Height = worksheet.Row(row - 1).Height;
                }
                worksheet.Cells[row, 1].Value = item.ProductSn;
                worksheet.Cells[row, 7].Value = item.Height2;
                worksheet.Cells[row, 13].Value = item.Height1;
                worksheet.Cells[row, 19].Value = item.PressPressure;
                worksheet.Cells[row, 25].Value = item.ScrewTorque;
                if (item.PressTightenUnfinished == 1)
                {
                    worksheet.Cells[row, 31].Value = "压装拧紧异常";
                }
                else if (item.CheckUnfinished == 1)
                {
                    worksheet.Cells[row, 31].Value = "检测异常";
                }
                else
                {
                    worksheet.Cells[row, 31].Value = "正常";
                }
                row++;
            }
            //worksheet.DeleteRow(row, worksheet.Dimension.End.Row - row + 1);
            package.Save();
            string pdfFileName = $"{DateTime.Now.ToString("yyyyMMddHHssmm")}.pdf";
            string pdfPath = $"{AppDomain.CurrentDomain.BaseDirectory}Download\\{pdfFileName}";
            Workbook workbook = new Workbook();
            workbook.LoadFromFile(savePath);
            // è½¬æ¢ç¬¬ä¸€ä¸ªå·¥ä½œè¡¨åˆ°PDF
            workbook.SaveToFile(pdfPath, FileFormat.PDF);
            return WebResponseContent.Instance.OK(data: new { path = pdfPath, fileName = pdfFileName });
        }
        // <summary>
        /// è‡ªå®šä¹‰Excel单元格合并规则复制方法(兼容低版本EPPlus)
        /// </summary>
        /// <param name="worksheet">Excel工作表</param>
        /// <param name="sourceRange">源单元格范围</param>
        /// <param name="targetRange">目标单元格范围</param>
        public void CopyCellMerge(ExcelWorksheet worksheet, ExcelRange sourceRange, ExcelRange targetRange)
        {
            if (sourceRange == null || targetRange == null) return;
            if (sourceRange.Worksheet != worksheet || targetRange.Worksheet != worksheet) return;
            // 1. å…ˆå°†æºèŒƒå›´å†…的合并区域提取到临时列表中
            var sourceMergeList = new List<string>();
            foreach (var merge in worksheet.MergedCells)
            {
                var mergeRange = worksheet.Cells[merge];
                if (mergeRange.Start.Row >= sourceRange.Start.Row && mergeRange.End.Row <= sourceRange.End.Row
                    && mergeRange.Start.Column >= sourceRange.Start.Column && mergeRange.End.Column <= sourceRange.End.Column)
                {
                    sourceMergeList.Add(merge);
                }
            }
            // 2. éåŽ†ä¸´æ—¶åˆ—è¡¨ï¼Œå®‰å…¨åœ°åˆ›å»ºç›®æ ‡åˆå¹¶åŒºåŸŸ
            foreach (var merge in sourceMergeList)
            {
                var mergeRange = worksheet.Cells[merge];
                int rowOffset = targetRange.Start.Row - sourceRange.Start.Row;
                int colOffset = targetRange.Start.Column - sourceRange.Start.Column;
                var targetMergeRange = worksheet.Cells[
                    mergeRange.Start.Row + rowOffset,
                    mergeRange.Start.Column + colOffset,
                    mergeRange.End.Row + rowOffset,
                    mergeRange.End.Column + colOffset
                ];
                targetMergeRange.Merge = true;
            }
        }
    }
}