773 lines
38 KiB
C#
773 lines
38 KiB
C#
using AlibabaCloud.SDK.Dingtalkworkbench_1_0.Models;
|
||
using DOAN.Model;
|
||
using DOAN.Model.MES.product;
|
||
using DOAN.Model.MES.product.Dto;
|
||
using DOAN.Repository;
|
||
using DOAN.Service.MES.product.IService;
|
||
using Infrastructure;
|
||
using Infrastructure.Attribute;
|
||
using Infrastructure.Extensions;
|
||
using Microsoft.AspNetCore.Hosting;
|
||
using Microsoft.AspNetCore.Http;
|
||
using Microsoft.AspNetCore.Http.HttpResults;
|
||
using NPOI.HPSF;
|
||
using NPOI.HSSF.UserModel;
|
||
using NPOI.SS.Formula.Functions;
|
||
using NPOI.SS.UserModel;
|
||
using NPOI.XSSF.UserModel;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Text.RegularExpressions;
|
||
using System.Threading.Tasks;
|
||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||
|
||
|
||
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)
|
||
{
|
||
|
||
using (var stream = formFile.OpenReadStream())
|
||
{
|
||
try
|
||
{
|
||
List<ProWeeklyPlan> insertProWeekPlanList = new List<ProWeeklyPlan>();
|
||
List<ProWeeklyDate> insertProWeeklyDateList = new List<ProWeeklyDate>();
|
||
|
||
|
||
IWorkbook workbook = new XSSFWorkbook(stream);
|
||
ISheet sheet = workbook.GetSheet("Sheet1");
|
||
// 处理第2行 获取日期
|
||
|
||
IRow secondRow = sheet.GetRow(1);
|
||
NPOI.SS.UserModel.ICell cell = secondRow.GetCell(0);
|
||
|
||
string title = cell.ToString();
|
||
//提取括号内的数字
|
||
int week = extractWeek(title);
|
||
int year = DateTime.Now.Year;
|
||
|
||
// 遍历每一行
|
||
for (int row = 6; row <= sheet.LastRowNum; row++)
|
||
{
|
||
int index = row - 5;
|
||
IRow currentRow = sheet.GetRow(row);
|
||
if (currentRow != null) // 确保行不为空
|
||
{
|
||
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();
|
||
proWeeklyPlan.Planner = planner;
|
||
//本周计划装配数量
|
||
double plan_qty = currentRow.GetCell(7).NumericCellValue;
|
||
proWeeklyPlan.PlanQty = (int)plan_qty;
|
||
|
||
//本周实际装配数
|
||
double actual_qty = currentRow.GetCell(8).NumericCellValue;
|
||
proWeeklyPlan.CompletedQty = (int)actual_qty;
|
||
proWeeklyPlan.CreatedBy = username;
|
||
|
||
|
||
// 2025/8/25 星期一 产品类型
|
||
// 2025/8/25
|
||
ProWeeklyDate proWeeklyDatePlan = new ProWeeklyDate();
|
||
proWeeklyDatePlan.Id = SnowFlakeSingle.Instance.NextId();
|
||
proWeeklyDatePlan.FkWeeklyId = proWeeklyPlan.Id;
|
||
proWeeklyDatePlan.PlanCode = proWeeklyPlan.PlanCode;
|
||
int weekdayindex = 9;
|
||
DateTime? MondayDate = sheet.GetRow(2).GetCell(weekdayindex)?.DateCellValue;
|
||
proWeeklyDatePlan.WeekDate = MondayDate??DateTime.MinValue;
|
||
proWeeklyPlan.PlanStartDate = MondayDate ?? DateTime.MinValue;
|
||
proWeeklyPlan.PlanYear = MondayDate.Value.Year;
|
||
year = MondayDate.Value.Year;
|
||
|
||
// 星期一名称
|
||
|
||
string MondayName = sheet.GetRow(3).GetCell(weekdayindex)?.ToString();
|
||
proWeeklyDatePlan.DayOfWeek = MondayName;
|
||
//产品类型
|
||
string Mondayproducttype = currentRow.GetCell(9)?.ToString();
|
||
proWeeklyDatePlan.ProductType = Mondayproducttype;
|
||
//计划数量
|
||
int MondayPlanQty = (int)currentRow.GetCell(10)?.NumericCellValue;
|
||
proWeeklyDatePlan.PlanNum = MondayPlanQty;
|
||
//是否变更
|
||
string MondayIsChange = currentRow.GetCell(11)?.ToString();
|
||
proWeeklyDatePlan.IsChange = MondayIsChange;
|
||
//实际数量
|
||
int MondayActualQty = (int)currentRow.GetCell(12)?.NumericCellValue;
|
||
proWeeklyDatePlan.ActualQt = MondayActualQty;
|
||
proWeeklyDatePlan.CreatedTime = DateTime.Now;
|
||
|
||
// 2025/8/25 星期二 产品类型
|
||
// 2025/8/25
|
||
ProWeeklyDate proWeeklyDatePlan2 = new ProWeeklyDate();
|
||
proWeeklyDatePlan2.Id = SnowFlakeSingle.Instance.NextId();
|
||
proWeeklyDatePlan2.FkWeeklyId = proWeeklyPlan.Id;
|
||
proWeeklyDatePlan2.PlanCode = proWeeklyPlan.PlanCode;
|
||
|
||
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();
|
||
proWeeklyDatePlan2.ProductType = Tuesdayproducttype;
|
||
|
||
//计划数量
|
||
int TuesdayPlanQty = (int)currentRow.GetCell(10 + 4 * 1)?.NumericCellValue;
|
||
proWeeklyDatePlan2.PlanNum = TuesdayPlanQty;
|
||
//是否变更
|
||
string TuesdayIsChange = currentRow.GetCell(11 + 4 * 1)?.ToString();
|
||
proWeeklyDatePlan2.IsChange = TuesdayIsChange;
|
||
//实际数量
|
||
int TuesdayActualQty = (int)currentRow.GetCell(12)?.NumericCellValue;
|
||
proWeeklyDatePlan2.ActualQt = TuesdayActualQty;
|
||
proWeeklyDatePlan2.CreatedTime = DateTime.Now;
|
||
|
||
// 2025/8/25 星期三 产品类型
|
||
// 2025/8/25
|
||
|
||
ProWeeklyDate proWeeklyDatePlan3 = new ProWeeklyDate();
|
||
proWeeklyDatePlan3.Id = SnowFlakeSingle.Instance.NextId();
|
||
proWeeklyDatePlan3.FkWeeklyId = proWeeklyPlan.Id;
|
||
proWeeklyDatePlan3.PlanCode = proWeeklyPlan.PlanCode;
|
||
DateTime? WednesdayDate = sheet.GetRow(2).GetCell(weekdayindex + 4 * 2)?.DateCellValue;
|
||
proWeeklyDatePlan3.WeekDate = WednesdayDate;
|
||
// 星期三名称
|
||
string WednesdayName = sheet.GetRow(3).GetCell(weekdayindex + 4 * 2)?.ToString();
|
||
proWeeklyDatePlan3.DayOfWeek = WednesdayName;
|
||
//产品类型
|
||
string Wednesdayproducttype = currentRow.GetCell(9 + 4 * 2)?.ToString();
|
||
proWeeklyDatePlan3.ProductType = Wednesdayproducttype;
|
||
//计划数量
|
||
int WednesdayPlanQty = (int)currentRow.GetCell(10 + 4 * 2)?.NumericCellValue;
|
||
proWeeklyDatePlan3.PlanNum = WednesdayPlanQty;
|
||
//是否变更
|
||
string WednesdayIsChange = currentRow.GetCell(11 + 4 * 2)?.ToString();
|
||
proWeeklyDatePlan3.IsChange = WednesdayIsChange;
|
||
//实际数量
|
||
int WednesdayActualQty = (int)currentRow.GetCell(12 + 4 * 2)?.NumericCellValue;
|
||
proWeeklyDatePlan3.ActualQt = WednesdayActualQty;
|
||
proWeeklyDatePlan3.CreatedTime = DateTime.Now;
|
||
|
||
|
||
|
||
// 2025/8/25 星期四 产品类型
|
||
// 2025/8/25
|
||
ProWeeklyDate proWeeklyDatePlan4 = new ProWeeklyDate();
|
||
proWeeklyDatePlan4.Id = SnowFlakeSingle.Instance.NextId();
|
||
proWeeklyDatePlan4.FkWeeklyId = proWeeklyPlan.Id;
|
||
proWeeklyDatePlan4.PlanCode = proWeeklyPlan.PlanCode;
|
||
DateTime? ThursdayDate = sheet.GetRow(2).GetCell(weekdayindex + 4 * 3)?.DateCellValue;
|
||
proWeeklyDatePlan4.WeekDate = ThursdayDate;
|
||
// 星期三名称
|
||
string ThursdayName = sheet.GetRow(3).GetCell(weekdayindex + 4 * 3)?.ToString();
|
||
proWeeklyDatePlan4.DayOfWeek = ThursdayName;
|
||
//产品类型
|
||
string Thursdayproducttype = currentRow.GetCell(9 + 4 * 3)?.ToString();
|
||
proWeeklyDatePlan4.ProductType = Thursdayproducttype;
|
||
//计划数量
|
||
int ThursdayPlanQty = (int)currentRow.GetCell(10 + 4 * 3)?.NumericCellValue;
|
||
proWeeklyDatePlan4.PlanNum = ThursdayPlanQty;
|
||
//是否变更
|
||
string ThursdayIsChange = currentRow.GetCell(11 + 4 * 3)?.ToString();
|
||
proWeeklyDatePlan4.IsChange = ThursdayIsChange;
|
||
//实际数量
|
||
int ThursdayActualQty = (int)currentRow.GetCell(12 + 4 * 3)?.NumericCellValue;
|
||
proWeeklyDatePlan4.ActualQt = ThursdayActualQty;
|
||
proWeeklyDatePlan4.CreatedTime = DateTime.Now;
|
||
|
||
// 2025/8/25 星期五 产品类型
|
||
// 2025/8/25
|
||
ProWeeklyDate proWeeklyDatePlan5 = new ProWeeklyDate();
|
||
proWeeklyDatePlan5.Id = SnowFlakeSingle.Instance.NextId();
|
||
proWeeklyDatePlan5.FkWeeklyId = proWeeklyPlan.Id;
|
||
proWeeklyDatePlan5.PlanCode = proWeeklyPlan.PlanCode;
|
||
DateTime? FridayDate = sheet.GetRow(2).GetCell(weekdayindex + 4 * 4)?.DateCellValue;
|
||
proWeeklyDatePlan5.WeekDate = FridayDate;
|
||
// 星期三名称
|
||
string FridayName = sheet.GetRow(3).GetCell(weekdayindex + 4 * 4)?.ToString();
|
||
proWeeklyDatePlan5.DayOfWeek = FridayName;
|
||
//产品类型
|
||
string Fridayproducttype = currentRow.GetCell(9 + 4 * 4)?.ToString();
|
||
proWeeklyDatePlan5.ProductType = Fridayproducttype;
|
||
//计划数量
|
||
int FridayPlanQty = (int)currentRow.GetCell(10 + 4 * 4)?.NumericCellValue;
|
||
proWeeklyDatePlan5.PlanNum = FridayPlanQty;
|
||
//是否变更
|
||
string FridayIsChange = currentRow.GetCell(11 + 4 * 4)?.ToString();
|
||
proWeeklyDatePlan5.IsChange = FridayIsChange;
|
||
//实际数量
|
||
int FridayActualQty = (int)currentRow.GetCell(12 + 4 * 4)?.NumericCellValue;
|
||
proWeeklyDatePlan5.ActualQt = FridayActualQty;
|
||
proWeeklyDatePlan5.CreatedTime = DateTime.Now;
|
||
// 2025/8/25 星期六 产品类型
|
||
// 2025/8/25
|
||
|
||
ProWeeklyDate proWeeklyDatePlan6 = new ProWeeklyDate();
|
||
proWeeklyDatePlan6.Id = SnowFlakeSingle.Instance.NextId();
|
||
proWeeklyDatePlan6.FkWeeklyId = proWeeklyPlan.Id;
|
||
proWeeklyDatePlan6.PlanCode = proWeeklyPlan.PlanCode;
|
||
DateTime? SaturdayDate = sheet.GetRow(2).GetCell(weekdayindex + 4 * 5)?.DateCellValue;
|
||
proWeeklyDatePlan6.WeekDate = SaturdayDate;
|
||
// 星期三名称
|
||
string SaturdayName = sheet.GetRow(3).GetCell(weekdayindex + 4 * 5)?.ToString();
|
||
proWeeklyDatePlan6.DayOfWeek = SaturdayName;
|
||
//产品类型
|
||
string Saturdayproducttype = currentRow.GetCell(9 + 4 * 5)?.ToString();
|
||
proWeeklyDatePlan6.ProductType = Saturdayproducttype;
|
||
//计划数量
|
||
int SaturdayPlanQty = (int)currentRow.GetCell(10 + 4 * 5)?.NumericCellValue;
|
||
proWeeklyDatePlan6.PlanNum = SaturdayPlanQty;
|
||
//是否变更
|
||
string SaturdayIsChange = currentRow.GetCell(11 + 4 * 5)?.ToString();
|
||
proWeeklyDatePlan6.IsChange = SaturdayIsChange;
|
||
//实际数量
|
||
int SaturdayActualQty = (int)currentRow.GetCell(12 + 4 * 5)?.NumericCellValue;
|
||
proWeeklyDatePlan6.ActualQt = SaturdayActualQty;
|
||
proWeeklyDatePlan6.CreatedTime = DateTime.Now;
|
||
|
||
// 2025/8/25 星期日 产品类型
|
||
// 2025/8/25
|
||
ProWeeklyDate proWeeklyDatePlan7 = new ProWeeklyDate();
|
||
proWeeklyDatePlan7.Id = SnowFlakeSingle.Instance.NextId();
|
||
proWeeklyDatePlan7.FkWeeklyId = proWeeklyPlan.Id;
|
||
proWeeklyDatePlan7.PlanCode = proWeeklyPlan.PlanCode;
|
||
DateTime? SundayDate = sheet.GetRow(2).GetCell(weekdayindex + 4 * 6)?.DateCellValue;
|
||
proWeeklyDatePlan7.WeekDate = SundayDate;
|
||
// 星期三名称
|
||
string SundayName = sheet.GetRow(3).GetCell(weekdayindex + 4 * 6)?.ToString();
|
||
proWeeklyDatePlan7.DayOfWeek = SundayName;
|
||
//产品类型
|
||
string Sundayproducttype = currentRow.GetCell(9 + 4 * 6)?.ToString();
|
||
|
||
|
||
proWeeklyDatePlan7.ProductType = Sundayproducttype;
|
||
//计划数量
|
||
int SundayPlanQty = (int)currentRow.GetCell(10 + 4 * 6)?.NumericCellValue;
|
||
proWeeklyDatePlan7.PlanNum = SundayPlanQty;
|
||
//是否变更
|
||
string SundayIsChange = currentRow.GetCell(11 + 4 * 6)?.ToString();
|
||
proWeeklyDatePlan7.IsChange = SundayIsChange;
|
||
//实际数量
|
||
int SundayActualQty = (int)currentRow.GetCell(12 + 4 * 6)?.NumericCellValue;
|
||
proWeeklyDatePlan7.ActualQt = SundayActualQty;
|
||
proWeeklyDatePlan7.CreatedTime = DateTime.Now;
|
||
proWeeklyPlan.PlanEndDate = (DateTime)SundayDate;
|
||
|
||
|
||
insertProWeekPlanList.Add(proWeeklyPlan);
|
||
insertProWeeklyDateList.Add(proWeeklyDatePlan);
|
||
insertProWeeklyDateList.Add(proWeeklyDatePlan2);
|
||
insertProWeeklyDateList.Add(proWeeklyDatePlan3);
|
||
insertProWeeklyDateList.Add(proWeeklyDatePlan4);
|
||
insertProWeeklyDateList.Add(proWeeklyDatePlan5);
|
||
insertProWeeklyDateList.Add(proWeeklyDatePlan6);
|
||
insertProWeeklyDateList.Add(proWeeklyDatePlan7);
|
||
}
|
||
}
|
||
|
||
// 插入数据
|
||
UseTran2(() =>
|
||
{
|
||
//获取本周本年 所有日计划
|
||
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();
|
||
|
||
//批量插入周计划
|
||
Context.Insertable(insertProWeekPlanList).ExecuteCommand();
|
||
//批量插入日计划
|
||
Context.Insertable(insertProWeeklyDateList).ExecuteCommand();
|
||
|
||
});
|
||
return insertProWeekPlanList.Count();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
throw ex;
|
||
}
|
||
}
|
||
}
|
||
const int BATCH_SIZE = 500;
|
||
|
||
/// <summary>
|
||
/// 处理一行Excel数据
|
||
/// </summary>
|
||
/// <param name="row">当前行</param>
|
||
/// <param name="index">索引</param>
|
||
/// <param name="username">用户名</param>
|
||
/// <param name="week">周数</param>
|
||
/// <param name="weekDays">星期信息</param>
|
||
/// <returns>计划和日期列表</returns>
|
||
private (ProWeeklyPlan, List<ProWeeklyDate>) ProcessRow(IRow row, int index, string username, int week, List<(DateTime Date, string DayName, int DateCellIndex)> weekDays)
|
||
{
|
||
try
|
||
{
|
||
ProWeeklyPlan proWeeklyPlan = new ProWeeklyPlan();
|
||
proWeeklyPlan.Id = SnowFlakeSingle.Instance.NextId();
|
||
proWeeklyPlan.PlanCode = "WP" + DateTime.Now.ToString("yyMM") + index.ToString("000");
|
||
proWeeklyPlan.PlanYear = weekDays.Any() ? weekDays.First().Date.Year : DateTime.Now.Year;
|
||
proWeeklyPlan.PlanWeek = week;
|
||
proWeeklyPlan.CreatedTime = DateTime.Now;
|
||
proWeeklyPlan.CreatedBy = username;
|
||
|
||
//班组
|
||
proWeeklyPlan.GroupName = row.GetCell(0)?.ToString();
|
||
//车型
|
||
string part_no = row.GetCell(1)?.ToString();
|
||
//产品编码
|
||
proWeeklyPlan.ProductCode = row.GetCell(2)?.ToString();
|
||
//产品名称
|
||
proWeeklyPlan.ProductName = row.GetCell(3)?.ToString();
|
||
//产品零件号
|
||
proWeeklyPlan.Specification = row.GetCell(4)?.ToString();
|
||
//生产状态
|
||
string planStatus = row.GetCell(5)?.ToString();
|
||
if (!string.IsNullOrEmpty(planStatus))
|
||
{
|
||
proWeeklyPlan.PlanStatus = planStatus;
|
||
}
|
||
|
||
//车间计划员
|
||
proWeeklyPlan.Planner = row.GetCell(6)?.ToString();
|
||
//本周计划装配数量
|
||
if (row.GetCell(7) != null)
|
||
{
|
||
double planQty = row.GetCell(7).NumericCellValue;
|
||
proWeeklyPlan.PlanQty = (int)planQty;
|
||
}
|
||
|
||
//本周实际装配数
|
||
if (row.GetCell(8) != null)
|
||
{
|
||
double actualQty = row.GetCell(8).NumericCellValue;
|
||
proWeeklyPlan.CompletedQty = (int)actualQty;
|
||
}
|
||
|
||
// 设置计划开始和结束日期
|
||
if (weekDays.Any())
|
||
{
|
||
proWeeklyPlan.PlanStartDate = weekDays.First().Date;
|
||
proWeeklyPlan.PlanEndDate = weekDays.Last().Date;
|
||
}
|
||
|
||
// 创建每日计划
|
||
List<ProWeeklyDate> weeklyDates = new List<ProWeeklyDate>();
|
||
foreach (var (date, dayName, colIndex) in weekDays)
|
||
{
|
||
// 确保列索引有效
|
||
if (colIndex + 3 <= row.LastCellNum) // 检查是否有足够的列
|
||
{
|
||
// 产品类型
|
||
string productType = row.GetCell(colIndex)?.ToString();
|
||
// 计划数量
|
||
int planNum = 0;
|
||
if (row.GetCell(colIndex + 1) != null)
|
||
{
|
||
planNum = (int)row.GetCell(colIndex + 1).NumericCellValue;
|
||
}
|
||
// 是否变更
|
||
string isChange = row.GetCell(colIndex + 2)?.ToString();
|
||
// 实际数量
|
||
int actualQt = 0;
|
||
if (row.GetCell(colIndex + 3) != null)
|
||
{
|
||
actualQt = (int)row.GetCell(colIndex + 3).NumericCellValue;
|
||
}
|
||
|
||
ProWeeklyDate weeklyDate = new ProWeeklyDate
|
||
{
|
||
Id = SnowFlakeSingle.Instance.NextId(),
|
||
FkWeeklyId = proWeeklyPlan.Id,
|
||
PlanCode = proWeeklyPlan.PlanCode,
|
||
WeekDate = date,
|
||
DayOfWeek = dayName,
|
||
ProductType = productType,
|
||
PlanNum = planNum,
|
||
IsChange = isChange,
|
||
ActualQt = actualQt,
|
||
CreatedTime = DateTime.Now,
|
||
CreateBy = username
|
||
};
|
||
|
||
weeklyDates.Add(weeklyDate);
|
||
}
|
||
}
|
||
|
||
return (proWeeklyPlan, weeklyDates);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 记录错误但继续处理其他行
|
||
Console.WriteLine($"处理行数据时出错: {ex.Message}");
|
||
return (null, null);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 批量处理数据并执行数据库操作
|
||
/// </summary>
|
||
/// <param name="weeklyPlans">周计划列表</param>
|
||
/// <param name="weeklyDates">日期计划列表</param>
|
||
/// <param name="year">年份</param>
|
||
/// <param name="week">周数</param>
|
||
private void ProcessBatchData(List<ProWeeklyPlan> weeklyPlans, List<ProWeeklyDate> weeklyDates, int year, int week)
|
||
{
|
||
if (!weeklyPlans.Any()) return;
|
||
|
||
UseTran2(() =>
|
||
{
|
||
// 如果是第一批数据,删除本周的旧数据
|
||
if (weeklyPlans.Count <= BATCH_SIZE * 2) // 简单判断是否为第一批
|
||
{
|
||
Context.Deleteable<ProWeeklyPlan>().Where(p => p.PlanYear == year && p.PlanWeek == week).ExecuteCommand();
|
||
// 不需要单独删除ProWeeklyDate,因为它们通过外键关联会被级联删除
|
||
}
|
||
|
||
// 批量插入周计划
|
||
if (weeklyPlans.Any())
|
||
{
|
||
Context.Insertable(weeklyPlans).ExecuteCommand();
|
||
}
|
||
|
||
// 批量插入日期计划
|
||
if (weeklyDates.Any())
|
||
{
|
||
// 分批插入,每批最多2000条记录
|
||
const int MAX_BATCH_INSERT = 2000;
|
||
for (int i = 0; i < weeklyDates.Count; i += MAX_BATCH_INSERT)
|
||
{
|
||
var batch = weeklyDates.Skip(i).Take(MAX_BATCH_INSERT).ToList();
|
||
if (batch.Any())
|
||
{
|
||
Context.Insertable(batch).ExecuteCommand();
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
public PagedInfo<ProWeeklyPlanChildDateDto> SearchWeekplan(WeekplanQueryDto weekplanQuery)
|
||
{
|
||
if (weekplanQuery == null)
|
||
{
|
||
return null;
|
||
}
|
||
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.Specification.Contains(weekplanQuery.partnumber))
|
||
.Select(p => new ProWeeklyPlanChildDateDto()
|
||
{
|
||
Id = p.Id,
|
||
PlanCode = p.PlanCode,
|
||
PlanYear = p.PlanYear,
|
||
PlanWeek = p.PlanWeek,
|
||
PlanStartDate = p.PlanStartDate,
|
||
PlanEndDate = p.PlanEndDate,
|
||
OrderCode = p.OrderCode,
|
||
ProductCode = p.ProductCode,
|
||
ProductName = p.ProductName,
|
||
Specification = p.Specification,
|
||
Color = p.Color,
|
||
PlanQty = p.PlanQty,
|
||
CompletedQty = p.CompletedQty,
|
||
RemainingQty = p.PlanQty - p.CompletedQty, // 若数据库中没有,可在此计算
|
||
ScrapQty = p.ScrapQty,
|
||
WorkshopCode = p.WorkshopCode,
|
||
WorkshopName = p.WorkshopName,
|
||
LineCode = p.LineCode,
|
||
LineName = p.LineName,
|
||
GroupCode = p.GroupCode,
|
||
GroupName = p.GroupName,
|
||
ShiftType = p.ShiftType,
|
||
PlanStatus = p.PlanStatus,
|
||
Planner = p.Planner,
|
||
Priority = p.Priority,
|
||
Sort = p.Sort,
|
||
MaterialReady = p.MaterialReady,
|
||
Remark = p.Remark,
|
||
CreatedBy = p.CreatedBy,
|
||
CreatedTime = p.CreatedTime, // 假设 p 中有此字段,否则用 DateTime.Now
|
||
UpdatedBy = p.UpdatedBy,
|
||
UpdatedTime = p.UpdatedTime,
|
||
proWeeklyDatechildList = SqlFunc.Subqueryable<ProWeeklyDate>()
|
||
.Where(d => d.PlanCode == p.PlanCode)
|
||
.ToList()
|
||
|
||
|
||
|
||
|
||
|
||
}).ToPage_NO_Convert(weekplanQuery);
|
||
|
||
}
|
||
|
||
public int UpdateActualAssemblyProgress(int year, int week)
|
||
{
|
||
int result = 0;
|
||
//获取周的日期开始到结束
|
||
var WeekStartAndEnd = Context.Queryable<ProWeeklyPlan>().Where(it => it.PlanYear == year && it.PlanWeek == week)
|
||
.Select(it => new { it.PlanStartDate, it.PlanEndDate }).First();
|
||
if(WeekStartAndEnd == null)
|
||
{
|
||
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;
|
||
|
||
}
|
||
|
||
|
||
|
||
private int extractWeek(string title)
|
||
{
|
||
global::System.Text.RegularExpressions.Match match = Regex.Match(title, @"[((](\d+)[))]");
|
||
|
||
if (match.Success)
|
||
{
|
||
string numberStr = match.Groups[1].Value; // 获取第一个捕获组中的内容,即数字部分
|
||
if (int.TryParse(numberStr, out int weekNumber))
|
||
{
|
||
Console.WriteLine("提取到的周数是: " + weekNumber); // 输出: 35
|
||
return weekNumber;
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine("括号内不是有效的数字。");
|
||
return -1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine("未找到括号内的数字。");
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 导出日计划
|
||
/// </summary>
|
||
/// <param name="year"></param>
|
||
/// <param name="week"></param>
|
||
/// <param name="dayofweek"></param>
|
||
(byte[] fileBytes, string fileName) IProweekplanManageService.ExportWeekDatePlan(int year, int week, string dayofweek)
|
||
{
|
||
// 1. 查询数据:周日计划及关联日期数据
|
||
List<ProWeeklyPlanAndDateDto> ProWeeklyPlanAndDateList = Context.Queryable<ProWeeklyPlan>()
|
||
.LeftJoin<ProWeeklyDate>((p, d) => p.PlanCode == d.PlanCode)
|
||
.WhereIF(year > 0, (p, d) => p.PlanYear == year)
|
||
.WhereIF(week > 0, (p, d) => p.PlanWeek == week)
|
||
.WhereIF(!string.IsNullOrEmpty(dayofweek), (p, d) => d.DayOfWeek == dayofweek)
|
||
.Select((p, d) => new ProWeeklyPlanAndDateDto
|
||
{
|
||
// ProWeeklyPlan 字段(p)
|
||
ProWeeklyPlanId = p.Id,
|
||
PlanCode = p.PlanCode,
|
||
PlanYear = p.PlanYear,
|
||
PlanWeek = p.PlanWeek,
|
||
PlanStartDate = p.PlanStartDate,
|
||
PlanEndDate = p.PlanEndDate,
|
||
OrderCode = p.OrderCode,
|
||
ProductCode = p.ProductCode,
|
||
ProductName = p.ProductName,
|
||
Specification = p.Specification,
|
||
Color = p.Color,
|
||
PlanQty = p.PlanQty,
|
||
CompletedQty = p.CompletedQty,
|
||
RemainingQty = p.PlanQty - p.CompletedQty,
|
||
ScrapQty = p.ScrapQty,
|
||
WorkshopCode = p.WorkshopCode,
|
||
WorkshopName = p.WorkshopName,
|
||
LineCode = p.LineCode,
|
||
LineName = p.LineName,
|
||
GroupCode = p.GroupCode,
|
||
GroupName = p.GroupName,
|
||
ShiftType = p.ShiftType,
|
||
PlanStatus = p.PlanStatus,
|
||
Planner = p.Planner,
|
||
Priority = p.Priority,
|
||
Sort = p.Sort,
|
||
MaterialReady = p.MaterialReady,
|
||
Remark = p.Remark,
|
||
ProWeeklyPlanCreatedBy = p.CreatedBy,
|
||
ProWeeklyPlanCreatedTime = p.CreatedTime,
|
||
ProWeeklyPlanUpdatedBy = p.UpdatedBy,
|
||
ProWeeklyPlanUpdatedTime = p.UpdatedTime,
|
||
|
||
// ProWeeklyDate 字段(d)
|
||
ProWeeklyDateId = d.Id,
|
||
FkWeeklyId = d.FkWeeklyId,
|
||
ProWeeklyPlanPlanCode = d.PlanCode,
|
||
WeekDate = d.WeekDate,
|
||
DayOfWeek = d.DayOfWeek,
|
||
ProductType = d.ProductType,
|
||
PlanNum = d.PlanNum,
|
||
IsChange = d.IsChange,
|
||
ActualQt = d.ActualQt,
|
||
CreateBy = d.CreateBy,
|
||
CreatedTime = d.CreatedTime,
|
||
UpdateBy = d.UpdateBy,
|
||
UpdatedTime = d.UpdatedTime
|
||
})
|
||
.ToList();
|
||
|
||
// 2. 转为工单列表(可选,如果你后续要用,目前你只是导出 Excel)
|
||
List<ProWorkorder> proWorkorderList = new List<ProWorkorder>();
|
||
|
||
if (ProWeeklyPlanAndDateList != null && ProWeeklyPlanAndDateList.Count > 0)
|
||
{
|
||
foreach (var item in ProWeeklyPlanAndDateList)
|
||
{
|
||
ProWorkorder proWorkorder = new ProWorkorder
|
||
{
|
||
Id = SnowFlakeSingle.Instance.NextId().ToString(),
|
||
Workorder = string.Empty,
|
||
ProductionCode = item.ProductCode,
|
||
ProductionName = item.ProductName,
|
||
Specification = item.Specification,
|
||
DeliveryNum = item.PlanNum
|
||
};
|
||
proWorkorderList.Add(proWorkorder);
|
||
}
|
||
}
|
||
|
||
// 3. 读取 Excel 模板
|
||
IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment));
|
||
string fileName = "workorder"; // 模板文件名(不含扩展名)
|
||
string sFileName = $"{fileName}.xlsx";
|
||
string fullPath = Path.Combine(webHostEnvironment.WebRootPath, "ImportTemplate", sFileName);
|
||
|
||
if (!global::System.IO.File.Exists(fullPath))
|
||
{
|
||
throw new CustomException("Excel 模板文件未找到,请确保 ImportTemplate/workorder.xlsx 存在");
|
||
}
|
||
|
||
// 4. 加载模板 workbook
|
||
using (FileStream fileStream = new FileStream(fullPath, FileMode.Open, FileAccess.Read))
|
||
{
|
||
IWorkbook workbook = new XSSFWorkbook(fileStream);
|
||
ISheet sheet = workbook.GetSheet("Sheet1");
|
||
if (sheet == null)
|
||
{
|
||
throw new CustomException("未找到 Sheet1,请检查 Excel 模板");
|
||
}
|
||
|
||
// 5. 填充数据(从第4行开始,即索引 3)
|
||
int dataRowIndex = 3;
|
||
|
||
// 可选:在第一行写入当前时间(比如 A2 单元格)
|
||
if (sheet.GetRow(1) != null)
|
||
{
|
||
sheet.GetRow(1).CreateCell(0).SetCellValue(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
|
||
}
|
||
|
||
// 6. 遍历工单数据,填充每一行
|
||
foreach (var item in proWorkorderList)
|
||
{
|
||
IRow dataRow = sheet.GetRow(dataRowIndex) ?? sheet.CreateRow(dataRowIndex);
|
||
dataRow.CreateCell(0).SetCellValue(item.ProductionCode); // A列
|
||
dataRow.CreateCell(1).SetCellValue(item.ProductionName); // B列
|
||
dataRow.CreateCell(2).SetCellValue(item.Specification); // C列
|
||
dataRow.CreateCell(4).SetCellValue((double)item.DeliveryNum); // D列
|
||
dataRowIndex++;
|
||
}
|
||
|
||
// 7. 写入到 MemoryStream(关键:不要用 using 包裹,否则流会被释放!)
|
||
var memoryStream = new MemoryStream();
|
||
workbook.Write(memoryStream);
|
||
|
||
|
||
// 8. 返回 byte[] 和文件名
|
||
return (memoryStream.ToArray(), "导出数据.xlsx");
|
||
}
|
||
}
|
||
}
|
||
}
|