From efa5c91aa1538a19aabf8ef27a741039a5c9c3b1 Mon Sep 17 00:00:00 2001 From: fei550 <1420031550@qq.com> Date: Wed, 24 Jun 2026 09:59:56 +0800 Subject: [PATCH] =?UTF-8?q?feat(clgl)=E6=9D=A1=E7=A0=81=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SGGL/BLL/Common/FastReport.cs | 162 +++++++++++++++- SGGL/FineUIPro.Web/CLGL/InPlanMaster.aspx.cs | 4 +- SGGL/FineUIPro.Web/CLGL/InputMaster.aspx | 48 +++++ SGGL/FineUIPro.Web/CLGL/InputMaster.aspx.cs | 6 +- .../FineUIPro.Web/Controls/Fastreport.aspx.cs | 4 +- .../Excel/DataOut/管道数据表导出模板.xlsx | Bin 0 -> 9426 bytes SGGL/FineUIPro.Web/FineUIPro.Web.csproj | 2 +- SGGL/FineUIPro.Web/Global.asax.cs | 1 + .../HJGL/InfoQuery/PipelineQuery.aspx | 3 + .../HJGL/InfoQuery/PipelineQuery.aspx.cs | 175 +++++++++++++++++- .../InfoQuery/PipelineQuery.aspx.designer.cs | 9 + .../PreWeld/CuttingCheck.aspx.designer.cs | 2 +- .../PreWeld/CuttingCheckEdit.aspx.designer.cs | 2 +- .../HJGL/PreWeld/FitupCheck.aspx.designer.cs | 2 +- .../PreWeld/FitupCheckEdit.aspx.designer.cs | 2 +- 15 files changed, 410 insertions(+), 12 deletions(-) create mode 100644 SGGL/FineUIPro.Web/File/Excel/DataOut/管道数据表导出模板.xlsx diff --git a/SGGL/BLL/Common/FastReport.cs b/SGGL/BLL/Common/FastReport.cs index 9ecf8a8b..e3667678 100644 --- a/SGGL/BLL/Common/FastReport.cs +++ b/SGGL/BLL/Common/FastReport.cs @@ -1,12 +1,19 @@ -using FastReport; +using FastReport; +using FastReport.Export.Pdf; +using System; using System.Collections.Generic; using System.Data; +using System.IO; +using System.Text; +using System.Timers; using System.Web; namespace BLL { public static class FastReportService { + private static Timer tempReportCleanupTimer; + /// /// 重置数据 /// @@ -32,6 +39,159 @@ namespace BLL } + /// + /// 启动临时报表清理定时器,定期删除超过 1 小时的 PDF。 + /// + public static void StartTempReportCleanupMonitor() + { + if (tempReportCleanupTimer != null) + { + tempReportCleanupTimer.Stop(); + tempReportCleanupTimer.Dispose(); + tempReportCleanupTimer = null; + } + + CleanExpiredTempReports(); + tempReportCleanupTimer = new Timer + { + AutoReset = true, + Interval = 1000 * 60 * 30 + }; + tempReportCleanupTimer.Elapsed += TempReportCleanupTimer_Elapsed; + tempReportCleanupTimer.Start(); + } + + private static void TempReportCleanupTimer_Elapsed(object sender, ElapsedEventArgs e) + { + CleanExpiredTempReports(); + } + + /// + /// 删除 File/Fastreport/Temp 下创建时间超过 1 小时的 PDF 临时文件。 + /// + public static void CleanExpiredTempReports() + { + try + { + string tempDirectory = Path.Combine(Funs.RootPath, @"File\Fastreport\Temp\"); + if (!Directory.Exists(tempDirectory)) + { + return; + } + + DateTime expiredTime = DateTime.Now.AddHours(-1); + foreach (string file in Directory.GetFiles(tempDirectory, "*.pdf", SearchOption.TopDirectoryOnly)) + { + FileInfo fileInfo = new FileInfo(file); + if (fileInfo.CreationTime < expiredTime) + { + fileInfo.Attributes = FileAttributes.Normal; + fileInfo.Delete(); + } + } + } + catch (Exception ex) + { + ErrLogInfo.WriteLog(ex, "FastReport临时报表清理", "FastReportService.CleanExpiredTempReports"); + } + } + + /// + /// 导出报表 PDF 到临时目录,并返回可访问的相对 URL。 + /// + /// 报表模板路径,支持绝对路径或相对 Funs.RootPath 的路径。 + public static string ExportReport(string reportPath) + { + List dataTables = (List)HttpContext.Current.Session["ReportDataTables"]; + Dictionary parameterValues = (Dictionary)HttpContext.Current.Session["ReportParameterValues"]; + return ExportReport(reportPath, dataTables, parameterValues); + } + + /// + /// 导出报表 PDF 到临时目录,并返回可访问的相对 URL。 + /// + /// 报表模板路径,支持绝对路径或相对 Funs.RootPath 的路径。 + /// 报表数据源集合。 + /// 报表参数集合。 + public static string ExportReport(string reportPath, List dataTables, Dictionary parameterValues) + { + string fullReportPath = GetReportFullPath(reportPath); + if (string.IsNullOrEmpty(fullReportPath) || !File.Exists(fullReportPath)) + { + throw new FileNotFoundException("打印模板不存在!", reportPath); + } + + string relativeDirectory = @"File\Fastreport\Temp\"; + string tempDirectory = Path.Combine(Funs.RootPath, relativeDirectory); + if (!Directory.Exists(tempDirectory)) + { + Directory.CreateDirectory(tempDirectory); + } + + string fileName = "report_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "_" + Guid.NewGuid().ToString("N") + ".pdf"; + string filePath = Path.Combine(tempDirectory, fileName); + using (Report report = BuildPreparedReport(fullReportPath, dataTables, parameterValues)) + using (PDFExport pdfExport = new PDFExport()) + { + // Web 打印先导出 PDF,前端用 iframe 装载后调用浏览器打印。 + pdfExport.PrintScaling = false; + pdfExport.ShowPrintDialog = true; + report.Export(pdfExport, filePath); + } + + return "~/" + relativeDirectory.Replace("\\", "/") + fileName; + } + + private static Report BuildPreparedReport(string reportPath, List dataTables, Dictionary parameterValues) + { + FastReport.Utils.Config.WebMode = true; + Report report = new Report(); + report.Load(reportPath); + if (report.Dictionary.Connections.Count > 0) + { + var reportConnection = report.Dictionary.Connections[0]; + if (reportConnection.ConnectionString != Funs.ConnString) + { + // 打印时只替换本次报表连接,避免把运行环境连接串写回模板文件。 + reportConnection.ConnectionString = Funs.ConnString; + } + } + + if (dataTables != null && dataTables.Count > 0) + { + for (int i = 0; i < dataTables.Count; i++) + { + report.RegisterData(dataTables[i], dataTables[i].TableName); + } + } + + if (parameterValues != null && parameterValues.Count > 0) + { + foreach (KeyValuePair kvp in parameterValues) + { + report.SetParameterValue(kvp.Key, kvp.Value); + } + } + + report.Prepare(); + return report; + } + + private static string GetReportFullPath(string reportPath) + { + if (string.IsNullOrEmpty(reportPath)) + { + return reportPath; + } + + if (Path.IsPathRooted(reportPath)) + { + return reportPath; + } + + return Path.Combine(Funs.RootPath, reportPath.TrimStart('\\', '/')); + } + /// /// 合并报表后打印 /// diff --git a/SGGL/FineUIPro.Web/CLGL/InPlanMaster.aspx.cs b/SGGL/FineUIPro.Web/CLGL/InPlanMaster.aspx.cs index 3b0232d4..d0f6a212 100644 --- a/SGGL/FineUIPro.Web/CLGL/InPlanMaster.aspx.cs +++ b/SGGL/FineUIPro.Web/CLGL/InPlanMaster.aspx.cs @@ -1,4 +1,5 @@ using BLL; +using FastReport; using Model; using System; using System.Collections.Generic; @@ -433,8 +434,7 @@ namespace FineUIPro.Web.CLGL { BindDetailGrid(Grid1.SelectedRowID); } - - private void Print(string Id) + private void Print(string Id) { BLL.FastReportService.ResetData(); if (string.IsNullOrEmpty(Id)) diff --git a/SGGL/FineUIPro.Web/CLGL/InputMaster.aspx b/SGGL/FineUIPro.Web/CLGL/InputMaster.aspx index 19c3dd18..e2c7d0bf 100644 --- a/SGGL/FineUIPro.Web/CLGL/InputMaster.aspx +++ b/SGGL/FineUIPro.Web/CLGL/InputMaster.aspx @@ -254,6 +254,54 @@ function reloadGrid() { __doPostBack(null, 'reloadGrid'); } + function printByHiddenFrame(url) { + var frameId = 'fastreport-print-frame-' + new Date().getTime(); + var frame = document.createElement('iframe'); + frame.id = frameId; + frame.name = frameId; + frame.style.position = 'fixed'; + frame.style.left = '-10000px'; + frame.style.top = '-10000px'; + frame.style.width = '1px'; + frame.style.height = '1px'; + frame.style.border = '0'; + frame.style.opacity = '0'; + frame.onload = function () { + setTimeout(function () { + try { + frame.contentWindow.onafterprint = cleanupPrintFrame; + frame.contentWindow.focus(); + frame.contentWindow.print(); + } catch (e) { + window.print(); + } + }, 500); + }; + frame.src = url; + document.body.appendChild(frame); + var cleaned = false; + function cleanupPrintFrame() { + if (cleaned) { + return; + } + cleaned = true; + if (frame && frame.parentNode) { + frame.parentNode.removeChild(frame); + } + window.removeEventListener('afterprint', cleanupPrintFrame); + } + window.addEventListener('afterprint', cleanupPrintFrame); + setTimeout(cleanupPrintFrame, 300000); + } + window.addEventListener('message', function (event) { + if (!event.data || event.data.type !== 'fastreport-print-finished') { + return; + } + var frame = document.getElementById(event.data.frameId); + if (frame && frame.parentNode) { + frame.parentNode.removeChild(frame); + } + }); diff --git a/SGGL/FineUIPro.Web/CLGL/InputMaster.aspx.cs b/SGGL/FineUIPro.Web/CLGL/InputMaster.aspx.cs index a8f8f4ce..c35657c3 100644 --- a/SGGL/FineUIPro.Web/CLGL/InputMaster.aspx.cs +++ b/SGGL/FineUIPro.Web/CLGL/InputMaster.aspx.cs @@ -368,7 +368,7 @@ namespace FineUIPro.Web.CLGL { ShowNotify("请选择要打印的项", MessageBoxIcon.Warning); return; - } + } BLL.FastReportService.ResetData(); var query = new Tw_InputDetailBarCodeOutput @@ -394,7 +394,9 @@ namespace FineUIPro.Web.CLGL string initTemplatePath = "File\\Fastreport\\材料入库条码.frx"; if (File.Exists(rootPath + initTemplatePath)) { - PageContext.RegisterStartupScript(Window2.GetShowReference(String.Format("~/Controls/Fastreport.aspx?ReportPath={0}", rootPath + initTemplatePath))); + //PageContext.RegisterStartupScript(Window2.GetShowReference(String.Format("~/Controls/Fastreport.aspx?ReportPath={0}", rootPath + initTemplatePath))); + string printUrl = ResolveUrl(BLL.FastReportService.ExportReport(rootPath + initTemplatePath)); + PageContext.RegisterStartupScript(String.Format("printByHiddenFrame('{0}');", printUrl)); } } diff --git a/SGGL/FineUIPro.Web/Controls/Fastreport.aspx.cs b/SGGL/FineUIPro.Web/Controls/Fastreport.aspx.cs index 26e751dc..9165301e 100644 --- a/SGGL/FineUIPro.Web/Controls/Fastreport.aspx.cs +++ b/SGGL/FineUIPro.Web/Controls/Fastreport.aspx.cs @@ -1,4 +1,5 @@ using BLL; +using FastReport.Web; using System; using System.Collections.Generic; using System.Data; @@ -61,7 +62,8 @@ namespace FineUIPro.Web.Controls } } WebReport1.ReportFile = ReportPath; - WebReport1.Prepare(); + WebReport1.PdfShowPrintDialog = false; + WebReport1.Prepare(); // WebReport1.ExportPdf(); } private void WebReport1_StartReport(object sender, EventArgs e) diff --git a/SGGL/FineUIPro.Web/File/Excel/DataOut/管道数据表导出模板.xlsx b/SGGL/FineUIPro.Web/File/Excel/DataOut/管道数据表导出模板.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6662b4ad95f945be7a058d01c441268f9ffe9d18 GIT binary patch literal 9426 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 --> - + \ No newline at end of file diff --git a/SGGL/FineUIPro.Web/Global.asax.cs b/SGGL/FineUIPro.Web/Global.asax.cs index 73682871..79486a86 100644 --- a/SGGL/FineUIPro.Web/Global.asax.cs +++ b/SGGL/FineUIPro.Web/Global.asax.cs @@ -66,6 +66,7 @@ BLL.MonitorService.StartMonitorEve(); //BLL.YunMouService.StartMonitor(); //BLL.MonitorService.StartPersonQuarterCheck(); + BLL.FastReportService.StartTempReportCleanupMonitor(); QuartzServices.Init(); } catch (Exception ex) diff --git a/SGGL/FineUIPro.Web/HJGL/InfoQuery/PipelineQuery.aspx b/SGGL/FineUIPro.Web/HJGL/InfoQuery/PipelineQuery.aspx index 6a31d251..26d7173d 100644 --- a/SGGL/FineUIPro.Web/HJGL/InfoQuery/PipelineQuery.aspx +++ b/SGGL/FineUIPro.Web/HJGL/InfoQuery/PipelineQuery.aspx @@ -76,6 +76,9 @@ + + diff --git a/SGGL/FineUIPro.Web/HJGL/InfoQuery/PipelineQuery.aspx.cs b/SGGL/FineUIPro.Web/HJGL/InfoQuery/PipelineQuery.aspx.cs index b05fdf1d..fd0373ad 100644 --- a/SGGL/FineUIPro.Web/HJGL/InfoQuery/PipelineQuery.aspx.cs +++ b/SGGL/FineUIPro.Web/HJGL/InfoQuery/PipelineQuery.aspx.cs @@ -406,6 +406,179 @@ namespace FineUIPro.Web.HJGL.InfoQuery // return sb.ToString(); // } + + /// + /// 管道数据表导出按钮 + /// + protected void btnPipelineDataOut_Click(object sender, EventArgs e) + { + var pipelines = GetCurrentPipelineList(); + if (pipelines.Count == 0) + { + ShowNotify("没有可导出的管线数据!", MessageBoxIcon.Warning); + return; + } + + string templatePath = Funs.RootPath + @"File\Excel\DataOut\管道数据表导出模板.xlsx"; + if (!File.Exists(templatePath)) + { + ShowNotify("导出模板不存在!", MessageBoxIcon.Warning); + return; + } + + string tempPath = Funs.RootPath + @"File\Excel\Temp\管道数据表.xlsx"; + tempPath = tempPath.Replace(".xlsx", string.Format("{0:yyyy-MM-dd-HH-mm-ss}", DateTime.Now) + ".xlsx"); + Directory.CreateDirectory(Path.GetDirectoryName(tempPath)); + + var pipelineIds = pipelines.Select(x => x.PipelineId).Where(x => !string.IsNullOrEmpty(x)).ToList(); + var hotPipelineIds = Funs.DB.HJGL_WeldJoint + .Where(x => x.ProjectId == this.CurrUser.LoginProjectId && x.PipelineId != null && pipelineIds.Contains(x.PipelineId) && x.IsHotProess == true) + .Select(x => x.PipelineId) + .Distinct() + .ToList(); + var hotPipelineIdSet = new HashSet(hotPipelineIds); + + var pipelineData = pipelines.Select((x, index) => new + { + No = index + 1, + PipelineCode = SafeText(x.PipelineCode), + PipingClassCode = SafeText(x.PipingClassCode), + MediumName = SafeText(x.MediumName), + PressurePipingClassCode = SafeText(x.PressurePipingClassCode), + DesignPress = SafeText(x.DesignPress), + DesignTemperature = SafeText(x.DesignTemperature), + OperatePressure = "/", + OperateTemperature = "/", + PWHT = hotPipelineIdSet.Contains(x.PipelineId) ? "PWHT" : "/", + DetectionRateCode = SafeText(x.DetectionRateCode), + InsulationType = "/", + Tracing = "/", + TestType = "/", + TestMethod = SafeText(x.TestMediumCode), + TestPressure = SafeText(x.TestPressure) + }).ToList(); + + var weldJoints = Funs.DB.View_HJGL_WeldJoint + .Where(x => x.ProjectId == this.CurrUser.LoginProjectId && x.PipelineId != null && pipelineIds.Contains(x.PipelineId)) + .OrderBy(x => x.PipelineCode) + .ThenBy(x => x.WeldJointCode) + .ToList(); + var weldJointIds = weldJoints.Select(x => x.WeldJointId).Where(x => !string.IsNullOrEmpty(x)).ToList(); + var pointJointIds = Funs.DB.HJGL_Batch_PointBatchItem + .Where(x => x.WeldJointId != null && weldJointIds.Contains(x.WeldJointId) && x.PointState != null) + .Select(x => x.WeldJointId) + .Distinct() + .ToList(); + var pointJointIdSet = new HashSet(pointJointIds); + + var weldJointData = weldJoints.Select((x, index) => new + { + No = index + 1, + SingleNumber = SafeText(x.SingleNumber), + WeldJointCode = SafeText(x.WeldJointCode), + Dia = x.Dia, + Thickness = x.Thickness, + MaterialCode = SafeText(x.MaterialCode), + WeldingDate = SafeText(x.WeldingDate), + WelderName = JoinTexts(x.BackingWelderName, x.CoverWelderName), + CertificateNo = "/", + WelderCode = JoinTexts(x.BackingWelderCode, x.CoverWelderCode), + WelderExamDate = "/", + TestJointDate = "/", + RootWeldingData = FormatWeldingData(x.WeldingMethodCode, x.WeldingRodCode, x.WeldingWireCode), + RemainingWeldingData = FormatWeldingData(x.WeldingMethodCode, x.WeldingRodCode, x.WeldingWireCode), + // P列和V列按“管线需要热处理”判断,不按单个焊口判断。 + PWHT = hotPipelineIdSet.Contains(x.PipelineId) ? "PWHT" : "/", + HotProcessAccept = hotPipelineIdSet.Contains(x.PipelineId) ? "ACC." : "/", + // AB列按点口记录判断;AC列按管道等级1级判断,否则保持模板要求的“/”。 + PointAccept = IsPointed(x.IsPoint, x.WeldJointId, pointJointIdSet) ? "ACC." : "/", + PipingClassAccept = IsFirstLevelPipingClass(x.PipingClassCode) ? "ACC." : "/" + }).ToList(); + + var value = new Dictionary + { + ["PipelineData"] = pipelineData, + ["WeldJointData"] = weldJointData + }; + + MiniExcel.SaveAsByTemplate(tempPath, templatePath, value); + DownTempFile(tempPath, "管道数据表.xlsx"); + } + + /// + /// 按当前页面筛选条件重新获取导出管线,避免使用跨用户共享的静态缓存。 + /// + private List GetCurrentPipelineList() + { + Model.View_HJGL_Pipeline model = new Model.View_HJGL_Pipeline(); + model.ProjectId = this.CurrUser.LoginProjectId; + model.UnitWorkId = this.tvControlItem.SelectedNodeID; + model.PipelineCode = this.txtPipelineCode.Text.Trim(); + model.IsFinished = null; + if (drpIsFinish.SelectedValue == "1") + { + model.IsFinished = true; + } + if (drpIsFinish.SelectedValue == "0") + { + model.IsFinished = false; + } + return BLL.PipelineService.GetView_HJGL_Pipelines(model); + } + + private void DownTempFile(string path, string fileName) + { + FileInfo info = new FileInfo(path); + long fileSize = info.Length; + System.Web.HttpContext.Current.Response.Clear(); + System.Web.HttpContext.Current.Response.ContentType = "application/x-zip-compressed"; + System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + System.Web.HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8)); + System.Web.HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString()); + System.Web.HttpContext.Current.Response.TransmitFile(path, 0, fileSize); + System.Web.HttpContext.Current.Response.Flush(); + System.Web.HttpContext.Current.Response.Close(); + File.Delete(path); + } + + private static string SafeText(object value) + { + if (value == null) + { + return "/"; + } + string text = value.ToString(); + return string.IsNullOrWhiteSpace(text) ? "/" : text.Trim(); + } + + private static string JoinTexts(params string[] values) + { + var texts = values + .Where(x => !string.IsNullOrWhiteSpace(x)) + .Select(x => x.Trim()) + .Distinct() + .ToList(); + return texts.Count == 0 ? "/" : string.Join("/", texts); + } + + private static string FormatWeldingData(params string[] values) + { + return JoinTexts(values); + } + + private static bool IsPointed(string isPoint, string weldJointId, HashSet pointJointIdSet) + { + return pointJointIdSet.Contains(weldJointId) || isPoint == "1" || isPoint == "是" || isPoint == "True"; + } + + private static bool IsFirstLevelPipingClass(string pipingClassCode) + { + if (string.IsNullOrWhiteSpace(pipingClassCode)) + { + return false; + } + string code = pipingClassCode.Trim(); + return code == "1" || code == "1级" || code == "一级" || code == "Ⅰ级" || code == "Ⅰ"; + } #endregion protected string ConvertDetectionType(object detectionType) @@ -572,4 +745,4 @@ namespace FineUIPro.Web.HJGL.InfoQuery //ctlAuditFlow.BindData(); } } -} \ No newline at end of file +} diff --git a/SGGL/FineUIPro.Web/HJGL/InfoQuery/PipelineQuery.aspx.designer.cs b/SGGL/FineUIPro.Web/HJGL/InfoQuery/PipelineQuery.aspx.designer.cs index 93d00524..c499d441 100644 --- a/SGGL/FineUIPro.Web/HJGL/InfoQuery/PipelineQuery.aspx.designer.cs +++ b/SGGL/FineUIPro.Web/HJGL/InfoQuery/PipelineQuery.aspx.designer.cs @@ -182,6 +182,15 @@ namespace FineUIPro.Web.HJGL.InfoQuery { /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 /// protected global::FineUIPro.Button btnOut; + + /// + /// btnPipelineDataOut 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.Button btnPipelineDataOut; /// /// Grid1 控件。 diff --git a/SGGL/FineUIPro.Web/HJGL/PreWeld/CuttingCheck.aspx.designer.cs b/SGGL/FineUIPro.Web/HJGL/PreWeld/CuttingCheck.aspx.designer.cs index 1f0181e6..9d31f91d 100644 --- a/SGGL/FineUIPro.Web/HJGL/PreWeld/CuttingCheck.aspx.designer.cs +++ b/SGGL/FineUIPro.Web/HJGL/PreWeld/CuttingCheck.aspx.designer.cs @@ -1,4 +1,4 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // <自动生成> // 此代码由工具生成。 // diff --git a/SGGL/FineUIPro.Web/HJGL/PreWeld/CuttingCheckEdit.aspx.designer.cs b/SGGL/FineUIPro.Web/HJGL/PreWeld/CuttingCheckEdit.aspx.designer.cs index 940ccf53..d337f239 100644 --- a/SGGL/FineUIPro.Web/HJGL/PreWeld/CuttingCheckEdit.aspx.designer.cs +++ b/SGGL/FineUIPro.Web/HJGL/PreWeld/CuttingCheckEdit.aspx.designer.cs @@ -1,4 +1,4 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // <自动生成> // 此代码由工具生成。 // diff --git a/SGGL/FineUIPro.Web/HJGL/PreWeld/FitupCheck.aspx.designer.cs b/SGGL/FineUIPro.Web/HJGL/PreWeld/FitupCheck.aspx.designer.cs index 36fe2914..6ed60852 100644 --- a/SGGL/FineUIPro.Web/HJGL/PreWeld/FitupCheck.aspx.designer.cs +++ b/SGGL/FineUIPro.Web/HJGL/PreWeld/FitupCheck.aspx.designer.cs @@ -1,4 +1,4 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // <自动生成> // 此代码由工具生成。 // diff --git a/SGGL/FineUIPro.Web/HJGL/PreWeld/FitupCheckEdit.aspx.designer.cs b/SGGL/FineUIPro.Web/HJGL/PreWeld/FitupCheckEdit.aspx.designer.cs index 61e38245..988ac02b 100644 --- a/SGGL/FineUIPro.Web/HJGL/PreWeld/FitupCheckEdit.aspx.designer.cs +++ b/SGGL/FineUIPro.Web/HJGL/PreWeld/FitupCheckEdit.aspx.designer.cs @@ -1,4 +1,4 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // <自动生成> // 此代码由工具生成。 //