diff --git a/DataBase/版本日志/SGGLDB_V2026-08-21-lpf(管道预制汇总菜单脚本).sql b/DataBase/版本日志/SGGLDB_V2026-08-21-lpf(管道预制汇总菜单脚本).sql new file mode 100644 index 00000000..97997838 --- /dev/null +++ b/DataBase/版本日志/SGGLDB_V2026-08-21-lpf(管道预制汇总菜单脚本).sql @@ -0,0 +1,81 @@ +/* + 焊接数据分析:管道预制汇总菜单 + 可重复执行,已有菜单时同步修正名称、地址、父级和排序。 +*/ +DECLARE @MenuId NVARCHAR(50) = N'9A28D681-0C91-49B8-9A63-DA3FEEA25BC2'; +DECLARE @SuperMenuId NVARCHAR(50) = N'F3B157B7-9BEE-4150-80CB-087828F1C51D'; + +IF NOT EXISTS (SELECT 1 FROM dbo.Sys_Menu WHERE MenuId = @SuperMenuId) +BEGIN + RAISERROR(N'未找到父菜单“焊接数据分析”,请先执行焊接管理菜单初始化脚本。', 16, 1); + RETURN; +END; + +IF EXISTS (SELECT 1 FROM dbo.Sys_Menu WHERE MenuId = @MenuId) +BEGIN + UPDATE dbo.Sys_Menu + SET MenuName = N'管道预制汇总', + Icon = NULL, + Url = N'HJGL/WeldingReport/PipePrefabricationSummary.aspx', + SortIndex = 85, + SuperMenu = @SuperMenuId, + MenuType = N'Menu_HJGL', + IsOffice = 0, + IsEnd = 1, + IsUsed = 1 + WHERE MenuId = @MenuId; +END +ELSE +BEGIN + INSERT INTO dbo.Sys_Menu + ( + MenuId, + MenuName, + Icon, + Url, + SortIndex, + SuperMenu, + MenuType, + IsOffice, + IsEnd, + IsUsed + ) + VALUES + ( + @MenuId, + N'管道预制汇总', + NULL, + N'HJGL/WeldingReport/PipePrefabricationSummary.aspx', + 85, + @SuperMenuId, + N'Menu_HJGL', + 0, + 1, + 1 + ); +END; + +IF NOT EXISTS +( + SELECT 1 + FROM dbo.Sys_ButtonToMenu + WHERE MenuId = @MenuId + AND ButtonName = N'查看' +) +BEGIN + INSERT INTO dbo.Sys_ButtonToMenu + ( + ButtonToMenuId, + MenuId, + ButtonName, + SortIndex + ) + VALUES + ( + N'40D01F4E-D38C-4480-ABF3-5FE45C0E8650', + @MenuId, + N'查看', + 1 + ); +END; +GO diff --git a/SGGL/BLL/BLL.csproj b/SGGL/BLL/BLL.csproj index e3604353..d1747f31 100644 --- a/SGGL/BLL/BLL.csproj +++ b/SGGL/BLL/BLL.csproj @@ -461,6 +461,7 @@ + diff --git a/SGGL/BLL/HJGL/WeldingManage/WeldingDailyService.cs b/SGGL/BLL/HJGL/WeldingManage/WeldingDailyService.cs index 160fcfb8..e7f36855 100644 --- a/SGGL/BLL/HJGL/WeldingManage/WeldingDailyService.cs +++ b/SGGL/BLL/HJGL/WeldingManage/WeldingDailyService.cs @@ -1355,6 +1355,178 @@ namespace BLL return list; } + + /// + /// 获取焊接日志导出数据;传日报ID时导出单份日报,否则按单位工程和月份导出。 + /// + /// 项目ID + /// 单位工程ID + /// 焊接日报ID + /// 月份,格式为yyyy-MM + /// 仅包含俄文表头和业务数据的焊接日志 + public static DataTable GetWeldingLogExportData(string projectId, string unitWorkId, + string weldingDailyId, string month) + { + if (string.IsNullOrWhiteSpace(projectId) + || (string.IsNullOrWhiteSpace(unitWorkId) && string.IsNullOrWhiteSpace(weldingDailyId))) + { + return new DataTable(); + } + + DateTime monthStart = DateTime.MinValue; + if (string.IsNullOrWhiteSpace(weldingDailyId) + && !DateTime.TryParse(month + "-01", out monthStart)) + { + return new DataTable(); + } + + string condition; + var parameters = new List + { + new SqlParameter("@ProjectId", projectId) + }; + if (!string.IsNullOrWhiteSpace(weldingDailyId)) + { + condition = "jot.WeldingDailyId = @WeldingDailyId"; + parameters.Add(new SqlParameter("@WeldingDailyId", weldingDailyId)); + } + else + { + condition = @"jot.UnitWorkId = @UnitWorkId + AND jot.WeldingDateD >= @MonthStart + AND jot.WeldingDateD < @NextMonth"; + parameters.Add(new SqlParameter("@UnitWorkId", unitWorkId)); + parameters.Add(new SqlParameter("@MonthStart", monthStart.Date)); + parameters.Add(new SqlParameter("@NextMonth", monthStart.Date.AddMonths(1))); + } + + // 俄文日志列横跨焊口、日报、外观、热处理、硬度和无损检测,统一在服务层完成映射,页面仅负责下载。 + string sql = @" +SELECT ROW_NUMBER() OVER (ORDER BY jot.WeldingDateD, jot.PipelineCode, jot.WeldJointCode) AS C01, + CONCAT(jot.PipelineCode, '/', jot.WeldJointCode, + CASE WHEN ISNULL(jot.WeldTypeCode, '') = '' THEN '' ELSE ', ' + jot.WeldTypeCode END) AS C02, + CASE WHEN welder.BackingDisplay = welder.CoverDisplay THEN welder.BackingDisplay + WHEN welder.BackingDisplay = '' THEN welder.CoverDisplay + WHEN welder.CoverDisplay = '' THEN welder.BackingDisplay + ELSE welder.BackingDisplay + CHAR(10) + welder.CoverDisplay END AS C03, + REPLACE(ISNULL(jot.MaterialCode, ''), '/', ' / ') AS C04, + REPLACE(REPLACE( + COALESCE(NULLIF(jot.Specification, ''), + CONCAT(CONVERT(varchar(30), jot.Dia), N'×', CONVERT(varchar(30), jot.Thickness))), + N'Φ', ''), '*', N'×') AS C05, + CONVERT(varchar(10), jot.WeldingDateD, 104) AS C06, + ISNULL(jot.WeldingMethodCode, '') AS C07, + CONCAT( + CASE WHEN ISNULL(jot.WeldingWireCode, '') = '' THEN '' + ELSE jot.WeldingWireCode + CASE WHEN ISNULL(wire.Standard, '') = '' THEN '' ELSE ' (' + wire.Standard + ')' END END, + CASE WHEN ISNULL(jot.WeldingWireCode, '') = '' OR ISNULL(jot.WeldingRodCode, '') = '' THEN '' ELSE CHAR(10) END, + CASE WHEN ISNULL(jot.WeldingRodCode, '') = '' THEN '' + ELSE jot.WeldingRodCode + CASE WHEN ISNULL(rod.Standard, '') = '' THEN '' ELSE ' (' + rod.Standard + ')' END END) AS C08, + CASE WHEN appearance.PreheatTemperature IS NULL AND appearance.InterpassTemperature IS NULL + THEN CASE WHEN ISNULL(jot.PreTemperature, '') = '' THEN '' ELSE jot.PreTemperature + N' °C' END + WHEN appearance.InterpassTemperature IS NULL + THEN CONCAT(CONVERT(varchar(30), appearance.PreheatTemperature), N' °C') + WHEN appearance.PreheatTemperature IS NULL + THEN CONCAT(CONVERT(varchar(30), appearance.InterpassTemperature), N' °C') + ELSE CONCAT(CONVERT(varchar(30), appearance.PreheatTemperature), ' / ', + CONVERT(varchar(30), appearance.InterpassTemperature), N' °C') END AS C09, + N'' AS C10, + N'' AS C11, + N'' AS C12, + ISNULL(hotProcess.RecordChartNo, '') AS C13, + CONCAT( + CASE WHEN hardness.HardNessValue1 IS NULL THEN '' ELSE CONVERT(varchar(20), hardness.HardNessValue1) END, + CASE WHEN hardness.HardNessValue2 IS NULL THEN '' ELSE '/' + CONVERT(varchar(20), hardness.HardNessValue2) END, + CASE WHEN hardness.HardNessValue3 IS NULL THEN '' ELSE '/' + CONVERT(varchar(20), hardness.HardNessValue3) END, + CASE WHEN ISNULL(hardness.HardReportNo, '') = '' THEN '' ELSE ', ' + RTRIM(hardness.HardReportNo) END, + CASE WHEN hardness.ReportDate IS NULL THEN '' ELSE ', ' + CONVERT(varchar(10), hardness.ReportDate, 104) END) AS C14, + CASE WHEN appearance.IsQualified = 1 THEN N'Годен' + WHEN appearance.IsQualified = 0 THEN N'Не годен' + ELSE N'' END AS C15, + ISNULL(ndt.ResultText, '') AS C16, + N'' AS C17 +FROM dbo.View_HJGL_WeldJoint AS jot +LEFT JOIN dbo.Base_Consumables AS wire ON wire.ConsumablesId = jot.WeldingWire +LEFT JOIN dbo.Base_Consumables AS rod ON rod.ConsumablesId = jot.WeldingRod +OUTER APPLY +( + SELECT CONCAT(ISNULL(jot.BackingWelderName, ''), + CASE WHEN ISNULL(jot.BackingWelderCode, '') = '' THEN '' ELSE ' (' + jot.BackingWelderCode + ')' END) AS BackingDisplay, + CONCAT(ISNULL(jot.CoverWelderName, ''), + CASE WHEN ISNULL(jot.CoverWelderCode, '') = '' THEN '' ELSE ' (' + jot.CoverWelderCode + ')' END) AS CoverDisplay +) AS welder +OUTER APPLY +( + SELECT TOP 1 checkItem.IsQualified, checkItem.PreheatTemperature, checkItem.InterpassTemperature + FROM dbo.HJGL_WeldAppearanceCheck AS checkItem + WHERE checkItem.WeldJointId = jot.WeldJointId + ORDER BY checkItem.CheckTime DESC, checkItem.CreateTime DESC, checkItem.AppearanceCheckId DESC +) AS appearance +OUTER APPLY +( + SELECT TOP 1 report.RecordChartNo + FROM dbo.HJGL_HotProess_TrustItem AS trustItem + LEFT JOIN dbo.HJGL_HotProess_Report AS report + ON report.HotProessTrustItemId = trustItem.HotProessTrustItemId + WHERE trustItem.WeldJointId = jot.WeldJointId + ORDER BY report.ProessDate DESC, report.HotProessReportId DESC +) AS hotProcess +OUTER APPLY +( + SELECT TOP 1 report.HardReportNo, report.HardNessValue1, report.HardNessValue2, + report.HardNessValue3, hardTrust.ReportDate + FROM dbo.HJGL_Hard_TrustItem AS hardItem + LEFT JOIN dbo.HJGL_Hard_Report AS report ON report.HardTrustItemID = hardItem.HardTrustItemID + LEFT JOIN dbo.HJGL_Hard_Trust AS hardTrust ON hardTrust.HardTrustID = hardItem.HardTrustID + WHERE hardItem.WeldJointId = jot.WeldJointId + ORDER BY hardTrust.ReportDate DESC, report.SortIndex, report.HardReportId DESC +) AS hardness +OUTER APPLY +( + SELECT STUFF(( + SELECT CHAR(10) + CONCAT(ISNULL(detectionType.DetectionTypeCode, ''), + CASE ndeItem.CheckResult WHEN '1' THEN N': Годен' WHEN '2' THEN N': Не годен' ELSE '' END, + CASE WHEN ISNULL(ndeItem.NDEReportNo, nde.NDECode) IS NULL THEN '' + ELSE ', ' + ISNULL(ndeItem.NDEReportNo, nde.NDECode) END, + CASE WHEN ndeItem.ReportDate IS NULL THEN '' ELSE ', ' + CONVERT(varchar(10), ndeItem.ReportDate, 104) END) + FROM dbo.HJGL_Batch_BatchTrustItem AS trustItem + INNER JOIN dbo.HJGL_Batch_NDEItem AS ndeItem ON ndeItem.TrustBatchItemId = trustItem.TrustBatchItemId + LEFT JOIN dbo.HJGL_Batch_NDE AS nde ON nde.NDEID = ndeItem.NDEID + LEFT JOIN dbo.Base_DetectionType AS detectionType ON detectionType.DetectionTypeId = ndeItem.DetectionTypeId + WHERE trustItem.WeldJointId = jot.WeldJointId + ORDER BY ndeItem.ReportDate, ndeItem.NDEItemID + FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '') AS ResultText +) AS ndt +WHERE jot.ProjectId = @ProjectId AND " + condition; + + DataTable table = SQLHelper.GetDataTableRunText(sql, parameters.ToArray()); + string[] headers = + { + "№\r\nп/п", + "Обозначение сварного соединения по исполнительному чертежу, тип сварного соединения ГОСТ 16037", + "Ф.И.О.\r\nсварщика,\r\nличное\r\nклеймо", + "Марка стали (композиция марок\r\nсталей), НД, №№ сертификатов", + "Наружный диаметр элемента трубопровода и толщина стенки Dн×S, мм", + "Дата сварки, температурные условия в рабочей зоне,°С", + "Способ\r\nсварки", + "Сварочные материалы (марка электрода, сварочной проволоки, защитный газ, флюс), НД, №№ сертификатов", + "Режим\r\nпредварительного и\r\nсопутствующего\r\nподогрева", + "Отметка о контроле\r\nкорня\r\nшва", + "Стилоскопирование металла шва,\r\n№ заключения, дата", + "Ф.И.О. оператора- термиста, личное клеймо", + "№ диаграммы по журналу термообработки сварных соединений", + "Твердость металла шва, № заключения, дата", + "Отметка о годности сварного соединения по внешнему осмотру и измерениям", + "Способ и результаты неразрушающего контроля сварного соединения, № заключения, дата", + "Результаты измерения ферритной фазы в металле шва, № заключения, дата" + }; + for (int i = 0; i < headers.Length; i++) + { + table.Columns[i].ColumnName = headers[i]; + } + return table; + } + public static Dictionary GetFileOutValueById(string WeldingDailyId) { var value = new Dictionary(); diff --git a/SGGL/BLL/HJGL/WeldingReport/PipePrefabricationSummaryService.cs b/SGGL/BLL/HJGL/WeldingReport/PipePrefabricationSummaryService.cs new file mode 100644 index 00000000..6a2afcb8 --- /dev/null +++ b/SGGL/BLL/HJGL/WeldingReport/PipePrefabricationSummaryService.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; +using System.Linq; + +namespace BLL +{ + /// + /// 管道预制汇总服务。 + /// + public static class PipePrefabricationSummaryService + { + /// + /// 按单位、单位工程汇总管道预制达因。 + /// + public static List GetSummary( + string projectId, + IEnumerable unitWorkIds, + DateTime startDate, + DateTime endDate, + DateTime reportDate) + { + if (string.IsNullOrWhiteSpace(projectId)) + { + throw new ArgumentException("项目不能为空。", "projectId"); + } + + if (startDate.Date > endDate.Date) + { + throw new ArgumentException("开始日期不能晚于结束日期。"); + } + + var selectedUnitWorkIds = (unitWorkIds ?? Enumerable.Empty()) + .Where(x => !string.IsNullOrWhiteSpace(x) && x != Const._Null) + .Distinct() + .ToList(); + var parameters = new List + { + new SqlParameter("@ProjectId", projectId), + new SqlParameter("@StartDate", startDate.Date), + // 结束日期按整日包含,SQL 使用小于次日零点规避时间精度问题。 + new SqlParameter("@EndDateExclusive", endDate.Date.AddDays(1)), + // 报表日期 D 的昨日数据取 D-1,当日零点作为昨日区间的结束边界。 + new SqlParameter("@DailyStartDate", reportDate.Date.AddDays(-1)), + new SqlParameter("@ReportDate", reportDate.Date) + }; + + string unitWorkFilter = string.Empty; + if (selectedUnitWorkIds.Count > 0) + { + var parameterNames = new List(); + for (int index = 0; index < selectedUnitWorkIds.Count; index++) + { + string parameterName = "@UnitWorkId" + index; + parameterNames.Add(parameterName); + parameters.Add(new SqlParameter(parameterName, selectedUnitWorkIds[index])); + } + + unitWorkFilter = " AND unitWork.UnitWorkId IN (" + string.Join(",", parameterNames) + ")"; + } + + string sql = @" +SELECT + ISNULL(unitWork.UnitWorkName, '') AS UnitWorkName, + ISNULL(unitInfo.UnitCode, '') AS ConstructionUnitCode, + ISNULL(unitWork.UnitWorkCode, '') AS UnitWorkCode, + CAST(SUM(ISNULL(joint.Size, 0)) AS DECIMAL(19, 2)) AS TotalDrawingQuantity, + CAST(SUM(ISNULL(joint.Size, 0)) AS DECIMAL(19, 2)) AS IsoDrawingQuantity, + CAST(SUM(CASE WHEN joint.JointAttribute = N'预制口' THEN ISNULL(joint.Size, 0) ELSE 0 END) AS DECIMAL(19, 2)) AS WorkFrontQuantity, + CAST(SUM(CASE + WHEN joint.JointAttribute = N'预制口' + AND daily.WeldingDate < @EndDateExclusive + THEN ISNULL(joint.Size, 0) ELSE 0 END) AS DECIMAL(19, 2)) AS CompletedQuantity, + CAST(SUM(CASE + WHEN joint.JointAttribute = N'预制口' + AND daily.WeldingDate >= @StartDate + AND daily.WeldingDate < @EndDateExclusive + THEN ISNULL(joint.Size, 0) ELSE 0 END) AS DECIMAL(19, 2)) AS WeeklyQuantity, + CAST(SUM(CASE + WHEN joint.JointAttribute = N'预制口' + AND daily.WeldingDate >= @DailyStartDate + AND daily.WeldingDate < @ReportDate + THEN ISNULL(joint.Size, 0) ELSE 0 END) AS DECIMAL(19, 2)) AS DailyQuantity, + CAST(SUM(CASE + WHEN joint.JointAttribute = N'预制口' + AND daily.WeldingDate < @DailyStartDate + THEN ISNULL(joint.Size, 0) ELSE 0 END) AS DECIMAL(19, 2)) AS PreviousDayCumulativeQuantity, + CAST(SUM(CASE + WHEN joint.JointAttribute = N'预制口' + AND daily.WeldingDate < @StartDate + THEN ISNULL(joint.Size, 0) ELSE 0 END) AS DECIMAL(19, 2)) AS LastWeekCumulativeQuantity +FROM HJGL_WeldJoint joint +INNER JOIN HJGL_Pipeline pipeline ON pipeline.PipelineId = joint.PipelineId +INNER JOIN WBS_UnitWork unitWork ON unitWork.UnitWorkId = pipeline.UnitWorkId +LEFT JOIN Base_Unit unitInfo ON unitInfo.UnitId = unitWork.UnitId +LEFT JOIN HJGL_WeldingDaily daily ON daily.WeldingDailyId = joint.WeldingDailyId +WHERE pipeline.ProjectId = @ProjectId + AND pipeline.PipeArea = '1'" + unitWorkFilter + @" +GROUP BY unitWork.UnitWorkName, unitInfo.UnitCode, unitWork.UnitWorkCode +ORDER BY unitWork.UnitWorkName, unitWork.UnitWorkCode"; + + DataTable table = SQLHelper.GetDataTableRunText(sql, parameters.ToArray()); + return table.AsEnumerable().Select((row, index) => + { + string unitCode; + string blockCode; + ParseUnitAndBlock( + Convert.ToString(row["UnitWorkName"]), + Convert.ToString(row["ConstructionUnitCode"]), + Convert.ToString(row["UnitWorkCode"]), + out unitCode, + out blockCode); + + return new PipePrefabricationSummaryItem + { + RowKey = (index + 1).ToString(), + UnitCode = unitCode, + UnitWorkCode = blockCode, + // 当前模型没有独立的计划图纸达因字段,图纸总量按工厂预制管线设计焊口总达因统计。 + TotalDrawingQuantity = GetDecimal(row, "TotalDrawingQuantity"), + IsoDrawingQuantity = GetDecimal(row, "IsoDrawingQuantity"), + WorkFrontQuantity = GetDecimal(row, "WorkFrontQuantity"), + CompletedQuantity = GetDecimal(row, "CompletedQuantity"), + DailyQuantity = GetDecimal(row, "DailyQuantity"), + PreviousDayCumulativeQuantity = GetDecimal(row, "PreviousDayCumulativeQuantity"), + WeeklyQuantity = GetDecimal(row, "WeeklyQuantity"), + LastWeekCumulativeQuantity = GetDecimal(row, "LastWeekCumulativeQuantity"), + Note = string.Empty + }; + }).ToList(); + } + + private static void ParseUnitAndBlock( + string unitWorkName, + string fallbackUnitCode, + string fallbackBlockCode, + out string unitCode, + out string blockCode) + { + // 本项目单位工程名称按“Unit.Block”维护,报表需拆分成两个业务列。 + string[] segments = (unitWorkName ?? string.Empty).Split(new[] { '.' }, 2); + if (segments.Length == 2 + && !string.IsNullOrWhiteSpace(segments[0]) + && !string.IsNullOrWhiteSpace(segments[1])) + { + unitCode = segments[0].Trim(); + blockCode = segments[1].Trim(); + return; + } + + unitCode = fallbackUnitCode ?? string.Empty; + blockCode = fallbackBlockCode ?? string.Empty; + } + + private static decimal GetDecimal(DataRow row, string columnName) + { + return row.IsNull(columnName) ? 0M : Convert.ToDecimal(row[columnName]); + } + } + + /// + /// 管道预制汇总行。 + /// + public class PipePrefabricationSummaryItem + { + public string RowKey { get; set; } + public string UnitCode { get; set; } + public string UnitWorkCode { get; set; } + public decimal TotalDrawingQuantity { get; set; } + public decimal IsoDrawingQuantity { get; set; } + public decimal WorkFrontQuantity { get; set; } + public decimal CompletedQuantity { get; set; } + public decimal DailyQuantity { get; set; } + public decimal PreviousDayCumulativeQuantity { get; set; } + public decimal WeeklyQuantity { get; set; } + public decimal LastWeekCumulativeQuantity { get; set; } + public string Note { get; set; } + + public string TotalDrawingQuantityDisplay { get { return FormatQuantity(TotalDrawingQuantity); } } + public string IsoDrawingQuantityDisplay { get { return FormatQuantity(IsoDrawingQuantity); } } + public string WorkFrontQuantityDisplay { get { return FormatQuantity(WorkFrontQuantity); } } + public string CompletedQuantityDisplay { get { return FormatQuantity(CompletedQuantity); } } + public string DailyQuantityDisplay { get { return FormatQuantity(DailyQuantity); } } + public string PreviousDayCumulativeQuantityDisplay { get { return FormatQuantity(PreviousDayCumulativeQuantity); } } + public string WeeklyQuantityDisplay { get { return FormatQuantity(WeeklyQuantity); } } + public string LastWeekCumulativeQuantityDisplay { get { return FormatQuantity(LastWeekCumulativeQuantity); } } + public string QuantityCompleteRateDisplay + { + get + { + return TotalDrawingQuantity <= 0M + ? "0.00%" + : (CompletedQuantity * 100M / TotalDrawingQuantity).ToString("0.00") + "%"; + } + } + + public static string FormatQuantity(decimal quantity) + { + return quantity.ToString("#,##0.##"); + } + } +} diff --git a/SGGL/FineUIPro.Web/File/Excel/DataOut/管道预制汇总模板.xlsx b/SGGL/FineUIPro.Web/File/Excel/DataOut/管道预制汇总模板.xlsx new file mode 100644 index 00000000..6b509701 Binary files /dev/null and b/SGGL/FineUIPro.Web/File/Excel/DataOut/管道预制汇总模板.xlsx differ diff --git a/SGGL/FineUIPro.Web/FineUIPro.Web.csproj b/SGGL/FineUIPro.Web/FineUIPro.Web.csproj index 383227f4..7788a3ae 100644 --- a/SGGL/FineUIPro.Web/FineUIPro.Web.csproj +++ b/SGGL/FineUIPro.Web/FineUIPro.Web.csproj @@ -368,6 +368,7 @@ + @@ -1733,6 +1734,7 @@ + @@ -8279,7 +8281,7 @@ InPlanMaster.aspx - Component + ASPXCodeBehind InPlanMaster.aspx @@ -11689,6 +11691,13 @@ NDTWeeklyReport.aspx + + PipePrefabricationSummary.aspx + ASPXCodeBehind + + + PipePrefabricationSummary.aspx + PipePrefabricationRateStatistics.aspx ASPXCodeBehind diff --git a/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldReport.aspx b/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldReport.aspx index 7888c75b..dac41554 100644 --- a/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldReport.aspx +++ b/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldReport.aspx @@ -389,6 +389,9 @@ + + diff --git a/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldReport.aspx.cs b/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldReport.aspx.cs index 7a820fd4..8d532aa2 100644 --- a/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldReport.aspx.cs +++ b/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldReport.aspx.cs @@ -1,5 +1,7 @@ using BLL; using MiniExcelLibs; +using NPOI.SS.UserModel; +using NPOI.XSSF.UserModel; using System; using System.Collections.Generic; using System.Data; @@ -728,6 +730,135 @@ namespace FineUIPro.Web.HJGL.WeldingManage } } + /// + /// 导出俄文焊接日志。 + /// + protected void btnWeldingLogOut_Click(object sender, EventArgs e) + { + if (tvControlItem.SelectedNode == null + || (tvControlItem.SelectedNode.CommandName != "UnitWork" + && tvControlItem.SelectedNode.CommandName != "WeldingDaily")) + { + Alert.ShowInTop("请选择单位工程或焊接日报!", MessageBoxIcon.Warning); + return; + } + + string unitWorkId = null; + string weldingDailyId = null; + string fileName; + if (tvControlItem.SelectedNode.CommandName == "WeldingDaily") + { + weldingDailyId = tvControlItem.SelectedNodeID; + var daily = BLL.WeldingDailyService.GetPipeline_WeldingDailyByWeldingDailyId(weldingDailyId); + if (daily == null || daily.ProjectId != this.CurrUser.LoginProjectId) + { + Alert.ShowInTop("所选焊接日报不存在!", MessageBoxIcon.Warning); + return; + } + var unitWork = UnitWorkService.getUnitWorkByUnitWorkId(daily.UnitWorkId); + fileName = "焊接日志-" + (unitWork == null ? string.Empty : unitWork.UnitWorkName + "-") + + daily.WeldingDailyCode + ".xlsx"; + } + else + { + unitWorkId = tvControlItem.SelectedNodeID; + var unitWork = BLL.UnitWorkService.getUnitWorkByUnitWorkId(unitWorkId); + if (unitWork == null || unitWork.ProjectId != this.CurrUser.LoginProjectId) + { + Alert.ShowInTop("所选单位工程不存在!", MessageBoxIcon.Warning); + return; + } + fileName = "焊接日志-" + unitWork.UnitWorkName + "-" + txtMonth.Text.Trim() + ".xlsx"; + } + + DataTable data = BLL.WeldingDailyService.GetWeldingLogExportData( + this.CurrUser.LoginProjectId, unitWorkId, weldingDailyId, txtMonth.Text.Trim()); + if (data.Rows.Count == 0) + { + Alert.ShowInTop("无数据,无法导出!", MessageBoxIcon.Warning); + return; + } + + byte[] fileBytes; + var workbook = new XSSFWorkbook(); + using (var stream = new MemoryStream()) + { + ISheet sheet = workbook.CreateSheet("Сварочный журнал"); + ICellStyle headerStyle = workbook.CreateCellStyle(); + headerStyle.Alignment = HorizontalAlignment.Center; + headerStyle.VerticalAlignment = VerticalAlignment.Center; + headerStyle.WrapText = true; + headerStyle.BorderTop = BorderStyle.Thin; + headerStyle.BorderRight = BorderStyle.Thin; + headerStyle.BorderBottom = BorderStyle.Thin; + headerStyle.BorderLeft = BorderStyle.Thin; + IFont headerFont = workbook.CreateFont(); + headerFont.IsBold = true; + headerFont.FontHeightInPoints = 10; + headerStyle.SetFont(headerFont); + + ICellStyle dataStyle = workbook.CreateCellStyle(); + dataStyle.Alignment = HorizontalAlignment.Center; + dataStyle.VerticalAlignment = VerticalAlignment.Center; + dataStyle.WrapText = true; + dataStyle.BorderTop = BorderStyle.Thin; + dataStyle.BorderRight = BorderStyle.Thin; + dataStyle.BorderBottom = BorderStyle.Thin; + dataStyle.BorderLeft = BorderStyle.Thin; + + IRow headerRow = sheet.CreateRow(0); + headerRow.HeightInPoints = 90; + for (int columnIndex = 0; columnIndex < data.Columns.Count; columnIndex++) + { + ICell cell = headerRow.CreateCell(columnIndex); + cell.SetCellValue(data.Columns[columnIndex].ColumnName); + cell.CellStyle = headerStyle; + } + + for (int rowIndex = 0; rowIndex < data.Rows.Count; rowIndex++) + { + IRow row = sheet.CreateRow(rowIndex + 1); + row.HeightInPoints = 30; + for (int columnIndex = 0; columnIndex < data.Columns.Count; columnIndex++) + { + ICell cell = row.CreateCell(columnIndex); + object value = data.Rows[rowIndex][columnIndex]; + if (columnIndex == 0 && value != DBNull.Value) + { + cell.SetCellValue(Convert.ToDouble(value)); + } + else + { + cell.SetCellValue(value == DBNull.Value ? string.Empty : value.ToString()); + } + cell.CellStyle = dataStyle; + } + } + + int[] columnWidths = { 6, 45, 25, 35, 25, 25, 16, 45, 24, 18, 26, 24, 24, 28, 35, 45, 35 }; + for (int i = 0; i < columnWidths.Length; i++) + { + sheet.SetColumnWidth(i, columnWidths[i] * 256); + } + sheet.CreateFreezePane(0, 1); + sheet.FitToPage = true; + sheet.PrintSetup.Landscape = true; + sheet.PrintSetup.FitWidth = 1; + workbook.Write(stream); + fileBytes = stream.ToArray(); + } + + HttpResponse response = HttpContext.Current.Response; + response.Clear(); + response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + response.AddHeader("Content-Disposition", "attachment;filename=" + + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8)); + response.AddHeader("Content-Length", fileBytes.Length.ToString()); + response.BinaryWrite(fileBytes); + response.Flush(); + HttpContext.Current.ApplicationInstance.CompleteRequest(); + } + protected void btnMenuDeleteDetail_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(Grid1.SelectedRowID)) diff --git a/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldReport.aspx.designer.cs b/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldReport.aspx.designer.cs index bd94fb21..5eca6ab7 100644 --- a/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldReport.aspx.designer.cs +++ b/SGGL/FineUIPro.Web/HJGL/WeldingManage/WeldReport.aspx.designer.cs @@ -469,6 +469,15 @@ namespace FineUIPro.Web.HJGL.WeldingManage /// protected global::FineUIPro.MenuButton btnMenuOut; + /// + /// btnMenuWeldingLogOut 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.MenuButton btnMenuWeldingLogOut; + /// /// btnMenuDelete 控件。 /// diff --git a/SGGL/FineUIPro.Web/HJGL/WeldingReport/PipePrefabricationSummary.aspx b/SGGL/FineUIPro.Web/HJGL/WeldingReport/PipePrefabricationSummary.aspx new file mode 100644 index 00000000..989a2224 --- /dev/null +++ b/SGGL/FineUIPro.Web/HJGL/WeldingReport/PipePrefabricationSummary.aspx @@ -0,0 +1,102 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="PipePrefabricationSummary.aspx.cs" Inherits="FineUIPro.Web.HJGL.WeldingReport.PipePrefabricationSummary" %> + + + + + 管道预制汇总 + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SGGL/FineUIPro.Web/HJGL/WeldingReport/PipePrefabricationSummary.aspx.cs b/SGGL/FineUIPro.Web/HJGL/WeldingReport/PipePrefabricationSummary.aspx.cs new file mode 100644 index 00000000..9c2db08f --- /dev/null +++ b/SGGL/FineUIPro.Web/HJGL/WeldingReport/PipePrefabricationSummary.aspx.cs @@ -0,0 +1,194 @@ +using BLL; +using MiniExcelLibs; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace FineUIPro.Web.HJGL.WeldingReport +{ + public partial class PipePrefabricationSummary : PageBase + { + protected void Page_Load(object sender, EventArgs e) + { + if (!IsPostBack) + { + UnitWorkService.InitUnitWorkDropDownList(drpUnitWork, CurrUser.LoginProjectId, false); + DateTime today = DateTime.Today; + int daysSinceMonday = ((int)today.DayOfWeek + 6) % 7; + dpReportDate.SelectedDate = today; + dpStartDate.SelectedDate = today.AddDays(-daysSinceMonday); + dpEndDate.SelectedDate = today.AddDays(6 - daysSinceMonday); + BindGrid(); + } + } + + protected void btnQuery_Click(object sender, EventArgs e) + { + BindGrid(); + } + + protected void btnExport_Click(object sender, EventArgs e) + { + DateTime reportDate; + DateTime startDate; + DateTime endDate; + if (!TryGetFilterDates(out reportDate, out startDate, out endDate)) + { + return; + } + + string templatePath = Path.Combine(Funs.RootPath, "File", "Excel", "DataOut", "管道预制汇总模板.xlsx"); + if (!File.Exists(templatePath)) + { + ShowNotify("未找到管道预制汇总导出模板!", MessageBoxIcon.Warning); + return; + } + + List rows = GetSummary(reportDate, startDate, endDate); + var value = CreateExportValue(rows, reportDate); + string fileName = string.Format( + "管道预制汇总_{0:yyyyMMdd}_{1:yyyyMMdd}-{2:yyyyMMdd}.xlsx", + reportDate, + startDate, + endDate); + string filePath = Path.Combine(Funs.RootPath, "File", "Excel", "Temp", Guid.NewGuid().ToString("N") + ".xlsx"); + Directory.CreateDirectory(Path.GetDirectoryName(filePath)); + MiniExcel.SaveAsByTemplate(filePath, templatePath, value); + DownloadExcel(filePath, fileName); + } + + private void BindGrid() + { + DateTime reportDate; + DateTime startDate; + DateTime endDate; + if (!TryGetFilterDates(out reportDate, out startDate, out endDate)) + { + return; + } + + List rows = GetSummary(reportDate, startDate, endDate); + Grid1.RecordCount = rows.Count; + Grid1.DataSource = rows; + Grid1.DataBind(); + BindSummary(rows); + } + + private List GetSummary( + DateTime reportDate, + DateTime startDate, + DateTime endDate) + { + string[] unitWorkIds = drpUnitWork.SelectedValueArray + .Where(x => !string.IsNullOrWhiteSpace(x) && x != Const._Null) + .ToArray(); + return PipePrefabricationSummaryService.GetSummary( + CurrUser.LoginProjectId, + unitWorkIds, + startDate, + endDate, + reportDate); + } + + private bool TryGetFilterDates( + out DateTime reportDate, + out DateTime startDate, + out DateTime endDate) + { + reportDate = DateTime.MinValue; + startDate = DateTime.MinValue; + endDate = DateTime.MinValue; + if (!dpReportDate.SelectedDate.HasValue) + { + ShowNotify("请选择报表日期!", MessageBoxIcon.Warning); + return false; + } + + if (!dpStartDate.SelectedDate.HasValue || !dpEndDate.SelectedDate.HasValue) + { + ShowNotify("请选择完整的日期范围!", MessageBoxIcon.Warning); + return false; + } + + reportDate = dpReportDate.SelectedDate.Value.Date; + startDate = dpStartDate.SelectedDate.Value.Date; + endDate = dpEndDate.SelectedDate.Value.Date; + if (startDate > endDate) + { + ShowNotify("开始日期不能晚于结束日期!", MessageBoxIcon.Warning); + return false; + } + + return true; + } + + private void BindSummary(ICollection rows) + { + decimal totalDrawing = rows.Sum(x => x.TotalDrawingQuantity); + decimal completed = rows.Sum(x => x.CompletedQuantity); + JObject summary = new JObject + { + { "UnitCode", string.Empty }, + { "UnitWorkCode", "Total" }, + { "TotalDrawingQuantity", PipePrefabricationSummaryItem.FormatQuantity(totalDrawing) }, + { "IsoDrawingQuantity", PipePrefabricationSummaryItem.FormatQuantity(rows.Sum(x => x.IsoDrawingQuantity)) }, + { "WorkFrontQuantity", PipePrefabricationSummaryItem.FormatQuantity(rows.Sum(x => x.WorkFrontQuantity)) }, + { "CompletedQuantity", PipePrefabricationSummaryItem.FormatQuantity(completed) }, + { "QuantityCompleteRate", GetCompleteRate(completed, totalDrawing) }, + { "DailyQuantity", PipePrefabricationSummaryItem.FormatQuantity(rows.Sum(x => x.DailyQuantity)) }, + { "PreviousDayCumulativeQuantity", PipePrefabricationSummaryItem.FormatQuantity(rows.Sum(x => x.PreviousDayCumulativeQuantity)) }, + { "WeeklyQuantity", PipePrefabricationSummaryItem.FormatQuantity(rows.Sum(x => x.WeeklyQuantity)) }, + { "LastWeekCumulativeQuantity", PipePrefabricationSummaryItem.FormatQuantity(rows.Sum(x => x.LastWeekCumulativeQuantity)) }, + { "Note", string.Empty } + }; + Grid1.SummaryData = summary; + } + + private static string GetCompleteRate(decimal completed, decimal totalDrawing) + { + return totalDrawing <= 0M ? "0.00%" : (completed * 100M / totalDrawing).ToString("0.00") + "%"; + } + + private static Dictionary CreateExportValue( + ICollection rows, + DateTime reportDate) + { + decimal totalDrawing = rows.Sum(x => x.TotalDrawingQuantity); + decimal completed = rows.Sum(x => x.CompletedQuantity); + // 只向模板上半部分的数据占位符传值;下方“陕西化建人力统计表”保持模板原样空白。 + return new Dictionary + { + { "ReportDate", reportDate.ToString("yyyy-MM-dd") }, + { "Data", rows }, + // MiniExcel 1.31.3 的普通对象不支持模板中的嵌套属性,合计值使用扁平占位符。 + { "TotalUnitCode", string.Empty }, + { "TotalUnitWorkCode", "Total" }, + { "TotalDrawingQuantity", totalDrawing }, + { "TotalIsoDrawingQuantity", rows.Sum(x => x.IsoDrawingQuantity) }, + { "TotalWorkFrontQuantity", rows.Sum(x => x.WorkFrontQuantity) }, + { "TotalCompletedQuantity", completed }, + { "TotalQuantityCompleteRate", GetCompleteRate(completed, totalDrawing) }, + { "TotalDailyQuantity", rows.Sum(x => x.DailyQuantity) }, + { "TotalPreviousDayCumulativeQuantity", rows.Sum(x => x.PreviousDayCumulativeQuantity) }, + { "TotalWeeklyQuantity", rows.Sum(x => x.WeeklyQuantity) }, + { "TotalLastWeekCumulativeQuantity", rows.Sum(x => x.LastWeekCumulativeQuantity) }, + { "TotalNote", string.Empty } + }; + } + + private void DownloadExcel(string filePath, string fileName) + { + FileInfo file = new FileInfo(filePath); + Response.Clear(); + Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + Response.AddHeader("Content-Disposition", "attachment;filename=" + System.Web.HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8)); + Response.AddHeader("Content-Length", file.Length.ToString()); + Response.TransmitFile(filePath, 0, file.Length); + Response.Flush(); + File.Delete(filePath); + Response.End(); + } + } +} diff --git a/SGGL/FineUIPro.Web/HJGL/WeldingReport/PipePrefabricationSummary.aspx.designer.cs b/SGGL/FineUIPro.Web/HJGL/WeldingReport/PipePrefabricationSummary.aspx.designer.cs new file mode 100644 index 00000000..94bdc8be --- /dev/null +++ b/SGGL/FineUIPro.Web/HJGL/WeldingReport/PipePrefabricationSummary.aspx.designer.cs @@ -0,0 +1,134 @@ +//------------------------------------------------------------------------------ +// <自动生成> +// 此代码由工具生成。 +// +// 对此文件的更改可能导致不正确的行为,如果 +// 重新生成代码,则所做更改将丢失。 +// +//------------------------------------------------------------------------------ + +namespace FineUIPro.Web.HJGL.WeldingReport +{ + + + public partial class PipePrefabricationSummary + { + + /// + /// form1 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::System.Web.UI.HtmlControls.HtmlForm form1; + + /// + /// PageManager1 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.PageManager PageManager1; + + /// + /// Panel1 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.Panel Panel1; + + /// + /// Grid1 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.Grid Grid1; + + /// + /// Toolbar1 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.Toolbar Toolbar1; + + /// + /// drpUnitWork 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.DropDownList drpUnitWork; + + /// + /// dpReportDate 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.DatePicker dpReportDate; + + /// + /// dpStartDate 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.DatePicker dpStartDate; + + /// + /// lblDateSeparator 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.Label lblDateSeparator; + + /// + /// dpEndDate 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.DatePicker dpEndDate; + + /// + /// ToolbarFill1 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.ToolbarFill ToolbarFill1; + + /// + /// btnQuery 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.Button btnQuery; + + /// + /// btnExport 控件。 + /// + /// + /// 自动生成的字段。 + /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。 + /// + protected global::FineUIPro.Button btnExport; + } +} diff --git a/SGGL/FineUIPro.Web/common/Menu_HJGL.xml b/SGGL/FineUIPro.Web/common/Menu_HJGL.xml index ef0f3f00..67a34655 100644 --- a/SGGL/FineUIPro.Web/common/Menu_HJGL.xml +++ b/SGGL/FineUIPro.Web/common/Menu_HJGL.xml @@ -92,6 +92,7 @@ +