|
|
|
|
@ -198,5 +198,306 @@ namespace CncRepository.Impl
|
|
|
|
|
return conn.Query<DailyProduction>(sql, new { Start = startDate, End = endDate, Top = top }).ToList();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 三维度产量报表
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 机床维度统计卡片(从cnc_production_segment实时计算)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public MachineProductionSummaryResponse GetMachineSummary(DateTime startDate, DateTime endDate, int? workshopId)
|
|
|
|
|
{
|
|
|
|
|
using (var conn = CreateConnection())
|
|
|
|
|
{
|
|
|
|
|
string sql = @"SELECT COALESCE(SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity
|
|
|
|
|
ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END), 0) AS TotalQuantity,
|
|
|
|
|
COUNT(DISTINCT seg.machine_id) AS RunningMachineCount
|
|
|
|
|
FROM cnc_production_segment seg
|
|
|
|
|
LEFT JOIN cnc_machine m ON seg.machine_id = m.id
|
|
|
|
|
WHERE seg.production_date BETWEEN @Start AND @End";
|
|
|
|
|
|
|
|
|
|
var parameters = new DynamicParameters();
|
|
|
|
|
parameters.Add("Start", startDate);
|
|
|
|
|
parameters.Add("End", endDate);
|
|
|
|
|
|
|
|
|
|
if (workshopId.HasValue)
|
|
|
|
|
{
|
|
|
|
|
sql += " AND m.workshop_id = @WorkshopId";
|
|
|
|
|
parameters.Add("WorkshopId", workshopId.Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var result = conn.QuerySingleOrDefault<MachineProductionSummaryResponse>(sql, parameters);
|
|
|
|
|
if (result == null)
|
|
|
|
|
{
|
|
|
|
|
return new MachineProductionSummaryResponse();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算平均单机产量
|
|
|
|
|
if (result.RunningMachineCount > 0)
|
|
|
|
|
{
|
|
|
|
|
result.AvgPerMachine = Math.Round((decimal)result.TotalQuantity / result.RunningMachineCount, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询最高单产机床名称
|
|
|
|
|
string topSql = @"SELECT m.name FROM cnc_production_segment seg
|
|
|
|
|
LEFT JOIN cnc_machine m ON seg.machine_id = m.id
|
|
|
|
|
WHERE seg.production_date BETWEEN @Start AND @End";
|
|
|
|
|
if (workshopId.HasValue)
|
|
|
|
|
{
|
|
|
|
|
topSql += " AND m.workshop_id = @WorkshopId";
|
|
|
|
|
}
|
|
|
|
|
topSql += @" GROUP BY seg.machine_id
|
|
|
|
|
ORDER BY SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END) DESC LIMIT 1";
|
|
|
|
|
result.TopMachineName = conn.ExecuteScalar<string>(topSql, parameters) ?? "";
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 机床维度明细列表(按机床+程序聚合,产量降序)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public List<MachineProductionListItem> GetMachineList(DateTime startDate, DateTime endDate, int? workshopId, int? machineId)
|
|
|
|
|
{
|
|
|
|
|
using (var conn = CreateConnection())
|
|
|
|
|
{
|
|
|
|
|
string sql = @"SELECT m.name AS MachineName, seg.program_name AS ProgramName,
|
|
|
|
|
SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity
|
|
|
|
|
ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END) AS TotalQuantity,
|
|
|
|
|
cr_runtime.run_hours AS RunTime
|
|
|
|
|
FROM cnc_production_segment seg
|
|
|
|
|
LEFT JOIN cnc_machine m ON seg.machine_id = m.id
|
|
|
|
|
LEFT JOIN (
|
|
|
|
|
SELECT cr.machine_id, DATE(cr.collect_time) AS d,
|
|
|
|
|
COALESCE(ROUND(SUM(max_min.delta)/3600,1), 0) AS run_hours
|
|
|
|
|
FROM cnc_collect_record cr
|
|
|
|
|
JOIN (
|
|
|
|
|
SELECT machine_id, DATE(collect_time) AS dd, MAX(cutting_time)-MIN(cutting_time) AS delta
|
|
|
|
|
FROM cnc_collect_record GROUP BY machine_id, DATE(collect_time)
|
|
|
|
|
) max_min ON cr.machine_id = max_min.machine_id AND DATE(cr.collect_time) = max_min.dd
|
|
|
|
|
GROUP BY cr.machine_id, DATE(cr.collect_time)
|
|
|
|
|
) cr_runtime ON cr_runtime.machine_id = seg.machine_id AND cr_runtime.d = seg.production_date
|
|
|
|
|
WHERE seg.production_date BETWEEN @Start AND @End";
|
|
|
|
|
|
|
|
|
|
var parameters = new DynamicParameters();
|
|
|
|
|
parameters.Add("Start", startDate);
|
|
|
|
|
parameters.Add("End", endDate);
|
|
|
|
|
|
|
|
|
|
if (workshopId.HasValue)
|
|
|
|
|
{
|
|
|
|
|
sql += " AND m.workshop_id = @WorkshopId";
|
|
|
|
|
parameters.Add("WorkshopId", workshopId.Value);
|
|
|
|
|
}
|
|
|
|
|
if (machineId.HasValue)
|
|
|
|
|
{
|
|
|
|
|
sql += " AND seg.machine_id = @MachineId";
|
|
|
|
|
parameters.Add("MachineId", machineId.Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sql += " GROUP BY seg.machine_id, seg.program_name, m.name, cr_runtime.run_hours ORDER BY TotalQuantity DESC";
|
|
|
|
|
|
|
|
|
|
var items = conn.Query<MachineProductionListItem>(sql, parameters).ToList();
|
|
|
|
|
|
|
|
|
|
// 计算排行和日夜班标识
|
|
|
|
|
for (int i = 0; i < items.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
items[i].Rank = i + 1;
|
|
|
|
|
items[i].DayStatus = items[i].DayStatus ?? "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return items;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 员工维度统计卡片(通过cnc_worker_machine关联产量分段表)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public WorkerProductionSummaryResponse GetWorkerSummary(DateTime startDate, DateTime endDate)
|
|
|
|
|
{
|
|
|
|
|
using (var conn = CreateConnection())
|
|
|
|
|
{
|
|
|
|
|
string sql = @"SELECT COALESCE(SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity
|
|
|
|
|
ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END), 0) AS TotalQuantity,
|
|
|
|
|
COUNT(DISTINCT w.id) AS ActiveWorkerCount
|
|
|
|
|
FROM cnc_production_segment seg
|
|
|
|
|
JOIN cnc_worker_machine wm ON seg.machine_id = wm.machine_id
|
|
|
|
|
JOIN cnc_worker w ON wm.worker_id = w.id
|
|
|
|
|
WHERE seg.production_date BETWEEN @Start AND @End";
|
|
|
|
|
|
|
|
|
|
var result = conn.QuerySingleOrDefault<WorkerProductionSummaryResponse>(sql, new { Start = startDate, End = endDate });
|
|
|
|
|
if (result == null)
|
|
|
|
|
{
|
|
|
|
|
return new WorkerProductionSummaryResponse();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算人均产量
|
|
|
|
|
if (result.ActiveWorkerCount > 0)
|
|
|
|
|
{
|
|
|
|
|
result.AvgPerWorker = Math.Round((decimal)result.TotalQuantity / result.ActiveWorkerCount, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询最高产量员工名称
|
|
|
|
|
string topSql = @"SELECT w.name FROM cnc_production_segment seg
|
|
|
|
|
JOIN cnc_worker_machine wm ON seg.machine_id = wm.machine_id
|
|
|
|
|
JOIN cnc_worker w ON wm.worker_id = w.id
|
|
|
|
|
WHERE seg.production_date BETWEEN @Start AND @End
|
|
|
|
|
GROUP BY w.id, w.name
|
|
|
|
|
ORDER BY SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END) DESC LIMIT 1";
|
|
|
|
|
result.TopWorkerName = conn.ExecuteScalar<string>(topSql, new { Start = startDate, End = endDate }) ?? "";
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 员工维度明细列表(通过cnc_worker_machine关联,产量降序)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public List<WorkerProductionListItem> GetWorkerList(DateTime startDate, DateTime endDate, int? workerId)
|
|
|
|
|
{
|
|
|
|
|
using (var conn = CreateConnection())
|
|
|
|
|
{
|
|
|
|
|
string sql = @"SELECT w.name AS WorkerName,
|
|
|
|
|
COUNT(DISTINCT wm.machine_id) AS MachineCount,
|
|
|
|
|
COUNT(DISTINCT seg.program_name) AS ProgramCount,
|
|
|
|
|
COALESCE(SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity
|
|
|
|
|
ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END), 0) AS TotalQuantity
|
|
|
|
|
FROM cnc_worker w
|
|
|
|
|
JOIN cnc_worker_machine wm ON wm.worker_id = w.id
|
|
|
|
|
LEFT JOIN cnc_production_segment seg ON seg.machine_id = wm.machine_id
|
|
|
|
|
AND seg.production_date BETWEEN @Start AND @End";
|
|
|
|
|
|
|
|
|
|
var parameters = new DynamicParameters();
|
|
|
|
|
parameters.Add("Start", startDate);
|
|
|
|
|
parameters.Add("End", endDate);
|
|
|
|
|
|
|
|
|
|
if (workerId.HasValue)
|
|
|
|
|
{
|
|
|
|
|
sql += " AND w.id = @WorkerId";
|
|
|
|
|
parameters.Add("WorkerId", workerId.Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sql += " GROUP BY w.id, w.name ORDER BY TotalQuantity DESC";
|
|
|
|
|
|
|
|
|
|
var items = conn.Query<WorkerProductionListItem>(sql, parameters).ToList();
|
|
|
|
|
if (items.Count == 0) return items;
|
|
|
|
|
|
|
|
|
|
// 计算总量用于百分比
|
|
|
|
|
int grandTotal = items.Sum(x => x.TotalQuantity);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < items.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
items[i].Rank = i + 1;
|
|
|
|
|
if (grandTotal > 0)
|
|
|
|
|
{
|
|
|
|
|
items[i].Percentage = Math.Round((decimal)items[i].TotalQuantity / grandTotal * 100, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return items;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 程序维度统计卡片(按program_name聚合)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public ProgramProductionSummaryResponse GetProgramSummary(DateTime startDate, DateTime endDate, int? workshopId)
|
|
|
|
|
{
|
|
|
|
|
using (var conn = CreateConnection())
|
|
|
|
|
{
|
|
|
|
|
string sql = @"SELECT COALESCE(SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity
|
|
|
|
|
ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END), 0) AS TotalQuantity,
|
|
|
|
|
COUNT(DISTINCT seg.program_name) AS RunningProgramCount
|
|
|
|
|
FROM cnc_production_segment seg
|
|
|
|
|
LEFT JOIN cnc_machine m ON seg.machine_id = m.id
|
|
|
|
|
WHERE seg.production_date BETWEEN @Start AND @End";
|
|
|
|
|
|
|
|
|
|
var parameters = new DynamicParameters();
|
|
|
|
|
parameters.Add("Start", startDate);
|
|
|
|
|
parameters.Add("End", endDate);
|
|
|
|
|
|
|
|
|
|
if (workshopId.HasValue)
|
|
|
|
|
{
|
|
|
|
|
sql += " AND m.workshop_id = @WorkshopId";
|
|
|
|
|
parameters.Add("WorkshopId", workshopId.Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var result = conn.QuerySingleOrDefault<ProgramProductionSummaryResponse>(sql, parameters);
|
|
|
|
|
if (result == null)
|
|
|
|
|
{
|
|
|
|
|
return new ProgramProductionSummaryResponse();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算平均单程序产量
|
|
|
|
|
if (result.RunningProgramCount > 0)
|
|
|
|
|
{
|
|
|
|
|
result.AvgPerProgram = Math.Round((decimal)result.TotalQuantity / result.RunningProgramCount, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询最高产量程序名称
|
|
|
|
|
string topSql = @"SELECT seg.program_name FROM cnc_production_segment seg
|
|
|
|
|
LEFT JOIN cnc_machine m ON seg.machine_id = m.id
|
|
|
|
|
WHERE seg.production_date BETWEEN @Start AND @End";
|
|
|
|
|
if (workshopId.HasValue)
|
|
|
|
|
{
|
|
|
|
|
topSql += " AND m.workshop_id = @WorkshopId";
|
|
|
|
|
}
|
|
|
|
|
topSql += @" GROUP BY seg.program_name
|
|
|
|
|
ORDER BY SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END) DESC LIMIT 1";
|
|
|
|
|
result.TopProgramName = conn.ExecuteScalar<string>(topSql, parameters) ?? "";
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 程序维度明细列表(按program_name聚合,产量降序)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public List<ProgramProductionListItem> GetProgramList(DateTime startDate, DateTime endDate, string programName)
|
|
|
|
|
{
|
|
|
|
|
using (var conn = CreateConnection())
|
|
|
|
|
{
|
|
|
|
|
string sql = @"SELECT seg.program_name AS ProgramName,
|
|
|
|
|
COUNT(DISTINCT seg.machine_id) AS MachineCount,
|
|
|
|
|
COALESCE(SUM(CASE WHEN seg.is_settled=1 THEN seg.quantity
|
|
|
|
|
ELSE COALESCE(seg.end_part_count, seg.start_part_count) - seg.start_part_count END), 0) AS TotalQuantity
|
|
|
|
|
FROM cnc_production_segment seg
|
|
|
|
|
LEFT JOIN cnc_machine m ON seg.machine_id = m.id
|
|
|
|
|
WHERE seg.production_date BETWEEN @Start AND @End";
|
|
|
|
|
|
|
|
|
|
var parameters = new DynamicParameters();
|
|
|
|
|
parameters.Add("Start", startDate);
|
|
|
|
|
parameters.Add("End", endDate);
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(programName))
|
|
|
|
|
{
|
|
|
|
|
sql += " AND seg.program_name = @ProgramName";
|
|
|
|
|
parameters.Add("ProgramName", programName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sql += " GROUP BY seg.program_name ORDER BY TotalQuantity DESC";
|
|
|
|
|
|
|
|
|
|
var items = conn.Query<ProgramProductionListItem>(sql, parameters).ToList();
|
|
|
|
|
if (items.Count == 0) return items;
|
|
|
|
|
|
|
|
|
|
// 计算总量用于百分比
|
|
|
|
|
int grandTotal = items.Sum(x => x.TotalQuantity);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < items.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
items[i].Rank = i + 1;
|
|
|
|
|
if (items[i].MachineCount > 0)
|
|
|
|
|
{
|
|
|
|
|
items[i].AvgPerMachine = Math.Round((decimal)items[i].TotalQuantity / items[i].MachineCount, 1);
|
|
|
|
|
}
|
|
|
|
|
if (grandTotal > 0)
|
|
|
|
|
{
|
|
|
|
|
items[i].Percentage = Math.Round((decimal)items[i].TotalQuantity / grandTotal * 100, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return items;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|