using Aliyun.OSS;
using Dm;
using Learn.Archives.API.Controllers.Dto;
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 Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using SqlSugar;
using System.Diagnostics;
using System.Linq.Expressions;
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 StudentController : BackController
{
private readonly IHttpContextAccessor _httpContextAccessor;
readonly Repository baseService;
readonly Repository positionService;
readonly UserCenterService _userCenterService;
readonly LiveUserInfo userInfo;
public StudentController(Repository baseService, LiveUserInfo userInfo, IHttpContextAccessor httpContextAccessor, UserCenterService userCenterService, Repository positionService) : base(baseService)
{
this.baseService = baseService;
this.userInfo = userInfo;
_httpContextAccessor = httpContextAccessor;
_userCenterService = userCenterService;
this.positionService = positionService;
}
[NonAction]
public override Task PageList([FromBody] QueryRequestBase model)
{
return base.PageList(model);
}
///
/// 用户信息
///
///
[HttpGet]
public async Task Info(long uid)
{
if (uid == 0)
Oh.ModelError("无效数据");
return await baseService.AsQueryable().FirstAsync(s => s.UserCenterId == uid);
}
///
/// 获取职位id
/// 调用流程 用户中心->档案系统
///
///
[HttpPost]
public async Task PosititonIds(PositionIdsReq[] data)
{
if (data == null || data.Count()==0)
Oh.ModelError("无效数据");
var query = new Expressionable();
foreach (var pos in data)
{
query = query.Or(q =>
q.SchoolId == pos.SchoolId &&
q.PositionType == pos.PositionType &&
q.GradeLevel == pos.GradeLevel &&
q.GraduationYear == pos.GraduationYear &&
q.PositionLevel == pos.PositionLevel
&&
(
// PositionLevel == 3:只匹配前三个字段
(pos.PositionLevel == 3) ||
// PositionLevel == 4:再加上 ClassId
(pos.PositionLevel == 4 && q.ClassId == pos.ClassId) ||
// PositionLevel == 5:再加上 ClassId + SubjectId
(pos.PositionLevel == 5 && q.ClassId == pos.ClassId && q.SubjectId == pos.SubjectId)
)
);
}
return await positionService.AsQueryable()
.Where(query.ToExpression())
.Select(p => p.Id).ToArrayAsync();
}
///
/// 修改用户信息
/// 调用流程 用户中心->档案系统
///
///
[HttpPost]
public async Task EditInfo(Student e)
{
if (e == null || e.UserCenterId == 0)
Oh.ModelError("无效数据");
var has = await baseService.AsQueryable().FirstAsync(s => s.UserCenterId == e.UserCenterId);
e.Status = e.Status ?? UserStatusEnum.未录入;
if (has == null)
await baseService.InsertAsync(e);
else
{
e.Id = has.Id;
e.UserCenterId = has.UserCenterId;
await baseService.UpdateAsync(e);
}
return e.Id;
}
///
/// 获取学生列表
///
///
[HttpPost]
public new async Task> PageList(object data)
{
var apiRes =await _userCenterService.CallAPI_GetPageUserList(_httpContextAccessor.HttpContext);
var res= new PageResult() { Data = new List() };
if (apiRes == null|| apiRes.Data.Count == 0) return res;
res.Total = apiRes.Total;
var uids = apiRes.Data.Select(s => s.Id).ToArray();
var exData = await baseService.AsQueryable()
.Where(s => uids.Contains(s.UserCenterId))
.ToArrayAsync();
var exDataDic = exData.GroupBy(s => s.UserCenterId).ToDictionary(s => s.Key);
foreach (var item in apiRes.Data.Select(s => s.Adapt()))
{
res.Data.Add(item);
if (!exDataDic.ContainsKey(item.Id)) continue;
var ex = exDataDic[item.Id].First();
item.Status = ex.Status??UserStatusEnum.未录入;
item.ExitTime = ex.ExitTime==null? string.Empty : ex.ExitTime?.ToString("yyyy-MM-dd");
item.JoinTime = ex.JoinTime == null ? string.Empty : ex.JoinTime?.ToString("yyyy-MM-dd");
item.AmountRelief = ex.AmountRelief;
item.ReliefApplication = ex.ReliefApplication;
item.StudentType = ex.StudentType.ToString();
item.Remark = ex.Remark;
item.ReliefType = ex?.ReliefType?.ToString();
item.ReliefSubTime = ex.ReliefSubTime?.ToString("yyyy-MM-dd") ?? string.Empty;
}
return res;
}
///
/// 导入老师信息
///
///
[HttpPost, ResultIgnore]
[HttpLogEnable]
public async Task ImportTeacher(IFormFile? file)
{
var fl = file != null ? file : _httpContextAccessor.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("导入失败:无有效数据");
var insertInfo = new List();
var impError = new List();
var userCenterImp = new List();
foreach (var s in dataList)
{
var ginfo = GradeHelper.GetStudentGradeBaseByGrade(s.Grade);
var gStr = GradeHelper.GetGrade(ginfo.GradeLevel, ginfo.GradeYear);
if (gStr.ToEnum() == null) //无效的传入年级
{
s.ErrorMsg = "无效的年级 例如[初一/初2028] [年 级范围应当是当前有效的就读年级]";
impError.Add(s);
continue;
}
//基础信息校验
if (string.IsNullOrEmpty(s.UserType) ||
string.IsNullOrEmpty(s.School)||
(s.UserType != "年级主任" && string.IsNullOrEmpty(s.Class)) ||
string.IsNullOrEmpty(s.Phone)||
string.IsNullOrEmpty(s.RealName)
)
{
s.ErrorMsg = "基础信息未能检查通过/请检查 导入行中 是否缺少了[任职信息类型/学校/班级/年级/名称//手机号]";
impError.Add(s);
continue;
}
//无效的任教学科
if (!string.IsNullOrEmpty(s.Subject) && s.Subject.ToEnum()==null)
{
s.ErrorMsg = "无效的任教学科";
impError.Add(s);
continue;
}
userCenterImp.Add(new UserExcelExportData()
{
UserType = s.UserType,
Account = s.Phone.ToString(),
Subject = s.Subject,
ExamNo = s.ExamNo,
School = s.School,
Grade = gStr,
Class = s.Class,
Phone = s.Phone,
RealName = s.RealName,
Stages = s.Grade.Contains("初") ? StudentStagesEnum.初中.ToString() : StudentStagesEnum.高中.ToString()
});
}
//如果有错误数据则返回excel
if (impError.Count() != 0)
return File(impError.ExportExcel(), "application/ms-excel", $"导入错误的老师{DateTime.Now.ToString("MMddHHmm")}.xlsx");
//调用 用户中心 导入接口
var importRes = await _userCenterService.CallAPI_ImportJsonData(_httpContextAccessor.HttpContext, userCenterImp);
//处理数据
var errorExcelInfo = importRes.ErrorExcelExport.Select(s => s.Adapt());
//如果有错误数据则返回excel
if (errorExcelInfo.Count() != 0)
return File(errorExcelInfo.ExportExcel(), "application/ms-excel", $"导入错误的老师{DateTime.Now.ToString("MMddHHmm")}.xlsx");
return Ok();
}
///
/// 导入学生信息
///
///
[HttpPost, ResultIgnore]
[HttpLogEnable]
public async Task Import(IFormFile? file)
{
var fl = file != null ? file : _httpContextAccessor.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("导入失败:无有效数据");
var insertInfo = new List();
var impError = new List();
var userCenterImp = new List();
foreach (var s in dataList)
{
var ginfo = GradeHelper.GetStudentGradeBaseByGrade(s.Grade);
if(ginfo is null)
{
s.ErrorMsg = "未能识别的[初一/初2028] [年级范围应当是当前有效的就读年级]";
impError.Add(s);
continue;
}
var gStr = GradeHelper.GetGrade(ginfo.GradeLevel, ginfo.GradeYear);
if (gStr.ToEnum() == null) //无效的传入年级
{
s.ErrorMsg = "无效的年级 例如[初一/初2028] [年级范围应当是当前有效的就读年级]";
impError.Add(s);
continue;
}
insertInfo.Add(new Student()
{
AmountRelief = decimal.TryParse(s.AmountRelief,out decimal v)?v:0,
ExitTime = s.ExitTime,
Remark = s.Remark,
JoinTime = s.JoinTime,
Status = s.Status.ToEnum()??default,
UserCenterId = s.Id,
ReliefApplication=s.ReliefApplication?.Contains("已申请")??false,
ReliefSubTime = s.ReliefSubTime,
ReliefType =s.ReliefType,
StudentType =s.StudentType.ToEnum(),
});
var addExcelUser = new UserExcelExportData()
{
UserType = "学生",
Account = s.Id.ToString(),
School = s.School,
Grade = gStr,
Class = s.Class,
ExamNo = s.Id.ToString(),
Phone = s.Phone,
RealName = s.RealName,
Stages = s.Grade.Contains("初") ? StudentStagesEnum.初中.ToString() : StudentStagesEnum.高中.ToString()
};
userCenterImp.Add(addExcelUser);
if (!string.IsNullOrWhiteSpace(s.高考选科))
addExcelUser.GKSubject = s.高考选科;
}
//如果有错误数据则返回excel
if (impError.Count() != 0)
return File(impError.ExportExcel(), "application/ms-excel", $"导入错误学生{DateTime.Now.ToString("MMddHHmm")}.xlsx");
//调用 用户中心 导入接口
var importRes = await _userCenterService.CallAPI_ImportJsonData(_httpContextAccessor.HttpContext, userCenterImp);
var hUAccount = importRes.InsertUsers.ToDictionary(s=>s.Account,s=>s.Id);
//基于结果判断添加成功`
insertInfo = insertInfo
.Where(s => hUAccount.ContainsKey(s.UserCenterId.ToString())).Select(s =>
{
s.UserCenterId = hUAccount[s.UserCenterId.ToString()];
return s;
}).ToList();
//部分成功的数据写入数据库
await baseService.InsertRangeAsync(insertInfo);
//处理数据
var errorExcelInfo = importRes.ErrorExcelExport.Select(s => s.Adapt());
//如果有错误数据则返回excel
if (errorExcelInfo.Count() != 0)
return File(errorExcelInfo.ExportExcel(), "application/ms-excel", $"导入错误学生{DateTime.Now.ToString("MMddHHmm")}.xlsx");
return Ok();
}
///
/// 导入excel 更新学生信息
///
///
[HttpPost, ResultIgnore]
[HttpLogEnable]
public async Task ImportUpdateStudent(IFormFile? file)
{
var dataList = await _httpContextAccessor
.ParsingExcelAsync();
if (dataList == null || dataList.Count() == 0)
Oh.ModelError("导入失败:无有效数据");
var insertInfo = new List();
var impError = new List();
var userCenterImp = new List();
//如果有错误数据则返回excel
if (impError.Count() != 0)
return File(impError.ExportExcel(), "application/ms-excel", $"导入错误学生{DateTime.Now.ToString("MMddHHmm")}.xlsx");
//调用 用户中心 导入接口
var importRes = await _userCenterService.CallAPI_ImportJsonData(_httpContextAccessor.HttpContext, userCenterImp);
var hUAccount = importRes.InsertUsers.ToDictionary(s => s.Account, s => s.Id);
//基于结果判断添加成功`
insertInfo = insertInfo
.Where(s => hUAccount.ContainsKey(s.UserCenterId.ToString())).Select(s =>
{
s.UserCenterId = hUAccount[s.UserCenterId.ToString()];
return s;
}).ToList();
//部分成功的数据写入数据库
await baseService.InsertRangeAsync(insertInfo);
//处理数据
var errorExcelInfo = importRes.ErrorExcelExport.Select(s => s.Adapt());
//如果有错误数据则返回excel
if (errorExcelInfo.Count() != 0)
return File(errorExcelInfo.ExportExcel(), "application/ms-excel", $"导入错误学生{DateTime.Now.ToString("MMddHHmm")}.xlsx");
return Ok();
}
///
/// 下载导入模板
///
///
[HttpGet, ResultIgnore, AllowAnonymous]
public IActionResult DwImportTemplate()
{
var resultList = new List() { new StudentInfoImport()
{
RealName = "导入规范[导入时请删除本行]",
School = "必填:与系统匹配",
Grade = "必填:\r\n[高2027/高一/初一]",
Class = "必填:与系统匹配\r\n格式:10班[数字+班]",
Status = "选填 可选值\r\n[就读,退出]",
AmountRelief ="选填: 为0则视为 '未申请减免'",
ReliefType ="选填: 建卡贫困户\r\n低保户\r\n教师子女 \r\n孤儿\r\n艺体生\r\n残疾学生\r\n领导特殊承诺减免\r\n领导同意的特殊贫困减免",
ReliefApplication ="选填: [已申请, 未申请]",
StudentType = "选填: 可选值:\r\n复读生\r\n艺术生\r\n春招生\r\n领导承诺批准全免\r\n资源班\r\n国际班\r\n合同制收费学校\r\n渠道商家属\r\n新开班但领导承诺第一学期不收费",
Phone="选填",
Remark="选填",
高考选科 = "填写学科\r\n 例如 物理 \r\n多学科情况下 物理,化学,生物"
} };
return File(resultList.ExportExcel(), "application/ms-excel",
$"导入学生模板{DateTime.Now.ToString("MMddHHmm")}.xlsx");
}
///
/// 下载导入老师模板
///
///
[HttpGet, ResultIgnore, AllowAnonymous]
public IActionResult DwImportTeacherTemplate()
{
var resultList = new List() {
new TeacherInfoImport()
{
Phone="必填",
RealName = "导入规范[导入时请删除本行]",
UserType = "必填 可选值\r\n[年级主任,班主任,教师]",
School = "必填:与系统匹配",
Grade = "必填:可选值\r\n[高2027/高一/初一]",
Class = "必填:与系统匹配\r\n格式:10班[数字+班]\r\n任教类型是年级主任时不填",
Subject = "选填学科",
ExamNo ="选填: 填写老师任职信息[不在授课架构中的职务]",
}};
return File(resultList.ExportExcel(), "application/ms-excel",
$"导入老师模板_{DateTime.Now.ToString("MMddHHmm")}.xlsx");
}
}
}