using Infrastructure; using Infrastructure.Attribute; using Microsoft.AspNetCore.Hosting; using MiniExcelLibs; using Model.DBModel; using SqlSugar; using System; using System.IO; using System.Linq; using ZR.Model.mes.pro; using ZR.Model.MES.pro.DTO; using ZR.Model.MES.wms; using ZR.Service.mes.pro.IService; namespace ZR.Service.mes.pro { [AppService(ServiceType = typeof(IProWorkplanServiceV2), ServiceLifetime = LifeTime.Transient)] public class ProWorkplanServiceV2 : BaseService, IProWorkplanServiceV2 { public (List, int) GetAllData(int pageNum, int pageSize, int year, int week, string partNumber, string color) { // 如果年份为空(小于等于0),使用当天的年份 if (year <= 0) { year = DateTime.Now.Year; } var predicate = Expressionable.Create() .AndIF(year > 0, it => it.Year == year) .AndIF(week > 0, it => it.Week == week) .AndIF(!string.IsNullOrEmpty(partNumber), it => it.Partnumber.Contains(partNumber)) .AndIF(!string.IsNullOrEmpty(color), it => it.ColorCode.Contains(color)) .ToExpression(); int totalCount = 0; List proWorkplanList = Context.Queryable() .Where(predicate) .OrderBy(it => it.Id) .ToPageList(pageNum, pageSize, ref totalCount); // 计划是否正确检查 List proWorkplanDtoList = new List(); foreach (ProWorklplan_v2 item in proWorkplanList) { ProWorklplanDto plan = new() { Id = item.Id, Week = item.Week, Year = item.Year, BlankNum = item.BlankNum, Partnumber = item.Partnumber, ProductName = item.ProductName, Specification = item.Specification, ColorCode = item.ColorCode, ProductionBeat = item.ProductionBeat, ProductTime = item.ProductTime, NoSchedule = item.NoSchedule, QualificationRate = item.QualificationRate, RequireHanger = item.RequireHanger, AllHangerNum = item.AllHangerNum, EveryHangerNum = item.EveryHangerNum, RequireNum = item.RequireNum, TurnNumber = item.TurnNumber, Remark = item.Remark, CreatedBy = item.CreatedBy, CreatedTime = item.CreatedTime, UpdatedBy = item.UpdatedBy, UpdatedTime = item.UpdatedTime, }; plan.State = CheckWorkPlan(item); proWorkplanDtoList.Add(plan); } return (proWorkplanDtoList, totalCount); } public List GetProWorkplanById(string id) { return Context.Queryable().Where(it => it.Id == id).ToList(); } public int AddWorkPlan(ProWorklplan_v2 proWorkplan) { // 获取当前日期和周信息 DateTime now = DateTime.Now; int currentYear = now.Year; int currentWeek = GetWeekNumber(now); if (proWorkplan.Year <= 0) { proWorkplan.Year = currentYear; } if (proWorkplan.Week <= 0) { proWorkplan.Week = currentWeek; } string timeStr; // 判断是否为本周 if (proWorkplan.Year == currentYear && proWorkplan.Week == currentWeek) { // 本周使用当前日期 timeStr = now.ToString("yyyyMMdd"); } else { // 非本周使用该周的周一日期(yyyyMMdd格式) DateTime weekMonday = GetMondayOfWeek(proWorkplan.Year, proWorkplan.Week); timeStr = weekMonday.ToString("yyyyMMdd"); } proWorkplan.Id = "MP" + timeStr + Getworkplanid_max(timeStr).ToString("000"); proWorkplan.Remark = "手动插入"; return Context.Insertable(proWorkplan).ExecuteCommand(); } public string ImportExceldata(List worklplanList) { if (worklplanList == null || worklplanList.Count == 0) { return "导入数据为空"; } // 获取第一条数据的年份和周信息 ProWorklplan_v2 firstPlan = worklplanList.First(); int year = firstPlan.Year; int week = firstPlan.Week; // 获取当前日期和周信息 DateTime now = DateTime.Now; int currentYear = now.Year; int currentWeek = GetWeekNumber(now); string timeStr; // 判断是否为本周 if (year == currentYear && week == currentWeek) { // 本周使用当前日期 timeStr = now.ToString("yyyyMMdd"); } else { // 非本周使用该周的周一日期(yyyyMMdd格式) DateTime weekMonday = GetMondayOfWeek(year, week); timeStr = weekMonday.ToString("yyyyMMdd"); } int max_id = Getworkplanid_max(timeStr); worklplanList.ForEach(it => { it.Id = "MP" + timeStr + max_id.ToString("000"); it.Remark = "Excel导入"; max_id++; }); var x = Context.Storageable(worklplanList) .SplitUpdate(it => it.Any())//存在更新 .SplitInsert(it => true)//否则插入(更新优先级大于插入) .WhereColumns(it => new { it.Id, it.Year, it.Week, it.Partnumber })//如果不是主键可以这样实现(多字段it=>new{it.x1,it.x2}) .ToStorage(); x.AsInsertable.ExecuteCommand();//插入可插入部分; x.AsUpdateable.IgnoreColumns(it => it.Id).ExecuteCommand();//存在更新 string msg = string.Format(" 插入{0} 更新{1} 错误数据{2} 不计算数据{3} 删除数据{4} 总共{5}", x.InsertList.Count, x.UpdateList.Count, x.ErrorList.Count, x.IgnoreList.Count, x.DeleteList.Count, x.TotalList.Count); return msg; //插入可插入部分 } /// /// 下载 /// /// /// /// public (string, string) ExportExceldata(int year, int week) { // 如果年份为空(小于等于0),使用当天的年份 if (year <= 0) { year = DateTime.Now.Year; } //1.0 读取表数据 var list = Queryable().Where(it => it.Year == year && it.Week == week).ToList(); //2.0 保存为excel IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment)); string sFileName = $"{year}年{week}周计划-{DateTime.Now:MM-dd-HHmmss}.xlsx"; string fullPath = Path.Combine(webHostEnvironment.WebRootPath, "export", sFileName); Directory.CreateDirectory(Path.GetDirectoryName(fullPath)); var Sheet1 = new { year = year, week = week, title = $"{year}年车镜实业涂装事业{week}周生产滚动表", workplan = list }; string templatePath = Path.Combine(webHostEnvironment.WebRootPath, "ImportTemplate", "周计划标准模板1.xlsx"); MiniExcel.SaveAsByTemplate(fullPath, templatePath, Sheet1); // MiniExcel.SaveAs(fullPath, list); //3.0 返回路径和文件名 return (sFileName, fullPath); } public List GetWorkorderListByPlanId(string id) { return Context.Queryable().Where(it => it.FkProPlanId == id).OrderBy("priority desc ").ToList(); } public List GetWorkorderListById(string id) { return Context.Queryable().Where(it => it.Id == id).ToList(); } public int AddWorkorder(ProWorkorder proWorkorder) { return Context.Insertable(proWorkorder).ExecuteCommand(); } public int UpdateWorkorder(ProWorkorder proWorkorder) { return Context.Updateable(proWorkorder).ExecuteCommand(); } public int DeleteWorkorder(string id) { return Context.Deleteable().In(id).ExecuteCommand(); } public WorkplanSummaryDto GetWeekSummary(int year, int week) { // 如果年份为空(小于等于0),使用当天的年份 if (year <= 0) { year = DateTime.Now.Year; } return Context.Queryable().Where(it => it.Year == year && it.Week == week) .GroupBy(it => new { it.Week }) .Select(it => new WorkplanSummaryDto { requireNum = SqlFunc.AggregateSum(it.RequireNum), requireHanger = SqlFunc.AggregateSum(it.RequireHanger), turnnum = SqlFunc.AggregateSum(it.TurnNumber), productiontime = SqlFunc.AggregateSum(it.ProductTime), }) .First(); } public int DeleteAllWorkPlan(int year, int week) { // 如果年份为空(小于等于0),使用当天的年份 if (year <= 0) { year = DateTime.Now.Year; } return Context.Deleteable().Where(it => it.Year == year && it.Week == week).ExecuteCommand(); } public int CheckWorkPlan(ProWorklplan_v2 proWorkplan) { try { if (string.IsNullOrEmpty(proWorkplan.Partnumber)) { return 0; } WmMaterial material = Context.Queryable() .Where(it => it.Partnumber == proWorkplan.Partnumber) .Where(it => it.Status == 1) .First(); // 物料号不存在 if (material == null) { return 1; } // 规格与颜色异常 if (material.Specification != proWorkplan.Specification || material.Color != proWorkplan.ColorCode) { return 2; } return 0; } catch (Exception ex) { throw new Exception(ex.Message); } } // 修改 public int UpdateWorkPlan(ProWorklplan_v2 proWorkplan) { return Context.Updateable() .SetColumns(it => new ProWorklplan_v2() { BlankNum = proWorkplan.BlankNum, Partnumber = proWorkplan.Partnumber, ProductName = proWorkplan.ProductName, Specification = proWorkplan.Specification, ColorCode = proWorkplan.ColorCode, RequireNum = proWorkplan.RequireNum, EveryHangerNum = proWorkplan.EveryHangerNum, ProductionBeat = proWorkplan.ProductionBeat, AllHangerNum = proWorkplan.AllHangerNum, TurnNumber = proWorkplan.TurnNumber, ProductTime = proWorkplan.ProductTime, RequireHanger = proWorkplan.RequireHanger, }) .Where(it => it.Id == proWorkplan.Id) .ExecuteCommand(); } public int DeleteWorkPlan(string id) { return Context.Deleteable().In(id).ExecuteCommand(); } /// /// 获取指定日期所在的周数(不依赖Globalization) /// private int GetWeekNumber(DateTime date) { // 每年1月1日所在的周可能属于上一年的最后一周 // 这里简化处理,假设每年1月1日所在的周为第1周 DateTime startOfYear = new DateTime(date.Year, 1, 1); // 计算与1月1日的天数差 int daysDiff = (date - startOfYear).Days; // 计算1月1日是星期几 int firstDayOfWeek = (int)startOfYear.DayOfWeek; if (firstDayOfWeek == 0) firstDayOfWeek = 7; // 将Sunday(0)转为7 // 调整到周一为一周的开始 int adjustedDays = daysDiff + (8 - firstDayOfWeek); // 计算周数 int weekNumber = adjustedDays / 7; // 处理特殊情况:1月1日可能属于上一年的最后一周 if (weekNumber == 0) { // 获取上一年的最后一天 DateTime lastDayOfPrevYear = startOfYear.AddDays(-1); // 计算上一年最后一天所在的周数 return GetWeekNumber(lastDayOfPrevYear); } return weekNumber; } /// /// 获取指定年份和周数的周一日期(不依赖Globalization) /// private DateTime GetMondayOfWeek(int year, int week) { // 获取该年的第一天 DateTime firstDayOfYear = new DateTime(year, 1, 1); // 计算1月1日是星期几 int firstDayOfWeek = (int)firstDayOfYear.DayOfWeek; if (firstDayOfWeek == 0) firstDayOfWeek = 7; // 将Sunday(0)转为7 // 计算第一周的周一 DateTime firstMonday = firstDayOfYear.AddDays(8 - firstDayOfWeek - 7); // 如果第一周的周一在上一年,则第一周的周一为本年的1月1日之后的第一个周一 if (firstMonday.Year < year) { firstMonday = firstMonday.AddDays(7); } // 计算目标周的周一 DateTime targetMonday = firstMonday.AddDays((week - 1) * 7); return targetMonday; } /// /// 获取生产计划id /// /// private int Getworkplanid_max(string timeStr) { ProWorklplan_v2 max_workplan = Context.Queryable() .Where(it => it.Id.StartsWith("MP" + timeStr)) .OrderBy(it => it.Id, OrderByType.Desc) .First(); if (max_workplan != null && !string.IsNullOrEmpty(max_workplan.Id)) { int num = Convert.ToInt32(max_workplan.Id.Substring(2 + timeStr.Length)) + 1; return num; } else { return 1; } } } }