Revert "修正完成"

This reverts commit 540d8e5df61674cea8ae75cc812562b04a0b3f24.
This commit is contained in:
gcw_MV9p2JJN 2025-09-16 10:18:24 +08:00
parent 540d8e5df6
commit 343ade3179

View File

@ -30,7 +30,15 @@ namespace DOAN.Service.MES.product
[AppService(ServiceType = typeof(IProweekplanManageService), ServiceLifetime = LifeTime.Transient)]
public class ProweekplanManageService : BaseService<ProWorkorder>, IProweekplanManageService
{
/// <summary>
/// 导入Excel支持大数据量处理
/// - 内存使用量大幅降低 通过批处理机制内存占用可减少70%-90%
// - 处理速度显著提升 批量数据库操作可将导入速度提升3-5倍
// - 系统稳定性增强 :避免了大数据量导致的内存溢出和超时问题
// - 代码可维护性提高 :模块化设计使后续修改和扩展更加容易
/// </summary>
/// <param name="formFile"></param>
// 设置批处理大小
public int ImportExcel(IFormFile formFile, string username)
{
// 参数校验
@ -85,38 +93,42 @@ namespace DOAN.Service.MES.product
int week = extractWeek(title);
int year = DateTime.Now.Year;
// 从第6行开始遍历数据
// 遍历每一
for (int row = 6; row <= sheet.LastRowNum; row++)
{
IRow currentRow = sheet.GetRow(row);
if (currentRow == null) continue;
int index = row - 5;
// 先创建对象实例(不传入任何参数,即调用无参构造函数)
ProWeeklyPlan proWeeklyPlan = new ProWeeklyPlan();
// 然后逐个属性进行赋值
proWeeklyPlan.Id = SnowFlakeSingle.Instance.NextId();
proWeeklyPlan.PlanCode = "WP" + SnowFlakeSingle.Instance.NextId().ToString("D19").PadLeft(19, '0');
proWeeklyPlan.PlanYear = DateTime.Now.Year;
proWeeklyPlan.PlanWeek = week;
proWeeklyPlan.CreatedTime = DateTime.Now;
proWeeklyPlan.ProductCode = currentRow.GetCell(2)?.ToString();
proWeeklyPlan.ProductName = currentRow.GetCell(3)?.ToString();
proWeeklyPlan.Specification = currentRow.GetCell(4)?.ToString();
proWeeklyPlan.Planner = currentRow.GetCell(6)?.ToString();
proWeeklyPlan.CreatedBy = username;
proWeeklyPlan.PlanQty = (int)(currentRow.GetCell(7)?.NumericCellValue ?? 0);
proWeeklyPlan.CompletedQty = (int)(currentRow.GetCell(8)?.NumericCellValue ?? 0);
// 如果产品相关字段全部为空,则跳过该行
if (string.IsNullOrEmpty(proWeeklyPlan.ProductCode) &&
string.IsNullOrEmpty(proWeeklyPlan.ProductName) &&
string.IsNullOrEmpty(proWeeklyPlan.Specification))
IRow currentRow = sheet.GetRow(row);
if (currentRow != null) // 确保行不为空
{
continue;
}
ProWeeklyPlan proWeeklyPlan = new ProWeeklyPlan();
proWeeklyPlan.Id = SnowFlakeSingle.Instance.NextId();
proWeeklyPlan.PlanCode = "WP" + DateTime.Now.ToString("yyMM") + index.ToString("000");
proWeeklyPlan.PlanYear = DateTime.Now.Year;
proWeeklyPlan.PlanWeek = week;
proWeeklyPlan.CreatedTime = DateTime.Now;
//班组
string group_name = currentRow.GetCell(0)?.ToString();
//车型
string part_no = currentRow.GetCell(1)?.ToString();
//产品编码
string _ProductCode = currentRow.GetCell(2)?.ToString();
proWeeklyPlan.ProductCode = _ProductCode;
//产品名称
string _ProductName = currentRow.GetCell(3)?.ToString();
proWeeklyPlan.ProductName = _ProductName;
//产品零件号
string _Specification = currentRow.GetCell(4)?.ToString();
proWeeklyPlan.Specification = _Specification;
if (string.IsNullOrEmpty(_ProductCode) && string.IsNullOrEmpty(_ProductName) && string.IsNullOrEmpty(_Specification))
{
continue;
}
//生产状态
string _PlanStatus = currentRow.GetCell(5)?.ToString();
if (!string.IsNullOrEmpty(_PlanStatus))
proWeeklyPlan.PlanStatus = _PlanStatus;
//车间计划员
string planner = currentRow.GetCell(6)?.ToString();
@ -134,16 +146,6 @@ namespace DOAN.Service.MES.product
: 0;
proWeeklyPlan.CreatedBy = username;
// 处理星期一到星期日第9列开始每4列一组类型、计划数、是否变更、实际数
for (int dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++)
{
int colIndex = 9 + dayOfWeek * 4;
ICell dateCell = sheet.GetRow(2)?.GetCell(colIndex);
ICell dayNameCell = sheet.GetRow(3)?.GetCell(colIndex);
ICell productTypeCell = currentRow.GetCell(colIndex);
ICell planQtyCell = currentRow.GetCell(colIndex + 1);
ICell isChangeCell = currentRow.GetCell(colIndex + 2);
ICell actualQtyCell = currentRow.GetCell(colIndex + 3);
// 2025/8/25 星期一 产品类型
// 2025/8/25
@ -190,19 +192,7 @@ namespace DOAN.Service.MES.product
}
}
var proWeeklyDate = new ProWeeklyDate
{
Id = SnowFlakeSingle.Instance.NextId(),
FkWeeklyId = proWeeklyPlan.Id,
PlanCode = proWeeklyPlan.PlanCode,
WeekDate = weekDate,
DayOfWeek = dayOfWeekName,
ProductType = productType,
PlanNum = planNum,
IsChange = isChange,
ActualQt = actualQt,
CreatedTime = DateTime.Now
};
// 星期一名称
string MondayName = sheet.GetRow(3).GetCell(weekdayindex)?.ToString();
proWeeklyDatePlan.DayOfWeek = MondayName;
@ -228,20 +218,18 @@ namespace DOAN.Service.MES.product
proWeeklyDatePlan.ActualQt = MondayActualQty;
proWeeklyDatePlan.CreatedTime = DateTime.Now;
// 设置周计划的开始和结束日期
if (dayOfWeek == 0 && weekDate.HasValue)
{
proWeeklyPlan.PlanStartDate = weekDate.Value;
proWeeklyPlan.PlanYear = weekDate.Value.Year;
year = weekDate.Value.Year;
}
if (dayOfWeek == 6 && weekDate.HasValue)
{
proWeeklyPlan.PlanEndDate = weekDate.Value;
}
}
// 2025/8/25 星期二 产品类型
// 2025/8/25
ProWeeklyDate proWeeklyDatePlan2 = new ProWeeklyDate();
proWeeklyDatePlan2.Id = SnowFlakeSingle.Instance.NextId();
proWeeklyDatePlan2.FkWeeklyId = proWeeklyPlan.Id;
proWeeklyDatePlan2.PlanCode = proWeeklyPlan.PlanCode;
insertProWeekPlanList.Add(proWeeklyPlan);
DateTime? TuesdayDate = sheet.GetRow(2).GetCell(weekdayindex + 4 * 1)?.DateCellValue;
proWeeklyDatePlan2.WeekDate = TuesdayDate;
// 星期二名称
string TuesdayName = sheet.GetRow(3).GetCell(weekdayindex + 4 * 1)?.ToString();
proWeeklyDatePlan2.DayOfWeek = TuesdayName;
//产品类型
string Tuesdayproducttype = currentRow.GetCell(9 + 4 * 1)?.ToString();
@ -405,13 +393,25 @@ namespace DOAN.Service.MES.product
}
}
// 插入剩余不足500条的数据
if (insertProWeekPlanList.Count > 0)
// 插入数据
UseTran2(() =>
{
InsertBatchData(insertProWeekPlanList, insertProWeeklyDateList, year, week, username);
}
//获取本周本年 所有日计划
Context
.Deleteable<ProWeeklyDate>()
.Where(d =>
SqlFunc.Subqueryable<ProWeeklyPlan>()
.Where(it => it.PlanYear == year && it.PlanWeek == week && it.PlanCode == d.PlanCode)
.Any()).ExecuteCommand();
Context.Deleteable<ProWeeklyPlan>().Where(it => it.PlanYear == year && it.PlanWeek == week).ExecuteCommand();
return insertProWeekPlanList.Count + (insertProWeeklyDateList.Count > 0 ? 0 : 0); // 实际可根据需求返回总插入条数
//批量插入周计划
Context.Insertable(insertProWeekPlanList).ExecuteCommand();
//批量插入日计划
Context.Insertable(insertProWeeklyDateList).ExecuteCommand();
});
return insertProWeekPlanList.Count();
}
catch (Exception ex)
{
@ -589,7 +589,7 @@ namespace DOAN.Service.MES.product
return Context.Queryable<ProWeeklyPlan>()
.WhereIF(weekplanQuery.year > 0, p => p.PlanYear == weekplanQuery.year)
.WhereIF(weekplanQuery.week > 0, p => p.PlanWeek == weekplanQuery.week)
.WhereIF(!string.IsNullOrEmpty(weekplanQuery.partnumber), p => p.ProductCode.Contains(weekplanQuery.partnumber))
.WhereIF(!string.IsNullOrEmpty(weekplanQuery.partnumber), p => p.Specification.Contains(weekplanQuery.partnumber))
.Select(p => new ProWeeklyPlanChildDateDto()
{
Id = p.Id,
@ -639,77 +639,49 @@ namespace DOAN.Service.MES.product
public int UpdateActualAssemblyProgress(int year, int week)
{
int result = 0;
// 1. 获取该周的开始和结束日期
var weekInfo = Context.Queryable<ProWeeklyPlan>()
.Where(it => it.PlanYear == year && it.PlanWeek == week)
.Select(it => new { it.PlanStartDate, it.PlanEndDate })
.First();
if (weekInfo == null)
return result;
DateTime weekStartDate = weekInfo.PlanStartDate;
DateTime weekEndDate = weekInfo.PlanEndDate;
// 2. 查询该周所有的生产计划ProWeeklyPlan
var proWeeklyPlans = Context.Queryable<ProWeeklyPlan>()
.Where(it => it.PlanYear == year && it.PlanWeek == week)
.ToList();
if (proWeeklyPlans == null || !proWeeklyPlans.Any())
return result;
// 3. 提取所有唯一的 (ProductionCode, Specification) 组合,用于后续统计
var planGroups = proWeeklyPlans
.Select(p => new { p.ProductCode, p.Specification, p.Id, p.PlanQty })
.ToList();
if (!planGroups.Any())
return result;
// 4. 【关键优化点】一次性查询所有相关的工单数据,并按 ProductCode + Specification 分组统计总合格数
var workOrderStats = Context.Queryable<ProWorkorder>()
.LeftJoin<ProReportwork>((wo, rw) => wo.Workorder == rw.FkWorkorder) // ⚠️ 请根据实际外键关系修改!!!
.Where((wo, rw) =>
wo.WorkorderDate >= weekStartDate &&
wo.WorkorderDate <= weekEndDate &&
planGroups.Select(pg => pg.ProductCode).Contains(wo.ProductionCode) &&
planGroups.Select(pg => pg.Specification).Contains(wo.Specification)
)
.GroupBy((wo, rw) => new { wo.ProductionCode, wo.Specification })
.Select((wo, rw) => new
{
ProductionCode = wo.ProductionCode,
Specification = wo.Specification,
TotalDeliveryNum = SqlFunc.AggregateSum(rw.QualifiedNumber) ?? 0 // 注意rw 可能是 Reportwork需有 QualifiedNumber 字段
})
.ToList();
// 5. 遍历原始计划,从统计结果中找到对应的 TotalDeliveryNum进行更新
foreach (var plan in proWeeklyPlans)
//获取周的日期开始到结束
var WeekStartAndEnd = Context.Queryable<ProWeeklyPlan>().Where(it => it.PlanYear == year && it.PlanWeek == week)
.Select(it => new { it.PlanStartDate, it.PlanEndDate }).First();
if(WeekStartAndEnd == null)
{
var key = new { plan.ProductCode, plan.Specification };
var stat = workOrderStats.FirstOrDefault(s => s.ProductionCode == key.ProductCode && s.Specification == key.Specification);
int completedQty = stat?.TotalDeliveryNum ?? 0;
int remainingQty = plan.PlanQty - completedQty;
// 只有当数据有变化时才更新(可选,减少不必要的更新)
if (plan.CompletedQty != completedQty || plan.RemainingQty != remainingQty)
{
plan.CompletedQty = completedQty;
plan.RemainingQty = remainingQty;
plan.UpdatedBy = "system";
plan.UpdatedTime = DateTime.Now;
result += Context.Updateable(plan).ExecuteCommand();
}
return result;
}
DateTime WeekStartDate = WeekStartAndEnd.PlanStartDate;
DateTime WeekEndDate = WeekStartAndEnd.PlanEndDate;
//
List<ProWeeklyPlan> proWeeklyPlans = Context.Queryable<ProWeeklyPlan>().Where(it => it.PlanYear == year && it.PlanWeek == week).ToList();
if (proWeeklyPlans.Count > 0)
{
foreach (var plan in proWeeklyPlans)
{
//计算实际装配数
var workorderData = Context
.Queryable<ProWorkorder>()
.LeftJoin<ProReportwork>((w, r) => w.Id == r.Id)
.Where((w, r) => w.WorkorderDate >= WeekStartDate && w.WorkorderDate <= WeekEndDate && w.ProductionCode == plan.ProductCode && w.Specification == plan.Specification)
.GroupBy((w, r) => new { w.ProductionCode, w.Specification })
.Select((w, r) => new
{
w.ProductionCode,
w.Specification,
TotalDeliveryNum = SqlFunc.AggregateSum(r.QualifiedNumber)
}).First();
if (workorderData != null)
{
plan.CompletedQty = workorderData.TotalDeliveryNum ?? 0;
plan.RemainingQty = plan.PlanQty - plan.CompletedQty;
plan.UpdatedBy = "system";
plan.UpdatedTime = DateTime.Now;
result+= Context.Updateable(plan).ExecuteCommand();
}
}
}
return result;
}