diff --git a/Tiobon.Core.Common/Helper/DateTimeHelper.cs b/Tiobon.Core.Common/Helper/DateTimeHelper.cs index d9208dca..895ac314 100644 --- a/Tiobon.Core.Common/Helper/DateTimeHelper.cs +++ b/Tiobon.Core.Common/Helper/DateTimeHelper.cs @@ -197,6 +197,19 @@ public class DateTimeHelper return dateTime.ToString(@"yyyy\/MM\/dd HH:mm:ss"); } /// + /// 格式化DateTime类型为字符串类型,精确到秒,如:20080101180920 + /// + /// + /// + public static string ConvertToSecondString1(DateTime dateTime) + { + if (string.IsNullOrEmpty(Convert.ToString(dateTime))) + { + return ""; + } + return dateTime.ToString(@"yyyyMMddHHmmss"); + } + /// /// 格式化object类型为字符串类型,精确到秒,如:2008/01/01 18:09:20 /// /// diff --git a/Tiobon.Core.Model/View/Ghre/Ghre_StudyRecord.Dto.View.cs b/Tiobon.Core.Model/View/Ghre/Ghre_StudyRecord.Dto.View.cs index cfa7f6c5..1cabd8f4 100644 --- a/Tiobon.Core.Model/View/Ghre/Ghre_StudyRecord.Dto.View.cs +++ b/Tiobon.Core.Model/View/Ghre/Ghre_StudyRecord.Dto.View.cs @@ -147,4 +147,6 @@ public class Ghre_StudyRecordDto : Ghre_StudyRecord /// 是否合格 /// public string IsPass { get; set; } + + public int UpdateYN { get; set; } = 0; } diff --git a/Tiobon.Core.Services/BASE/BaseServices.cs b/Tiobon.Core.Services/BASE/BaseServices.cs index 45d71c1b..72abf90b 100644 --- a/Tiobon.Core.Services/BASE/BaseServices.cs +++ b/Tiobon.Core.Services/BASE/BaseServices.cs @@ -998,7 +998,7 @@ public class BaseServices : IBaseServ //Type entityType = typeof(TEntity); //var fileName = entityType.GetEntityTableName() + ".xlsx"; //var result = ServiceResult.OprateSuccess(fileName, physicsPath + path + fileName); - var result = ServiceResult.OprateSuccess($"{MenuName}.xlsx", path); + var result = ServiceResult.OprateSuccess($"{MenuName}_{DateTimeHelper.ConvertToSecondString1(DateTime.Now)}.xlsx", path); return result; } diff --git a/Tiobon.Core.Services/Ghre/Ghre_QuestionServices.cs b/Tiobon.Core.Services/Ghre/Ghre_QuestionServices.cs index 8a0356ac..db0e5aea 100644 --- a/Tiobon.Core.Services/Ghre/Ghre_QuestionServices.cs +++ b/Tiobon.Core.Services/Ghre/Ghre_QuestionServices.cs @@ -1184,7 +1184,7 @@ public class Ghre_QuestionServices : BaseServices.OprateSuccess("题库.xlsx", physicsPath1); + var result = ServiceResult.OprateSuccess("题库_" + DateTimeHelper.ConvertToSecondString1(DateTime.Now) + ".xlsx", physicsPath1); return result; } diff --git a/Tiobon.Core.Services/Ghre/Ghre_StudyRecordServices.cs b/Tiobon.Core.Services/Ghre/Ghre_StudyRecordServices.cs index 4bba2dcd..1945696d 100644 --- a/Tiobon.Core.Services/Ghre/Ghre_StudyRecordServices.cs +++ b/Tiobon.Core.Services/Ghre/Ghre_StudyRecordServices.cs @@ -11,6 +11,14 @@ using Newtonsoft.Json; using Tiobon.Core.Common.Helper; using SqlSugar; using static Tiobon.Core.Model.Consts; +using NPOI.SS.UserModel; +using static Tiobon.Core.DataAccess.ReportHelper; +using Tiobon.Core.Common.DB.Dapper.Extensions; +using NPOI.HSSF.UserModel; +using NPOI.SS.Util; +using NPOI.XSSF.UserModel; +using Microsoft.AspNetCore.Http; +using System.Data; namespace Tiobon.Core.Services; @@ -20,11 +28,15 @@ namespace Tiobon.Core.Services; public class Ghre_StudyRecordServices : BaseServices, IGhre_StudyRecordServices { private readonly IBaseRepository _dal; - public Ghre_StudyRecordServices(ICaching caching, IBaseRepository dal) + private IGhre_CourseServices _ghre_CourseServices; + public Ghre_StudyRecordServices(ICaching caching, + IGhre_CourseServices ghre_CourseServices, + IBaseRepository dal) { this._dal = dal; base.BaseDal = dal; base._caching = caching; + _ghre_CourseServices = ghre_CourseServices; } public override async Task> QueryFilterPage(QueryBody filter, string condition, bool? IsEnable = true) { @@ -94,6 +106,9 @@ public class Ghre_StudyRecordServices : BaseServices(filter.pageNum, total, filter.pageSize, entitys); @@ -105,7 +120,6 @@ public class Ghre_StudyRecordServices : BaseServices> ExportStaffExcel(QueryExport body) { QueryBody filter = new QueryBody(); @@ -261,6 +275,409 @@ public class Ghre_StudyRecordServices : BaseServices> DownloadExcel(string menuName) + { + var physicsPath = $"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}wwwroot"; + var path = $"{$"{Path.DirectorySeparatorChar}files{Path.DirectorySeparatorChar}ExcelTemplate{Path.DirectorySeparatorChar}"}"; + if (!Directory.Exists(physicsPath + path)) + Directory.CreateDirectory(physicsPath + path); + + Type entityType = typeof(Ghre_StudyRecord); + var fileName = entityType.GetEntityTableName() + ".xlsx"; + //physicsPath = physicsPath + path + fileName; + + IWorkbook hssfworkbook; + ISheet sheet; + using (FileStream file = new FileStream(physicsPath + path + fileName, FileMode.Open, FileAccess.Read)) + { + //hssfworkbook = new HSSFWorkbook(file); + //hssfworkbook = new XSSFWorkbook(file); + hssfworkbook = WorkbookFactory.Create(file); + } + ISheet sheet2 = hssfworkbook.CreateSheet("下拉数据"); + + var newFileName = Guid.NewGuid() + ".xlsx"; + int listColIndex = 0; + string sql = @"select 'Course' field, Id id, CourseNo no, CourseName name from Ghre_Course where IsEnable=1 and Status='Released'"; + var dataSourceLists = await Db.Ado.SqlQueryAsync(sql); + if (dataSourceLists.Any()) + { + var types = new List + { + "学习记录" + }; + + types.ForEach(sheetName => + { + int sheetIndex = hssfworkbook.GetSheetIndex(sheetName); + if (sheetIndex >= 0) + { + sheet = hssfworkbook.GetSheetAt(sheetIndex); + + SetCellDropdownList(sheet, 0, 0, dataSourceLists.Select(x => x.name).ToArray()); + } + + }); + MemoryStream ms; + using (ms = new MemoryStream()) + { + hssfworkbook.Write(ms); + ms.Flush(); + hssfworkbook.Dispose(); + //ms.Position = 0; + //return ms; + } + using (FileStream fs = new FileStream(physicsPath + path + newFileName, FileMode.Create, FileAccess.Write)) + { + byte[] data = ms.ToArray(); + fs.Write(data, 0, data.Length); + fs.Flush(); + } + + } + + var physicsPath1 = physicsPath + path + fileName; + if (dataSourceLists.Any()) + physicsPath1 = physicsPath + path + newFileName; + var result = ServiceResult.OprateSuccess("学习记录_" + DateTimeHelper.ConvertToSecondString1(DateTime.Now) + ".xlsx", physicsPath1); + return result; + } + + #region Excel导入 + public override async Task> ImportExcel(IFormFile file) + { + var data = new ExcelData(); + long id = SnowFlakeSingle.instance.getID(); + var physicsPath = $"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}wwwroot"; + var path = $"{$"{Path.DirectorySeparatorChar}files{Path.DirectorySeparatorChar}import{Path.DirectorySeparatorChar}{id}{Path.DirectorySeparatorChar}"}"; + if (!Directory.Exists(physicsPath + path)) + Directory.CreateDirectory(physicsPath + path); + + var filepath = physicsPath + path + file.FileName; + using (var stream = File.Create(filepath)) + { + await file.CopyToAsync(stream); + } + string extension = Path.GetExtension(filepath); + + bool isExistError = false; + var id1 = SnowFlakeSingle.instance.getID(); + string errorFileName = path + SnowFlakeSingle.instance.getID() + extension; + //types.ForEach(async x => + //{ + + // string questionType = ConvertQuestionType1(x); + // DataTable dt = NPOIHelper.ImportExcel(filepath, x); + + // NPOIHelper.ExportExcel(dt, null, x, path + id1 + extension); + //}); + DataTable dt = NPOIHelper.ImportExcel(filepath, "学习记录"); + if (dt.Columns["Comments"] == null) + dt.Columns.Add("Comments", typeof(string)); + + for (int i = 0; i < dt.Rows.Count; i++) + { + var comments = new List(); + + if (!dt.Columns.Contains("课程(必填)")) + { + comments.Add("未查询到【课程(必填)】列!"); + data.ErrorCount++; + dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); + isExistError = true; + continue; + } + if (!dt.Columns.Contains("课程场景")) + { + comments.Add("未查询到【课程场景】列!"); + data.ErrorCount++; + dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); + isExistError = true; + continue; + } + if (!dt.Columns.Contains("员工(必填)")) + { + comments.Add("未查询到【员工(必填)】列!"); + data.ErrorCount++; + dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); + isExistError = true; + continue; + } + if (!dt.Columns.Contains("考试日期(必填)")) + { + comments.Add("未查询到【考试日期(必填)】列!"); + data.ErrorCount++; + dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); + isExistError = true; + continue; + } + if (!dt.Columns.Contains("学习开始时间")) + { + comments.Add("未查询到【学习开始时间】列!"); + data.ErrorCount++; + dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); + isExistError = true; + continue; + } + if (!dt.Columns.Contains("学习结束时间")) + { + comments.Add("未查询到【学习结束时间】列!"); + data.ErrorCount++; + dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); + isExistError = true; + continue; + } + if (!dt.Columns.Contains("考试分数(必填)")) + { + comments.Add("未查询到【考试分数(必填)】列!"); + data.ErrorCount++; + dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); + isExistError = true; + continue; + } + if (!dt.Columns.Contains("调整分(必填)")) + { + comments.Add("未查询到【调整分(必填)】列!"); + data.ErrorCount++; + dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); + isExistError = true; + continue; + } + if (!dt.Columns.Contains("是否合格(必填)")) + { + comments.Add("未查询到【是否合格(必填)】列!"); + data.ErrorCount++; + dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); + isExistError = true; + continue; + } + if (!dt.Columns.Contains("备注")) + { + comments.Add("未查询到【备注】列!"); + data.ErrorCount++; + dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); + isExistError = true; + continue; + } + + var courseName = dt.Rows[i]["课程(必填)"].ToString(); + var staffName = dt.Rows[i]["员工(必填)"].ToString(); + var courseScene = dt.Rows[i]["课程场景"].ToString(); + var examDate = dt.Rows[i]["考试日期(必填)"].ToString(); + var courseBeginTime = dt.Rows[i]["学习开始时间"].ToString(); + var courseEndTime = dt.Rows[i]["学习结束时间"].ToString(); + var score = dt.Rows[i]["考试分数(必填)"].ToString(); + var adjustScore = dt.Rows[i]["调整分(必填)"].ToString(); + var isPass = dt.Rows[i]["是否合格(必填)"].ToString(); + var remarkSz = dt.Rows[i]["备注"].ToString(); + + if (courseName.IsNullOrEmpty()) + { + dt.Rows[i]["Comments"] = "课程为必填项!"; + data.ErrorCount++; + isExistError = true; + continue; + } + + if (staffName.IsNullOrEmpty()) + { + dt.Rows[i]["Comments"] = "员工为必填项!"; + data.ErrorCount++; + isExistError = true; + continue; + } + + if (examDate.IsNullOrEmpty()) + { + dt.Rows[i]["Comments"] = "考试日期为必填项!"; + data.ErrorCount++; + isExistError = true; + continue; + } + if (score.IsNullOrEmpty()) + { + dt.Rows[i]["Comments"] = "考试分数为必填项!"; + data.ErrorCount++; + isExistError = true; + continue; + } + if (isPass.IsNullOrEmpty()) + { + dt.Rows[i]["Comments"] = "是否合格为必填项!"; + data.ErrorCount++; + isExistError = true; + continue; + } + + var staff = await Db.Queryable().Where(x => x.StaffEname == staffName || x.StaffName == staffName || x.PinYinName == staffName).FirstAsync(); + + if (staff.IsNullOrEmpty()) + { + dt.Rows[i]["Comments"] = "该员工在系统中不存在存在!"; + data.ErrorCount++; + isExistError = true; + continue; + } + var course = await _ghre_CourseServices.QuerySingleDto(x => x.CourseName == courseName); + if (course.IsNullOrEmpty()) + { + dt.Rows[i]["Comments"] = "该课程在系统中不存在存在!"; + data.ErrorCount++; + isExistError = true; + continue; + } + + var scene = await Db.Queryable().Where(x => x.CourseName == courseScene).FirstAsync(); + + DateTime? dtExamDate = null; + try + { + dtExamDate = Convert.ToDateTime(examDate); + } + catch (Exception) + { + dt.Rows[i]["Comments"] = "无效的考试日期!"; + data.ErrorCount++; + isExistError = true; + continue; + } + + DateTime? dtCourseBeginTime = null; + if (dtCourseBeginTime.IsNotEmptyOrNull()) + { + try + { + dtCourseBeginTime = Convert.ToDateTime(dtCourseBeginTime); + } + catch (Exception) + { + dt.Rows[i]["Comments"] = "无效的学习开始时间!"; + data.ErrorCount++; + isExistError = true; + continue; + } + } + + DateTime? dtCourseEndTime = null; + if (dtCourseEndTime.IsNotEmptyOrNull()) + { + try + { + dtCourseEndTime = Convert.ToDateTime(dtCourseEndTime); + } + catch (Exception) + { + dt.Rows[i]["Comments"] = "无效的学习结束时间!"; + data.ErrorCount++; + isExistError = true; + continue; + } + } + + decimal? Score = null; + if (score.IsNotEmptyOrNull()) + { + try + { + Score = Convert.ToDecimal(score); + } + catch (Exception) + { + dt.Rows[i]["Comments"] = "无效的考试分数!"; + data.ErrorCount++; + isExistError = true; + continue; + } + } + + decimal? AdjustScore = null; + if (adjustScore.IsNotEmptyOrNull()) + { + try + { + AdjustScore = Convert.ToDecimal(adjustScore); + } + catch (Exception) + { + dt.Rows[i]["Comments"] = "无效的学习结束时间!"; + data.ErrorCount++; + isExistError = true; + continue; + } + } + + try + { + var insert = new InsertGhre_StudyRecordInput() + { + CourseId = course?.Id, + StaffId = staff.StaffID, + CourseSceneId = scene?.Id, + Score = Score, + AdjustScore = AdjustScore ?? 0, + IsPass = isPass == "是" ? true : false, + ExamDate = dtExamDate, + CourseBeginTime = dtCourseBeginTime, + CourseEndTime = dtCourseEndTime, + RemarkSz = remarkSz, + }; + await Add(insert); + } + catch (Exception E) + { + dt.Rows[i]["Comments"] = E.Message; + data.ErrorCount++; + isExistError = true; + continue; + } + + + } + + if (isExistError) + { + NPOIHelper.ExportExcel(dt, null, "学习记录", physicsPath + errorFileName); + data.filePath = errorFileName; + } + + return ServiceResult.OprateSuccess("导入成功!", data); + } + + #endregion + + public static void SetCellDropdownList(ISheet sheet, int firstcol, int lastcol, string[] vals) + { + + //設置生成下拉框的行和列 + var cellRegions = new CellRangeAddressList(1, 65535, firstcol, lastcol); + IDataValidation validation = null; + + if (sheet.GetType().Name.Contains("XSSF")) // .xlsx + { + XSSFDataValidationHelper helper = new XSSFDataValidationHelper((XSSFSheet)sheet);//获得一个数据验证Helper + //IDataValidation + validation = helper.CreateValidation( + helper.CreateExplicitListConstraint(vals), cellRegions);//创建约束 + } + else // HSSF .xls + { + //設置 下拉框內容 + DVConstraint constraint = DVConstraint.CreateExplicitListConstraint(vals); + validation = new HSSFDataValidation(cellRegions, constraint); + + + /*綁定下拉框和作用區域,並設置錯誤提示信息 + HSSFDataValidation dataValidate = new HSSFDataValidation(cellRegions, constraint); + dataValidate.CreateErrorBox("輸入不合法", "請輸入或選擇下拉列表中的值。"); + dataValidate.ShowPromptBox = true; +*/ + } + + validation.CreateErrorBox("输入不合法", "请输入或选择下拉列表中的值。"); + validation.ShowPromptBox = true; + + sheet.AddValidationData(validation); + } #region 获取ESS查询条件 public async Task> QueryESSSearchFields(QueryBody body) { @@ -788,4 +1205,5 @@ public class Ghre_StudyRecordServices : BaseServices