298 lines
13 KiB
C#
Raw Normal View History

2026-01-24 09:19:42 +08:00
using Aliyun.OSS;
2026-01-23 13:31:28 +08:00
using DOAN.Model.MES.andon;
using DOAN.Model.MES.base_;
using DOAN.Model.MES.group;
2026-01-21 11:16:34 +08:00
using DOAN.Model.MES.product;
2026-01-23 13:31:28 +08:00
using DOAN.Model.MES.report;
using DOAN.Service.MES.report.IService;
using Infrastructure.Attribute;
using System.Data;
2026-01-21 11:16:34 +08:00
namespace DOAN.Service.MES.report
{
[AppService(ServiceType = typeof(IReportService), ServiceLifetime = LifeTime.Transient)]
public class ReportService : BaseService<BaseWorkRoute>, IReportService
{
public List<DevicePoweronRateModel> DevicePoweronRate(DateTime dateTime)
{
List<DevicePoweronRateModel> list = new List<DevicePoweronRateModel>();
2026-01-23 15:30:37 +08:00
var response = Context.Queryable<BaseWorkRoute>().OrderBy(t => t.Id).ToList();
2026-01-21 11:16:34 +08:00
var dt = dateTime.ToString("yyyy-MM-dd");
var shiftList = Context.Queryable<GroupSchedule>()
.LeftJoin<GroupShift>((a, b) => a.FkShift == b.Id)
.LeftJoin<ProWorkorder>((a, b, c) => a.GroupCode == c.GroupCode && c.WorkorderDate.Value.ToString("yyyy-MM-dd") == dt)
.Where((a, b, c) => a.ScheduleDate.Value.ToString("yyyy-MM-dd") == dt)
.Select((a, b, c) =>
new
{
b.Name,
b.WorkHours,
b.StartTime,
b.EndTime,
c.LineCode
}).ToList();
var tempList = response.Select(it => new
{
LineCode = it.Code,
LineName = it.Name,
List = shiftList.Where(it2 => it2.LineCode == it.Code).Select(it2 => new { it2.Name, it2.StartTime, it2.EndTime }).ToList()
}).ToList();
tempList.ForEach(t =>
{
double poweronRate = 0;
double minutes = 0;
int shiftCount = 0;
t.List.ForEach(t2 =>
{
if (t2.EndTime.HasValue && t2.StartTime.HasValue)
{
if (t2.EndTime.Value.Hour == 16)
{
minutes += (t2.EndTime.Value - t2.StartTime.Value).TotalMinutes - 50;
shiftCount++;
}
else if (t2.EndTime.Value.Hour == 20)
{
minutes += (t2.EndTime.Value - t2.StartTime.Value).TotalMinutes - 80;
shiftCount++;
}
else if (t2.EndTime.Value.Hour == 22)
{
minutes += (t2.EndTime.Value - t2.StartTime.Value).TotalMinutes - 100;
shiftCount++;
}
}
});
if (shiftCount > 0)
{
poweronRate = Math.Round(minutes * 100.0 / (24 * 60 * shiftCount), 2);
}
list.Add(new DevicePoweronRateModel()
{
LineCode = t.LineCode,
LineName = t.LineName,
ShiftCount = shiftCount,
PoweronHours = minutes,
PoweronRate = poweronRate
});
});
return list;
}
2026-01-22 14:30:44 +08:00
public List<DeviceDowntimeRateModel> DeviceDowntimeRate(DateTime dateTime)
{
List<DeviceDowntimeRateModel> list = new List<DeviceDowntimeRateModel>();
var dt = dateTime.ToString("yyyy-MM-dd");
2026-01-23 15:30:37 +08:00
list = Context.Queryable<BaseWorkRoute>()
.LeftJoin<ProWorkorder>((a, b) => a.Code == b.LineCode && b.WorkorderDate.Value.ToString("yyyy-MM-dd") == dt)
.OrderBy((a,b)=>a.Id)
2026-01-22 14:30:44 +08:00
.Select((a, b) =>
new DeviceDowntimeRateModel
{
2026-01-23 15:30:37 +08:00
LineCode = a.Code,
LineName = a.Name,
PlanHours = SqlFunc.Round((b.Beat * b.DeliveryNum ?? 0) / 3600.0, 2)
2026-01-22 14:30:44 +08:00
}).ToList();
var response = Context.Queryable<AndonFaultRecord>()
.Where(t=>t.FaultDict== "设备异常" && t.StartTime.HasValue && t.EndTime.HasValue && t.EndTime.Value.ToString("yyyy-MM-dd") ==dt)
.Select(it => new
{
it.LineCode,
it.StartTime,
it.EndTime,
DowntimeHours = (it.EndTime.Value - it.StartTime.Value).TotalHours,
}).ToList();
var groupList = response.GroupBy(it => it.LineCode).Select(it => new
{
LineCode = it.Key,
DowntimeHours = it.ToList().Sum(t=>t.DowntimeHours)
}).ToList();
var result = list.GroupJoin(groupList,
l => l.LineCode,
g => g.LineCode,
(l, gList) => new DeviceDowntimeRateModel
{
LineCode = l.LineCode,
LineName = l.LineName,
PlanHours = l.PlanHours,
2026-01-23 15:30:37 +08:00
DowntimeHours = gList.FirstOrDefault()?.DowntimeHours ?? 0, // 如果没有停机时间则为0
DowntimeRate = l.PlanHours == 0 ? 0 : Math.Round((gList.FirstOrDefault()?.DowntimeHours ?? 0) / l.PlanHours, 2)
2026-01-22 14:30:44 +08:00
}).ToList();
return result;
}
2026-01-23 13:31:28 +08:00
public List<ProductionCompletionRate> ProductionCompletionRate(DateTime dateTime)
{
List<ProductionCompletionRate> list = new List<ProductionCompletionRate>();
var dt = dateTime.ToString("yyyy-MM-dd");
var woList = Context.Queryable<ProWorkorder>()
.LeftJoin<GroupSchedule>((a, b) => a.GroupCode == b.GroupCode)
.LeftJoin<GroupShift>((a, b, c) => b.FkShift == c.Id)
.LeftJoin<BaseGroup>((a, b, c, d) => a.GroupCode == d.GroupCode)
.Where((a, b, c, d) => a.WorkorderDate.Value.ToString("yyyy-MM-dd") == dt && b.ScheduleDate.Value.ToString("yyyy-MM-dd") == dt)
.Select((a, b, c, d) =>
new
{
a.Workorder,
a.GroupCode,
a.DeliveryNum,
a.LineCode,
a.Status,
c.StartTime,
c.EndTime,
d.GroupName
}).ToList();
string year = dateTime.Year.ToString("D4");
string month = dateTime.Month.ToString("D2");
string day = "01";
string sql = $@"SELECT FROM_UNIXTIME( FLOOR( UNIX_TIMESTAMP( d.created_time ) / 3600 ) * 3600 ) AS TimePeriod,
r.workorder as WorkOrder, COUNT(*) AS Count
FROM pro_workorder AS r
RIGHT JOIN pro_reportwork_detail_{year}{month}{day} AS d ON r.workorder = d.workorder
WHERE r.workorder_date = @dt
GROUP BY FLOOR( UNIX_TIMESTAMP( d.created_time ) / 600 ),r.workorder
ORDER BY TimePeriod";
var workDetailList = Context.Ado.SqlQuery<ProductionCompletionModel>(sql, new { dt = dt, });
list = woList.Select(t => new ProductionCompletionRate
{
WorkOrder = t.Workorder,
GroupName = t.GroupName,
2026-01-23 14:04:37 +08:00
WorkTimePeriod = $"{t.StartTime?.ToString("HH:mm")}-{t.EndTime?.ToString("HH:mm")}",
2026-01-23 13:31:28 +08:00
DeliveryNum = t.DeliveryNum ?? 0,
Status = GetStatusName(t.Status??0),
StartTime=t.StartTime,
EndTime=t.EndTime
}).ToList();
list.ForEach(t =>
{
var productionCompletionList = workDetailList.Where(wd => wd.WorkOrder == t.WorkOrder).ToList();
var hours = (t.EndTime - t.StartTime).Value.TotalHours;
for (int i = 0; i < hours; i++)
{
var productionCompletionModel = productionCompletionList.Where(t => t.TimePeriod.Hour == (8 + i)).FirstOrDefault();
2026-01-23 14:04:37 +08:00
t.List.Add(new PlanModel
2026-01-23 13:31:28 +08:00
{
StartTime = $"{8 + i}00",
PlanNum = t.DeliveryNum / 8,
2026-01-23 14:04:37 +08:00
CompletionNum = productionCompletionModel?.Count ?? 0,
});
2026-01-23 13:31:28 +08:00
}
t.CompletionNum = productionCompletionList.Sum(t => t.Count);
t.CompletionRate = Math.Round(t.CompletionNum*100.0 / t.DeliveryNum,2);
});
return list;
}
2026-01-24 09:19:42 +08:00
public List<ProductionCompletionRate> MonthlyProductionCompletionRate(DateTime dateTime)
{
(DateTime FirstDay, DateTime LastDay) Handlemonth = GetFirstAndLastDayOfMonth(dateTime);
List<ProductionCompletionRate> list = new List<ProductionCompletionRate>();
var woList = Context.Queryable<ProWorkorder>()
.LeftJoin<GroupSchedule>((a, b) => a.GroupCode == b.GroupCode)
.LeftJoin<GroupShift>((a, b, c) => b.FkShift == c.Id)
.LeftJoin<BaseGroup>((a, b, c, d) => a.GroupCode == d.GroupCode)
.Where((a, b, c, d) => a.WorkorderDate.Value>= Handlemonth.FirstDay && a.WorkorderDate.Value<= Handlemonth.LastDay
&& b.ScheduleDate.Value>= Handlemonth.FirstDay && b.ScheduleDate.Value<= Handlemonth.LastDay)
.Select((a, b, c, d) =>
new
{
a.Workorder,
a.GroupCode,
a.DeliveryNum,
a.LineCode,
a.Status,
c.StartTime,
c.EndTime,
d.GroupName
}).ToList();
string year = dateTime.Year.ToString("D4");
string month = dateTime.Month.ToString("D2");
string day = "01";
string sql = $@"SELECT FROM_UNIXTIME( FLOOR( UNIX_TIMESTAMP( d.created_time ) / 3600 ) * 3600 ) AS TimePeriod,
r.workorder as WorkOrder, COUNT(*) AS Count
FROM pro_workorder AS r
RIGHT JOIN pro_reportwork_detail_{year}{month}{day} AS d ON r.workorder = d.workorder
WHERE r.workorder_date >= @firstDay and r.workorder_date<=@lastDay
GROUP BY FLOOR( UNIX_TIMESTAMP( d.created_time ) / 600 ),r.workorder
ORDER BY TimePeriod";
var workDetailList = Context.Ado.SqlQuery<ProductionCompletionModel>(sql, new { firstDay = Handlemonth.FirstDay, lastDay= Handlemonth.LastDay });
list = woList.Select(t => new ProductionCompletionRate
{
WorkOrder = t.Workorder,
GroupName = t.GroupName,
WorkTimePeriod = $"{t.StartTime?.ToString("HH:mm")}-{t.EndTime?.ToString("HH:mm")}",
DeliveryNum = t.DeliveryNum ?? 0,
Status = GetStatusName(t.Status ?? 0),
StartTime = t.StartTime,
EndTime = t.EndTime
}).ToList();
list.ForEach(t =>
{
var productionCompletionList = workDetailList.Where(wd => wd.WorkOrder == t.WorkOrder).ToList();
var hours = (t.EndTime - t.StartTime).Value.TotalHours;
for (int i = 0; i < hours; i++)
{
var productionCompletionModel = productionCompletionList.Where(t => t.TimePeriod.Hour == (8 + i)).FirstOrDefault();
t.List.Add(new PlanModel
{
StartTime = $"{8 + i}00",
PlanNum = t.DeliveryNum / 8,
CompletionNum = productionCompletionModel?.Count ?? 0,
});
}
t.CompletionNum = productionCompletionList.Sum(t => t.Count);
t.CompletionRate = Math.Round(t.CompletionNum * 100.0 / t.DeliveryNum, 2);
});
return list;
}
2026-01-23 13:31:28 +08:00
private string GetStatusName(int status)
{
if (status == 1)
return "未开始";
else if (status == 2)
return "开始";
else if (status == 3)
return "完成";
else if (status == 4)
return "暂停";
else
return "";
}
2026-01-24 09:19:42 +08:00
private (DateTime FirstDay, DateTime LastDay) GetFirstAndLastDayOfMonth(DateTime date)
{
DateTime firstDay = new DateTime(date.Year, date.Month, 1);
int lastDay = DateTime.DaysInMonth(date.Year, date.Month);
DateTime lastDayDate = new DateTime(date.Year, date.Month, lastDay);
return (firstDay, lastDayDate);
}
2026-01-21 11:16:34 +08:00
}
}