feat(hjgl): 增加焊接日志导出与管道预制汇总

补充俄文焊接日志导出和管道预制汇总报表,统一菜单、数据库脚本与导出模板,便于按日报或单位工程查看和交付施工统计数据。
This commit is contained in:
2026-08-26 15:30:34 +08:00
parent a0669475f1
commit ad6ef33ce2
13 changed files with 1041 additions and 1 deletions
+1
View File
@@ -461,6 +461,7 @@
<Compile Include="HJGL\TestPackage\TestPackagePrintService.cs" />
<Compile Include="HJGL\WeldingManage\HJGL_ComponentJointService.cs" />
<Compile Include="HJGL\WeldingManage\HJGL_WeldingReportService.cs" />
<Compile Include="HJGL\WeldingReport\PipePrefabricationSummaryService.cs" />
<Compile Include="HJGL\WeldingManage\PipelineComponentService.cs" />
<Compile Include="HJGL\WeldingManage\PipelineMatService.cs" />
<Compile Include="HJGL\WeldingManage\PipelineService.cs" />
@@ -1355,6 +1355,178 @@ namespace BLL
return list;
}
/// <summary>
/// 获取焊接日志导出数据;传日报ID时导出单份日报,否则按单位工程和月份导出。
/// </summary>
/// <param name="projectId">项目ID</param>
/// <param name="unitWorkId">单位工程ID</param>
/// <param name="weldingDailyId">焊接日报ID</param>
/// <param name="month">月份,格式为yyyy-MM</param>
/// <returns>仅包含俄文表头和业务数据的焊接日志</returns>
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<SqlParameter>
{
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<string, object> GetFileOutValueById(string WeldingDailyId)
{
var value = new Dictionary<string, object>();
@@ -0,0 +1,203 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
namespace BLL
{
/// <summary>
/// 管道预制汇总服务。
/// </summary>
public static class PipePrefabricationSummaryService
{
/// <summary>
/// 按单位、单位工程汇总管道预制达因。
/// </summary>
public static List<PipePrefabricationSummaryItem> GetSummary(
string projectId,
IEnumerable<string> 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<string>())
.Where(x => !string.IsNullOrWhiteSpace(x) && x != Const._Null)
.Distinct()
.ToList();
var parameters = new List<SqlParameter>
{
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<string>();
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]);
}
}
/// <summary>
/// 管道预制汇总行。
/// </summary>
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.##");
}
}
}