471 lines
21 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Aliyun.OSS;
using DOAN.Model.MES;
using DOAN.Model.MES.andon;
using DOAN.Model.MES.base_;
using DOAN.Model.MES.group;
using DOAN.Model.MES.product;
using DOAN.Model.MES.report;
using DOAN.Service.MES.report.IService;
using Infrastructure.Attribute;
using JinianNet.JNTemplate.Dynamic;
using System.Data;
namespace DOAN.Service.MES.report
{
[AppService(ServiceType = typeof(IReportService), ServiceLifetime = LifeTime.Transient)]
public class ReportService : BaseService<BaseWorkRoute>, IReportService
{
public List<DevicePoweronRateModel> DevicePoweronRate(DeviceReportDto param)
{
List<DevicePoweronRateModel> list = new List<DevicePoweronRateModel>();
var response = Context.Queryable<BaseWorkRoute>().OrderBy(t => t.Id).ToList();
//var dt = dateTime.ToString("yyyy-MM-dd");
var shiftList = Context.Queryable<GroupSchedule>()
.LeftJoin<ProWorkorder>((a, c) => a.GroupCode == c.GroupCode
&& c.WorkorderDate.Value.ToString("yyyy-MM-dd") == a.ScheduleDate.Value.ToString("yyyy-MM-dd"))
.Where((a, c) => a.ScheduleDate.Value >= param.StartTime && a.ScheduleDate.Value <= param.EndTime)
.Select((a, c) =>
new
{
c.LineCode,
a.StartTime,
a.EndTime,
a.PlanRestTime
}).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.PlanRestTime, 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)
{
minutes += (t2.EndTime.Value - t2.StartTime.Value).TotalMinutes - t2.PlanRestTime;
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;
}
public List<DeviceDowntimeRateModel> DeviceDowntimeRate(DeviceReportDto param)
{
List<DeviceDowntimeRateModel> list = new List<DeviceDowntimeRateModel>();
//var dt = dateTime.ToString("yyyy-MM-dd");
list = Context.Queryable<BaseWorkRoute>()
.LeftJoin<ProWorkorder>((a, b) => a.Code == b.LineCode
&& b.WorkorderDate.Value>= param.StartTime
&& b.WorkorderDate.Value<= param.EndTime)
.OrderBy((a,b)=>a.Id)
.Select((a, b) =>
new DeviceDowntimeRateModel
{
LineCode = a.Code,
LineName = a.Name,
PlanHours = SqlFunc.Round((b.Beat * b.DeliveryNum ?? 0) / 3600.0, 2)
}).ToList();
var groupListWorkRoute = list.GroupBy(it => new { it.LineCode,it.LineName }).Select(it => new
{
LineCode = it.Key.LineCode,
LineName = it.Key.LineName,
PlanHours = it.ToList().Sum(t => t.PlanHours)
}).ToList();
var response = Context.Queryable<AndonFaultRecord>()
.Where(t=>t.FaultDict== "设备异常"
&& t.StartTime.HasValue
&& t.EndTime.HasValue
&& t.EndTime.Value>= param.StartTime
&& t.EndTime.Value<= param.EndTime)
.Select(it => new
{
it.LineCode,
it.StartTime,
it.EndTime,
DowntimeHours = (it.EndTime.Value - it.StartTime.Value).TotalHours,
}).ToList();
var totalDowntimeHours = response.Sum(it => it.DowntimeHours);
var totalPlanHours = groupListWorkRoute.Sum(it => it.PlanHours);
var groupList = response.GroupBy(it => it.LineCode).Select(it => new
{
LineCode = it.Key,
DowntimeHours = it.ToList().Sum(t=>t.DowntimeHours)
}).ToList();
var result = groupListWorkRoute.GroupJoin(groupList,
l => l.LineCode,
g => g.LineCode,
(l, gList) => new DeviceDowntimeRateModel
{
LineCode = l.LineCode,
LineName = l.LineName,
PlanHours = l.PlanHours,
DowntimeHours = gList.FirstOrDefault()?.DowntimeHours ?? 0, // 如果没有停机时间则为0
DowntimeRate = l.PlanHours == 0 ? 0 : Math.Round((gList.FirstOrDefault()?.DowntimeHours ?? 0) / l.PlanHours, 2),
TotalDowntimeHours = totalDowntimeHours,
TotalPlanHours = totalPlanHours,
TotalDowntimeRate = totalPlanHours == 0 ? 0 : Math.Round(totalDowntimeHours / totalPlanHours, 2)
}).ToList();
return result;
}
public List<ProductionCompletionRate> ProductionCompletionRate(string groupName, 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, d) => a.GroupCode == d.GroupCode)
.Where((a, b, d) => a.WorkorderDate.Value.ToString("yyyy-MM-dd") == dt
&& b.ScheduleDate.Value.ToString("yyyy-MM-dd") == dt
&& (string.IsNullOrEmpty(groupName) || d.GroupName.Contains(groupName)))
.Select((a, b, d) =>
new
{
a.Workorder,
a.GroupCode,
a.DeliveryNum,
a.ProductionName,
a.LineCode,
a.Beat,
a.Status,
b.StartTime,
b.EndTime,
b.PlanRestTime,
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";
string sql = $@"SELECT TimePeriod,WorkOrder,count(0) AS Count
from (
SELECT FROM_UNIXTIME( FLOOR( UNIX_TIMESTAMP( d.created_time ) / 3600 ) * 3600 ) AS TimePeriod,
r.workorder as WorkOrder
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
)t group by TimePeriod,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,
WorkTimePeriod = $"{t.StartTime?.ToString("HH:mm")}-{t.EndTime?.ToString("HH:mm")}",
DeliveryNum = t.DeliveryNum ?? 0,
Beat = t.Beat ?? 0,
Status = GetStatusName(t.Status ?? 0),
StartTime = t.StartTime,
EndTime = t.EndTime,
Model = t.ProductionName
}).ToList();
list.ForEach(t =>
{
var productionCompletionList = workDetailList.Where(wd => wd.WorkOrder == t.WorkOrder).ToList();
//var hours = (t.EndTime - t.StartTime).Value.TotalHours;
var planNum = t.Beat == 0 ? 0 : 3600 / t.Beat;
for (int i = 8; i < 24; i++)
{
var productionCompletionModel = productionCompletionList.Where(t => t.TimePeriod.Hour == i).FirstOrDefault();
t.List.Add(new PlanModel
{
StartTime = $"{i}00",
PlanNum = planNum,
CompletionNum = productionCompletionModel?.Count ?? 0,
});
}
for (int i = 0; i < 8; i++)
{
var productionCompletionModel = productionCompletionList.Where(t => t.TimePeriod.Hour == i).FirstOrDefault();
t.List.Add(new PlanModel
{
StartTime = $"{i}00",
PlanNum = planNum,
CompletionNum = productionCompletionModel?.Count ?? 0,
});
}
t.CompletionNum = productionCompletionList.Sum(t => t.Count);
t.CompletionRate = Math.Round(t.CompletionNum * 100.0 / t.DeliveryNum, 2);
});
return list;
}
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;
}
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 "";
}
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);
}
public List<ProductionReportModel> ProductionReport(DateTime dateTime)
{
var dt = dateTime.ToString("yyyy-MM-dd");
var woList = Context.Queryable<ProWorkorder>()
.LeftJoin<ProReportwork>((a, b) => a.Workorder == b.FkWorkorder)
.LeftJoin<BaseWorkRoute>((a, b, c) => a.LineCode == c.Code)
.LeftJoin<BaseGroup>((a, b, c, d) => a.GroupCode == d.GroupCode)
.Where((a, b, c, d) => a.WorkorderDate.Value.ToString("yyyy-MM-dd") == dt)
.Select((a, b, c, d) => new ProductionReportModel
{
WorkOrder = a.Workorder,
ProductionName = a.ProductionName,
PlanNum = a.DeliveryNum ?? 0,
CompletionNum = b.FinishedNum ?? 0,
CompletionRate = SqlFunc.Round((b.FinishedNum ?? 0) * 100.0 / (a.DeliveryNum ?? 0), 2),
QualifiedRate = b.FinishedNum.HasValue ? SqlFunc.Round((b.QualifiedNumber ?? 0) * 100.0 / (b.FinishedNum ?? 0), 2) : 0,
UnqualifiedRate = b.FinishedNum.HasValue ? SqlFunc.Round((b.UnqualifiedNumber ?? 0) * 100.0 / (b.FinishedNum ?? 0), 2) : 0,
Status = a.Status,
LineName = c.Name,
GroupName = d.GroupName
}).ToList();
woList.ForEach(t => t.StatusName = GetStatusName(t.Status ?? 0));
return woList;
}
public ProductionReportToalRate ProductionReportRate(DateTime dateTime, int type)
{
DateTime startDate, endDate;
if (type == 1)
{
var dateRange = GetWeekRange(dateTime);
startDate = dateRange.StartOfWeek;
endDate = dateRange.EndOfWeek;
}
else
{
var dateRange = GetMonthRange(dateTime);
startDate = dateRange.StartOfMonth;
endDate = dateRange.EndOfMonth;
}
var woList = Context.Queryable<ProWorkorder>()
.LeftJoin<ProReportwork>((a, b) => a.Workorder == b.FkWorkorder)
.Where((a, b) => a.WorkorderDate >= startDate && a.WorkorderDate <= endDate)
.Select((a, b) => new
{
PlanNum = a.DeliveryNum ?? 0,
CompletionNum = b.FinishedNum ?? 0,
QualifiedNumber = b.QualifiedNumber ?? 0,
UnqualifiedNumber = b.UnqualifiedNumber ?? 0
}).ToList();
var totalPlanNum = woList.Sum(t => t.PlanNum);
var totalCompletionNum = woList.Sum(t => t.CompletionNum);
var totalQualifiedNum = woList.Sum(t => t.QualifiedNumber);
var totalUnqualifiedNum = woList.Sum(t => t.UnqualifiedNumber);
ProductionReportToalRate rate = new ProductionReportToalRate()
{
CompleteRate = totalPlanNum == 0 ? 0 : Math.Round(totalCompletionNum * 100.0 / totalPlanNum, 2),
QualifiedRate = totalCompletionNum == 0 ? 0 : Math.Round(totalQualifiedNum * 100.0 / totalCompletionNum, 2),
UnqualifiedRate = totalCompletionNum == 0 ? 0 : Math.Round(totalUnqualifiedNum * 100.0 / totalCompletionNum, 2)
};
return rate;
}
private (DateTime StartOfWeek, DateTime EndOfWeek) GetWeekRange(DateTime date)
{
// 计算本周第一天(周一)
int diff = (7 + (date.DayOfWeek - DayOfWeek.Monday)) % 7;
DateTime startOfWeek = date.AddDays(-1 * diff).Date;
// 计算本周最后一天(周日)
DateTime endOfWeek = startOfWeek.AddDays(6);
return (startOfWeek, endOfWeek);
}
// 获取当月时间范围
private (DateTime StartOfMonth, DateTime EndOfMonth) GetMonthRange(DateTime date)
{
// 本月第一天
DateTime startOfMonth = new DateTime(date.Year, date.Month, 1);
// 本月最后一天
int daysInMonth = DateTime.DaysInMonth(date.Year, date.Month);
DateTime endOfMonth = new DateTime(date.Year, date.Month, daysInMonth);
return (startOfMonth, endOfMonth);
}
public ProductionReportRateModel ProductionReportRate2(DateTime dateTime)
{
var dt = dateTime.ToString("yyyy-MM-dd");
ProductionReportRateModel model = new ProductionReportRateModel();
var productionCompletionRate = ProductionCompletionRate("", dateTime);
model.CompletionRateList = productionCompletionRate.Select(t =>
new ProductionReportRate
{
WorkTimePeriod = t.WorkTimePeriod,
Rate = t.CompletionRate
}).ToList();
string sql = @"SELECT FROM_UNIXTIME( FLOOR( UNIX_TIMESTAMP( d.created_time ) / 3600 ) * 3600 ) AS TimePeriod,
sum(number) AS Count
FROM pro_workorder AS r
RIGHT JOIN qc_finishedproduct_defect_collection AS d ON r.workorder = d.workorder
WHERE r.workorder_date = @dt
GROUP BY FLOOR( UNIX_TIMESTAMP( d.created_time ) / 600 )
ORDER BY TimePeriod";
var defectList = Context.Ado.SqlQuery<ProductionCompletionModel>(sql, new { dt = dt, });
var tempList = defectList.Select(t =>
new
{
Count = t.Count,
WorkTimePeriod = t.TimePeriod.ToString("HH:00")
}
).ToList();
productionCompletionRate.ForEach(t =>
{
var defectModel = tempList.Where(d => d.WorkTimePeriod == t.WorkTimePeriod).FirstOrDefault();
var rate= defectModel==null ? 0 : Math.Round(defectModel.Count * 100.0 / t.DeliveryNum, 2);
model.UnqualifiedRateList.Add(new ProductionReportRate
{
WorkTimePeriod = t.WorkTimePeriod,
Rate = rate
});
model.QualifiedRateList.Add(new ProductionReportRate
{
WorkTimePeriod = t.WorkTimePeriod,
Rate = 100 - rate
});
});
return model;
}
}
}