zhuangpei-mesbackend/DOAN.Service/MES/product/ProweekplanManageService.cs
17630416519 d7f620bfe0 1
2025-09-15 18:10:40 +08:00

773 lines
38 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 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");
}
}
}
}