2026-01-24 09:19:42 +08:00
|
|
|
|
using Aliyun.OSS;
|
2026-01-26 15:11:57 +08:00
|
|
|
|
using DOAN.Model.MES;
|
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;
|
2026-02-05 09:59:12 +08:00
|
|
|
|
using JinianNet.JNTemplate.Dynamic;
|
2026-01-23 13:31:28 +08:00
|
|
|
|
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
|
|
|
|
|
|
{
|
2026-01-26 15:11:57 +08:00
|
|
|
|
public List<DevicePoweronRateModel> DevicePoweronRate(DeviceReportDto param)
|
2026-01-21 11:16:34 +08:00
|
|
|
|
{
|
|
|
|
|
|
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-26 15:11:57 +08:00
|
|
|
|
//var dt = dateTime.ToString("yyyy-MM-dd");
|
2026-01-21 11:16:34 +08:00
|
|
|
|
|
|
|
|
|
|
var shiftList = Context.Queryable<GroupSchedule>()
|
2026-01-31 15:46:56 +08:00
|
|
|
|
.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) =>
|
2026-01-21 11:16:34 +08:00
|
|
|
|
new
|
|
|
|
|
|
{
|
2026-01-26 15:11:57 +08:00
|
|
|
|
c.LineCode,
|
2026-01-31 15:46:56 +08:00
|
|
|
|
a.StartTime,
|
|
|
|
|
|
a.EndTime,
|
|
|
|
|
|
a.PlanRestTime
|
2026-01-21 11:16:34 +08:00
|
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
var tempList = response.Select(it => new
|
|
|
|
|
|
{
|
|
|
|
|
|
LineCode = it.Code,
|
|
|
|
|
|
LineName = it.Name,
|
2026-01-31 15:46:56 +08:00
|
|
|
|
List = shiftList.Where(it2 => it2.LineCode == it.Code).Select(it2 => new { it2.PlanRestTime, it2.StartTime, it2.EndTime }).ToList()
|
2026-01-21 11:16:34 +08:00
|
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
tempList.ForEach(t =>
|
|
|
|
|
|
{
|
|
|
|
|
|
double poweronRate = 0;
|
|
|
|
|
|
double minutes = 0;
|
|
|
|
|
|
int shiftCount = 0;
|
|
|
|
|
|
t.List.ForEach(t2 =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (t2.EndTime.HasValue && t2.StartTime.HasValue)
|
|
|
|
|
|
{
|
2026-01-31 15:46:56 +08:00
|
|
|
|
minutes += (t2.EndTime.Value - t2.StartTime.Value).TotalMinutes - t2.PlanRestTime;
|
|
|
|
|
|
shiftCount++;
|
2026-01-21 11:16:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2026-01-26 15:11:57 +08:00
|
|
|
|
public List<DeviceDowntimeRateModel> DeviceDowntimeRate(DeviceReportDto param)
|
2026-01-22 14:30:44 +08:00
|
|
|
|
{
|
|
|
|
|
|
List<DeviceDowntimeRateModel> list = new List<DeviceDowntimeRateModel>();
|
2026-01-26 15:11:57 +08:00
|
|
|
|
//var dt = dateTime.ToString("yyyy-MM-dd");
|
2026-01-22 14:30:44 +08:00
|
|
|
|
|
2026-01-23 15:30:37 +08:00
|
|
|
|
list = Context.Queryable<BaseWorkRoute>()
|
2026-01-26 15:11:57 +08:00
|
|
|
|
.LeftJoin<ProWorkorder>((a, b) => a.Code == b.LineCode
|
2026-01-27 09:04:49 +08:00
|
|
|
|
&& b.WorkorderDate.Value>= param.StartTime
|
|
|
|
|
|
&& b.WorkorderDate.Value<= param.EndTime)
|
2026-01-23 15:30:37 +08:00
|
|
|
|
.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();
|
|
|
|
|
|
|
2026-01-26 15:11:57 +08:00
|
|
|
|
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();
|
|
|
|
|
|
|
2026-01-22 14:30:44 +08:00
|
|
|
|
var response = Context.Queryable<AndonFaultRecord>()
|
2026-01-26 15:11:57 +08:00
|
|
|
|
.Where(t=>t.FaultDict== "设备异常"
|
|
|
|
|
|
&& t.StartTime.HasValue
|
|
|
|
|
|
&& t.EndTime.HasValue
|
2026-01-27 09:04:49 +08:00
|
|
|
|
&& t.EndTime.Value>= param.StartTime
|
|
|
|
|
|
&& t.EndTime.Value<= param.EndTime)
|
2026-01-22 14:30:44 +08:00
|
|
|
|
.Select(it => new
|
|
|
|
|
|
{
|
|
|
|
|
|
it.LineCode,
|
|
|
|
|
|
it.StartTime,
|
|
|
|
|
|
it.EndTime,
|
|
|
|
|
|
DowntimeHours = (it.EndTime.Value - it.StartTime.Value).TotalHours,
|
|
|
|
|
|
}).ToList();
|
2026-01-27 17:24:07 +08:00
|
|
|
|
|
|
|
|
|
|
var totalDowntimeHours = response.Sum(it => it.DowntimeHours);
|
2026-02-05 09:20:37 +08:00
|
|
|
|
var totalPlanHours = groupListWorkRoute.Sum(it => it.PlanHours);
|
2026-01-22 14:30:44 +08:00
|
|
|
|
var groupList = response.GroupBy(it => it.LineCode).Select(it => new
|
|
|
|
|
|
{
|
|
|
|
|
|
LineCode = it.Key,
|
|
|
|
|
|
DowntimeHours = it.ToList().Sum(t=>t.DowntimeHours)
|
|
|
|
|
|
}).ToList();
|
|
|
|
|
|
|
2026-01-26 15:11:57 +08:00
|
|
|
|
var result = groupListWorkRoute.GroupJoin(groupList,
|
2026-01-22 14:30:44 +08:00
|
|
|
|
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
|
2026-01-27 17:24:07 +08:00
|
|
|
|
DowntimeRate = l.PlanHours == 0 ? 0 : Math.Round((gList.FirstOrDefault()?.DowntimeHours ?? 0) / l.PlanHours, 2),
|
2026-02-05 09:20:37 +08:00
|
|
|
|
TotalDowntimeHours = totalDowntimeHours,
|
|
|
|
|
|
TotalPlanHours = totalPlanHours,
|
|
|
|
|
|
TotalDowntimeRate = totalPlanHours == 0 ? 0 : Math.Round(totalDowntimeHours / totalPlanHours, 2)
|
2026-01-22 14:30:44 +08:00
|
|
|
|
}).ToList();
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
2026-01-23 13:31:28 +08:00
|
|
|
|
|
2026-01-26 17:11:29 +08:00
|
|
|
|
public List<ProductionCompletionRate> ProductionCompletionRate(string groupName, DateTime dateTime)
|
2026-01-23 13:31:28 +08:00
|
|
|
|
{
|
|
|
|
|
|
List<ProductionCompletionRate> list = new List<ProductionCompletionRate>();
|
2026-01-31 15:46:56 +08:00
|
|
|
|
|
2026-01-23 13:31:28 +08:00
|
|
|
|
var dt = dateTime.ToString("yyyy-MM-dd");
|
|
|
|
|
|
|
|
|
|
|
|
var woList = Context.Queryable<ProWorkorder>()
|
|
|
|
|
|
.LeftJoin<GroupSchedule>((a, b) => a.GroupCode == b.GroupCode)
|
2026-01-31 15:46:56 +08:00
|
|
|
|
//.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
|
2026-01-26 17:11:29 +08:00
|
|
|
|
&& b.ScheduleDate.Value.ToString("yyyy-MM-dd") == dt
|
|
|
|
|
|
&& (string.IsNullOrEmpty(groupName) || d.GroupName.Contains(groupName)))
|
2026-01-31 15:46:56 +08:00
|
|
|
|
.Select((a, b, d) =>
|
2026-01-23 13:31:28 +08:00
|
|
|
|
new
|
|
|
|
|
|
{
|
|
|
|
|
|
a.Workorder,
|
|
|
|
|
|
a.GroupCode,
|
|
|
|
|
|
a.DeliveryNum,
|
2026-01-26 13:32:31 +08:00
|
|
|
|
a.ProductionName,
|
2026-01-23 13:31:28 +08:00
|
|
|
|
a.LineCode,
|
2026-01-31 15:46:56 +08:00
|
|
|
|
a.Beat,
|
2026-01-23 13:31:28 +08:00
|
|
|
|
a.Status,
|
2026-01-31 15:46:56 +08:00
|
|
|
|
b.StartTime,
|
|
|
|
|
|
b.EndTime,
|
|
|
|
|
|
b.PlanRestTime,
|
2026-01-23 13:31:28 +08:00
|
|
|
|
d.GroupName
|
|
|
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
string year = dateTime.Year.ToString("D4");
|
|
|
|
|
|
string month = dateTime.Month.ToString("D2");
|
|
|
|
|
|
string day = "01";
|
|
|
|
|
|
|
2026-01-27 09:54:44 +08:00
|
|
|
|
//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
|
2026-01-31 15:46:56 +08:00
|
|
|
|
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
|
2026-01-23 13:31:28 +08:00
|
|
|
|
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,
|
2026-01-31 15:46:56 +08:00
|
|
|
|
Beat = t.Beat ?? 0,
|
|
|
|
|
|
Status = GetStatusName(t.Status ?? 0),
|
|
|
|
|
|
StartTime = t.StartTime,
|
|
|
|
|
|
EndTime = t.EndTime,
|
|
|
|
|
|
Model = t.ProductionName
|
2026-01-23 13:31:28 +08:00
|
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
list.ForEach(t =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var productionCompletionList = workDetailList.Where(wd => wd.WorkOrder == t.WorkOrder).ToList();
|
2026-01-31 15:46:56 +08:00
|
|
|
|
//var hours = (t.EndTime - t.StartTime).Value.TotalHours;
|
|
|
|
|
|
var planNum = t.Beat == 0 ? 0 : 3600 / t.Beat;
|
2026-02-03 09:32:47 +08:00
|
|
|
|
for (int i = 8; i < 24; i++)
|
2026-01-23 13:31:28 +08:00
|
|
|
|
{
|
2026-01-31 15:46:56 +08:00
|
|
|
|
var productionCompletionModel = productionCompletionList.Where(t => t.TimePeriod.Hour == i).FirstOrDefault();
|
2026-01-23 14:04:37 +08:00
|
|
|
|
t.List.Add(new PlanModel
|
2026-01-23 13:31:28 +08:00
|
|
|
|
{
|
2026-01-31 15:46:56 +08:00
|
|
|
|
StartTime = $"{i}:00",
|
|
|
|
|
|
PlanNum = planNum,
|
|
|
|
|
|
CompletionNum = productionCompletionModel?.Count ?? 0,
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2026-02-03 09:32:47 +08:00
|
|
|
|
for (int i = 0; i < 8; i++)
|
2026-01-31 15:46:56 +08:00
|
|
|
|
{
|
|
|
|
|
|
var productionCompletionModel = productionCompletionList.Where(t => t.TimePeriod.Hour == i).FirstOrDefault();
|
|
|
|
|
|
t.List.Add(new PlanModel
|
|
|
|
|
|
{
|
|
|
|
|
|
StartTime = $"{i}:00",
|
|
|
|
|
|
PlanNum = planNum,
|
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);
|
2026-01-31 15:46:56 +08:00
|
|
|
|
t.CompletionRate = Math.Round(t.CompletionNum * 100.0 / t.DeliveryNum, 2);
|
2026-01-23 13:31:28 +08:00
|
|
|
|
});
|
|
|
|
|
|
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-26 15:47:41 +08:00
|
|
|
|
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)
|
2026-02-05 09:59:12 +08:00
|
|
|
|
.LeftJoin<BaseGroup>((a, b, c, d) => a.GroupCode == d.GroupCode)
|
2026-01-26 15:47:41 +08:00
|
|
|
|
.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;
|
|
|
|
|
|
}
|
2026-01-26 18:41:05 +08:00
|
|
|
|
|
2026-02-05 09:59:12 +08:00
|
|
|
|
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)
|
2026-01-26 18:41:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
2026-01-21 11:16:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|