Files
SGGL_SHJ/SGGL/BLL/HJGL/WeldingReport/PipePrefabricationSummaryService.cs
T
lpf ad6ef33ce2 feat(hjgl): 增加焊接日志导出与管道预制汇总
补充俄文焊接日志导出和管道预制汇总报表,统一菜单、数据库脚本与导出模板,便于按日报或单位工程查看和交付施工统计数据。
2026-08-26 15:30:34 +08:00

204 lines
9.1 KiB
C#

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.##");
}
}
}