diff --git a/Learn.Archives.API/Controllers/Dto/ExamClassInfoDto.cs b/Learn.Archives.API/Controllers/Dto/ExamClassInfoDto.cs
index 9434ef5..8745436 100644
--- a/Learn.Archives.API/Controllers/Dto/ExamClassInfoDto.cs
+++ b/Learn.Archives.API/Controllers/Dto/ExamClassInfoDto.cs
@@ -2,7 +2,7 @@
namespace Learn.Archives.API.Controllers.Dto
{
- public class ImportDto
+ public class ImportExamDto
{
///
/// 导入文件
diff --git a/Learn.Archives.API/Controllers/Dto/SchoolBusinessDto.cs b/Learn.Archives.API/Controllers/Dto/SchoolBusinessDto.cs
new file mode 100644
index 0000000..d23e1da
--- /dev/null
+++ b/Learn.Archives.API/Controllers/Dto/SchoolBusinessDto.cs
@@ -0,0 +1,79 @@
+using MiniExcelLibs.Attributes;
+
+namespace Learn.Archives.API.Controllers.Dto
+{
+ public class SchoolBusinessDto
+ {
+ }
+ public class SchoolBusinessImportError : SchoolBusinessImport
+ {
+
+
+ [ExcelColumnName("错误信息")]
+ public string Error { get; set; }
+ }
+ public class SchoolBusinessImport
+ {
+
+ [ExcelColumnName("学校")]
+ public string School { get; set; }
+ [ExcelColumnName("年级")]
+ public string Grade { get; set; }
+ ///
+ /// 赴校人员
+ /// 多个,分割
+ ///
+ [ExcelColumnName("赴校人员")]
+ public string Users { get; set; }
+ [ExcelColumnName("赴校时间")]
+ public DateTime StartTime { get; set; }
+ [ExcelColumnName("开展会谈")]
+ public bool IsDiscussion { get; set; }
+
+ [ExcelColumnName("开展会谈情况")]
+ public string Discussion { get; set; }
+
+ [ExcelColumnName("开展班会")]
+ public bool IsClassMeeting { get; set; }
+ [ExcelColumnName("开展班会情况")]
+ public string ClassMeeting { get; set; }
+
+
+ //----------------------------问题列表
+ [ExcelColumnName("[问题]学校领导班子")]
+ public string Q学校领导班子 { get; set; }
+ [ExcelColumnName("[问题]双师课堂")]
+ public string Q双师课堂 { get; set; }
+ [ExcelColumnName("[问题]设备")]
+ public string Q设备 { get; set; }
+ [ExcelColumnName("[问题]学生")]
+ public string Q学生 { get; set; }
+ [ExcelColumnName("[问题]其他")]
+ public string Q其他 { get; set; }
+
+ //----------------------------解决办法
+ [ExcelColumnName("[解决]学校领导班子")]
+ public string P学校领导班子 { get; set; }
+ [ExcelColumnName("[解决]双师课堂")]
+ public string P双师课堂 { get; set; }
+ [ExcelColumnName("[解决]设备")]
+ public string P设备 { get; set; }
+ [ExcelColumnName("[解决]学生")]
+ public string P学生 { get; set; }
+ [ExcelColumnName("[解决]其他")]
+ public string P其他 { get; set; }
+
+
+ //----------------------------额外需求
+ [ExcelColumnName("需求/方案")]
+ public string Solution { get; set; }
+ [ExcelColumnName("沟通时间/执行记录")]
+ public string Record { get; set; }
+ [ExcelColumnName("完结记录")]
+ public string EndRecord { get; set; }
+ [ExcelColumnName("备注")]
+ public string Remark { get; set; }
+
+
+ }
+}
diff --git a/Learn.Archives.API/Controllers/ExamClassInfoController.cs b/Learn.Archives.API/Controllers/ExamClassInfoController.cs
index 3c5d3cf..30ae640 100644
--- a/Learn.Archives.API/Controllers/ExamClassInfoController.cs
+++ b/Learn.Archives.API/Controllers/ExamClassInfoController.cs
@@ -2,6 +2,7 @@
using Learn.Archives.API.Expand;
using Learn.Archives.Core.Common;
using Learn.Archives.Core.Model;
+using Learn.Archives.Core.Model.Dto;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
@@ -33,6 +34,7 @@ namespace Learn.Archives.API.Controllers
this.examService = examService;
this.schoolService = schoolService;
}
+
[NonAction]
private Dictionary? ImportExamInfoSubjectDic(ImportExamInfo info)
{
@@ -49,6 +51,7 @@ namespace Learn.Archives.API.Controllers
{ SubjectEnum.地理, info.地理},
};
}
+
///
/// 导入考试信息
///
@@ -56,7 +59,7 @@ namespace Learn.Archives.API.Controllers
///
[HttpPost, ResultIgnore]
[HttpLogEnable]
- public async Task Import(ImportDto dto)
+ public async Task Import(ImportExamDto dto)
{
var exam = await examService.GetByIdAsync(dto.eId);
@@ -164,6 +167,7 @@ namespace Learn.Archives.API.Controllers
PeopleCount = classUserArr.Count(),
MinScore = int.MaxValue,
EntryPersonId = userInfo.Id,
+ BaseSchoolScore = exam.BaseSchoolScore,
EntryPerson = userInfo.Name,
};
insertClassInfo.Add(eCInfo);
@@ -287,5 +291,29 @@ namespace Learn.Archives.API.Controllers
}
+ public override Task PageList([FromBody] QueryRequestBase model)
+ {
+ var c = model.Conditions.FirstOrDefault(s => s.FieldName == "Grade");
+ if (c != null)
+ {
+ var gInfo = GradeHelper.GetStudentGradeBaseByGrade(c.FieldValue);
+ if (gInfo != null)
+ {
+ model.Conditions = model.Conditions.Where(s => s != c).ToList();
+ model.Conditions.Add(new SqlSugar.ConditionalModel()
+ {
+ FieldName = "GradeLevel",
+ FieldValue = gInfo.GradeLevel,
+ });
+ model.Conditions.Add(new SqlSugar.ConditionalModel()
+ {
+ FieldName = "GradeYear",
+ FieldValue = gInfo.GradeYear.ToString(),
+ CSharpTypeName="int"
+ });
+ }
+ }
+ return base.PageList(model);
+ }
}
}
diff --git a/Learn.Archives.API/Controllers/SchoolBusinessController.cs b/Learn.Archives.API/Controllers/SchoolBusinessController.cs
index c4a0ff8..16dab34 100644
--- a/Learn.Archives.API/Controllers/SchoolBusinessController.cs
+++ b/Learn.Archives.API/Controllers/SchoolBusinessController.cs
@@ -3,25 +3,36 @@ using Learn.Archives.API.Expand;
using Learn.Archives.Core.Common;
using Learn.Archives.Core.Model;
using Learn.Archives.Core.Model.Dto;
+using Learn.Archives.Core.Model.Enum;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
+using MiniExcelLibs;
using SqlSugar;
+using Swashbuckle.AspNetCore.SwaggerGen;
using System.Diagnostics;
using System.Security.Claims;
+using System.Text.RegularExpressions;
using UserCenter.Model;
using UserCenter.Model.Common;
+using UserCenter.Model.Enum;
namespace Learn.Archives.API.Controllers
{
public class SchoolBusinessController : BackController
{
readonly Repository baseService;
- public SchoolBusinessController(Repository baseService) : base(baseService)
+ readonly Repository schoolService;
+ readonly Repository adminService;
+ readonly IHttpContextAccessor accessor;
+ public SchoolBusinessController(Repository baseService, Repository schoolService, IHttpContextAccessor accessor, Repository adminService) : base(baseService)
{
this.baseService = baseService;
+ this.schoolService = schoolService;
+ this.accessor = accessor;
+ this.adminService = adminService;
}
- public class QueryPageDto
+ public class QueryPageDto
{
///
/// 学校id
@@ -32,13 +43,13 @@ namespace Learn.Archives.API.Controllers
///
public string? Grade { get; set; }
///
- /// 赴校人员名称
+ /// 赴校人员ID
///
- public string? UserName { get; set; }
+ public long? UserId { get; set; }
///
/// 是否查询完结
///
- public bool SolutionEnd { get; set; }
+ public bool? SolutionEnd { get; set; }
public DateTime? StartTime { get; set; }
public DateTime? EndTime { get; set; }
@@ -57,7 +68,7 @@ namespace Learn.Archives.API.Controllers
{
if (model.SolutionRecord != null && model.SolutionRecord.SolutionEnd == true)
model.SolutionEnd = true;
- if (!string.IsNullOrEmpty(model._grade))
+ if (!string.IsNullOrEmpty(model._grade))
{
var g = GradeHelper.GetStudentGradeBaseByGrade(model._grade);
model.GradeLevel = g.GradeLevel;
@@ -71,19 +82,183 @@ namespace Learn.Archives.API.Controllers
///
///
[HttpPost]
- public async Task> QueryPageList(QueryPageDto dto)
+ public async Task> QueryPageList(QueryPageDto dto)
{
+
+ var uid = dto.UserId.ToString();
+ var gInfo = GradeHelper.GetStudentGradeBaseByGrade(dto.Grade);
RefAsync total = 0;
var resData = await baseService.AsQueryable()
.WhereIF(dto.SchoolId != 0, s => s.SchoolId == dto.SchoolId)
- .WhereIF(!string.IsNullOrEmpty(dto.Grade), s => s.Grade == dto.Grade)
- .WhereIF(dto.SolutionEnd, s => s.SolutionEnd == dto.SolutionEnd)
+ .WhereIF(gInfo != null, s => s.GradeLevel == gInfo.GradeLevel && s.GradeYear == gInfo.GradeYear)
+ .WhereIF(dto.SolutionEnd != null, s => s.SolutionEnd == dto.SolutionEnd)
.WhereIF(dto.StartTime != null, s => s.StartTime >= dto.StartTime)
.WhereIF(dto.EndTime != null, s => s.StartTime <= dto.EndTime)
- .WhereIF(!string.IsNullOrEmpty(dto.UserName), s => s.SchoolBusinessUser != null && SqlFunc.JsonLike(s.SchoolBusinessUser, dto.Grade))
- .OrderByDescending(s=>s.Id)
+ .WhereIF(uid != null, s => s.SchoolBusinessUser != null && SqlFunc.JsonLike(s.SchoolBusinessUser, uid))
+ .OrderByDescending(s => s.Id)
.ToPageListAsync(dto.PageIndex, dto.PageSize, total);
return new PageResult() { Data = resData, Total = total };
}
+
+
+
+ ///
+ /// 导入考试信息
+ ///
+ ///
+ ///
+ [HttpPost, ResultIgnore]
+ [HttpLogEnable]
+ public async Task Import(IFormFile? file)
+ {
+
+ var fl = file != null ? file : accessor.HttpContext?.Request.Form.Files[0];
+ if (fl == null) Oh.ModelError("传入无效的数据");
+ if (!Path.GetExtension(fl.FileName).Equals(".xlsx", StringComparison.OrdinalIgnoreCase))
+ Oh.ModelError("请选择导入文件为.xlsx的后缀名!");
+ //分析excel
+ IEnumerable dataList;
+ using var stream = new MemoryStream();
+ {
+ await fl.CopyToAsync(stream);
+ dataList = stream.Query()
+ .Where(s => !string.IsNullOrEmpty(s.School));
+ }
+ if (dataList == null || dataList.Count() == 0)
+ Oh.ModelError("导入失败:无有效数据");
+
+ //todo
+ //处理数据
+ var errorExcelInfo = new List();
+ var insertInfo = new List();
+ var db = schoolService.Context;
+ foreach (var imp in dataList)
+ {
+ var school = await schoolService.GetFirstAsync(s => s.Name == imp.School);
+ if (school == null)
+ {
+ imp.Error = $"导入失败:学校 [{imp.School}] 未找到!";
+ errorExcelInfo.Add(imp);
+ continue;
+ }
+ var gradeInfo = GradeHelper.GetStudentGradeBaseByGrade(imp.Grade);
+ if (gradeInfo == null)
+ {
+ imp.Error = $"导入失败:学校 [{imp.School}] 年级[{imp.Grade}]不符合规范!";
+ errorExcelInfo.Add(imp);
+ continue;
+ }
+ var adminNameArr = imp.Users.Split(",");
+ if (adminNameArr == null)
+ {
+ imp.Error = $"赴校人员未能识别";
+ errorExcelInfo.Add(imp);
+ continue;
+ }
+ var adminArr = await adminService.AsQueryable()
+ .Where(s => adminNameArr.Contains(s.Name))
+ .Select(s => s.Id).ToArrayAsync();
+ var qStr = new Dictionary()
+ {
+ {FeedbackQuestionTypeEnum.学校领导班子,(imp.Q学校领导班子,imp.P学校领导班子) },
+ {FeedbackQuestionTypeEnum.双师课堂,(imp.Q双师课堂,imp.P双师课堂) },
+ {FeedbackQuestionTypeEnum.设备,(imp.Q设备,imp.P设备) },
+ {FeedbackQuestionTypeEnum.学生,(imp.Q学生,imp.P学生) },
+ {FeedbackQuestionTypeEnum.其他,(imp.Q其他,imp.P其他) }
+ };
+ var resultQuestion = new List();
+ var regex = new Regex(@"(问题\d+):(.*?)(?=;|$)", RegexOptions.Singleline);
+ foreach (var kvp in qStr)
+ {
+ var questionType = kvp.Key;
+ var questions = kvp.Value.Questions;
+ var solutions = kvp.Value.Solutions;
+ // 解析问题
+ var questionMatches = regex.Matches(questions);
+ var solutionMatches = regex.Matches(solutions);
+ // 创建字典以便快速查找解决方案
+ var solutionDict = new Dictionary();
+ foreach (Match match in solutionMatches)
+ if (match.Groups.Count == 3)
+ solutionDict[match.Groups[1].Value] = match.Groups[2].Value;
+ // 创建DTO对象
+ foreach (Match match in questionMatches)
+ {
+ if (match.Groups.Count == 3)
+ {
+ var sort = match.Groups[1].Value;
+ var question = match.Groups[2].Value;
+
+ solutionDict.TryGetValue(sort, out var solution);
+
+ resultQuestion.Add(new FeedbackQuestionsDto
+ {
+ QuestionType = questionType,
+ Sort = sort,
+ Question = question,
+ Solution = solution,
+ EndTime = null // 根据需求设置解决时间
+ });
+ }
+ }
+ }
+ var feedbackQuestions = resultQuestion.ToArray();
+
+ //沟通时间/执行记录
+ var regex1 = new Regex(@"(.*?):(.*?)(?=;|$)", RegexOptions.Singleline);
+ var record = new List();
+ foreach (Match match in regex1.Matches(imp.Record))
+ {
+ record.Add(new RecordDto()
+ {
+ ExecutionTime = match.Groups[1].Value.ExtractDateTime(),
+ ExecutionRecords = match.Groups[2].Value,
+ });
+ }
+
+ var business = new SchoolBusiness()
+ {
+ SchoolId = school.Id,
+ SchoolName = school.Name,
+ GradeLevel = gradeInfo.GradeLevel,
+ GradeYear = gradeInfo.GradeYear,
+ ClassMeeting = imp.ClassMeeting,
+ Discussion = imp.Discussion,
+ SchoolBusinessUser = adminArr,
+ Remark = imp.Remark,
+ StartTime = imp.StartTime,
+ FeedbackQuestions = feedbackQuestions,
+ SolutionRecord = new SolutionRecordDto()
+ {
+ EndRecord = imp.EndRecord,
+ EndRecordTime = imp.EndRecord.ExtractDateTime(),
+ Solution = imp.Solution,
+ Record = record,
+ }
+ };
+
+
+ };
+ if (errorExcelInfo.Count != 0)
+ return File(errorExcelInfo.ExportExcel(), "application/ms-excel");
+
+ //写入数据库
+
+ return Ok();
+ }
+
+ ///
+ /// 下载导入成绩模板
+ ///
+ ///
+ [HttpGet, ResultIgnore, AllowAnonymous]
+ public IActionResult DwImportTemplate()
+ {
+ var resultList = new List() { new SchoolBusinessImport() { } };
+ return File(resultList.ExportExcel(), "application/ms-excel");
+ }
+
+
+
}
}
diff --git a/Learn.Archives.API/Program.cs b/Learn.Archives.API/Program.cs
index 605742e..0a8498b 100644
--- a/Learn.Archives.API/Program.cs
+++ b/Learn.Archives.API/Program.cs
@@ -9,7 +9,6 @@ using Learn.Archives.API.Expand;
using System.ComponentModel;
var builder = WebApplication.CreateBuilder(args);
-
// Add services to the container.
builder.Services.AddLogging(loggingBuilder =>
{
diff --git a/Learn.Archives.Core/Common/AppCommon.cs b/Learn.Archives.Core/Common/AppCommon.cs
index e572f79..20e821a 100644
--- a/Learn.Archives.Core/Common/AppCommon.cs
+++ b/Learn.Archives.Core/Common/AppCommon.cs
@@ -102,7 +102,35 @@ namespace Learn.Archives.Core.Common
return Convert.ToHexString(hashBytes).ToUpper(); // 或者保留大写
}
}
+ public static DateTime? ExtractDateTime(this string input)
+ {
+ if (string.IsNullOrWhiteSpace(input))
+ return null;
+ // 定义日期模式的正则表达式
+ string pattern = @"(\d{4})[年./\s-](\d{1,2})[月./\s-](\d{1,2})日?";
+ var match = Regex.Match(input, pattern);
+
+ if (match.Success && match.Groups.Count == 4)
+ {
+ if (int.TryParse(match.Groups[1].Value, out int year) &&
+ int.TryParse(match.Groups[2].Value, out int month) &&
+ int.TryParse(match.Groups[3].Value, out int day))
+ {
+ try
+ {
+ return new DateTime(year, month, day);
+ }
+ catch (ArgumentOutOfRangeException)
+ {
+ // 处理无效日期(如2月30日)
+ return null;
+ }
+ }
+ }
+
+ return null;
+ }
///
/// 对象转化为JSON字符串
///
diff --git a/Learn.Archives.Core/Model/Dto/SchoolBusinessDto.cs b/Learn.Archives.Core/Model/Dto/SchoolBusinessDto.cs
index cde4b35..764c0c6 100644
--- a/Learn.Archives.Core/Model/Dto/SchoolBusinessDto.cs
+++ b/Learn.Archives.Core/Model/Dto/SchoolBusinessDto.cs
@@ -47,7 +47,7 @@ namespace Learn.Archives.Core.Model.Dto
///
/// 执行时间
///
- public DateTime ExecutionTime { get; set; }
+ public DateTime? ExecutionTime { get; set; }
}
diff --git a/Learn.Archives.Core/Model/ExamClassInfo.cs b/Learn.Archives.Core/Model/ExamClassInfo.cs
index 02a60ed..d687b31 100644
--- a/Learn.Archives.Core/Model/ExamClassInfo.cs
+++ b/Learn.Archives.Core/Model/ExamClassInfo.cs
@@ -101,6 +101,11 @@ namespace Learn.Archives.Core.Model
///
public decimal AverageRank1 { get; set; }
+ ///
+ /// 资源校平均分
+ ///
+ public decimal BaseSchoolScore { get; set; }
+
///
/// 录入人Id
diff --git a/Learn.Archives.Core/Model/SchoolBusiness.cs b/Learn.Archives.Core/Model/SchoolBusiness.cs
index bddd5b2..e4f3d05 100644
--- a/Learn.Archives.Core/Model/SchoolBusiness.cs
+++ b/Learn.Archives.Core/Model/SchoolBusiness.cs
@@ -48,7 +48,7 @@ namespace Learn.Archives.Core.Model
/// 赴校人员 逗号分隔
///
[SugarColumn(IsNullable = true, IsJson = true)]
- public string[]? SchoolBusinessUser { get; set; }
+ public long[]? SchoolBusinessUser { get; set; }
///
/// 赴校时间
///
@@ -56,7 +56,7 @@ namespace Learn.Archives.Core.Model
///
/// 赴校备注
///
- [SugarColumn(IsNullable = true)]
+ [SugarColumn(IsNullable = true, Length =1000)]
public string? Remark { get; set; }
///