Learn.Archives/Learn.Archives.API/Controllers/StudentController.cs

393 lines
17 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 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
{
/// <summary>
/// 学生接口
/// </summary>
public class StudentController : BackController<Student>
{
private readonly IHttpContextAccessor _httpContextAccessor;
readonly Repository<Student> baseService;
readonly Repository<Position> positionService;
readonly UserCenterService _userCenterService;
readonly LiveUserInfo userInfo;
public StudentController(Repository<Student> baseService, LiveUserInfo userInfo, IHttpContextAccessor httpContextAccessor, UserCenterService userCenterService, Repository<Position> positionService) : base(baseService)
{
this.baseService = baseService;
this.userInfo = userInfo;
_httpContextAccessor = httpContextAccessor;
_userCenterService = userCenterService;
this.positionService = positionService;
}
[NonAction]
public override Task<dynamic> PageList([FromBody] QueryRequestBase model)
{
return base.PageList(model);
}
/// <summary>
/// 用户信息
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<Student> Info(long uid)
{
if (uid == 0)
Oh.ModelError("无效数据");
return await baseService.AsQueryable().FirstAsync(s => s.UserCenterId == uid);
}
/// <summary>
/// 获取职位id
/// <para> 调用流程 用户中心->档案系统</para>
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<long[]> PosititonIds(PositionIdsReq[] data)
{
if (data == null || data.Count()==0)
Oh.ModelError("无效数据");
var query = new Expressionable<Position>();
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();
}
/// <summary>
/// 修改用户信息
/// <para> 调用流程 用户中心->档案系统</para>
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<long> EditInfo(Student e)
{
if (e == null || e.UserCenterId == 0)
Oh.ModelError("无效数据");
var has = await baseService.AsQueryable().FirstAsync(s => s.UserCenterId == e.UserCenterId);
if (has == null)
await baseService.InsertAsync(e);
else
{
e.Id = has.Id;
e.UserCenterId = has.UserCenterId;
await baseService.UpdateAsync(e);
}
return e.Id;
}
/// <summary>
/// 设置角色菜单
/// </summary>
/// <returns></returns>
[HttpPost]
public new async Task<PageResult<StudentInfoRes>> PageList()
{
var apiRes =await _userCenterService.CallAPI_GetPageUserList(_httpContextAccessor.HttpContext);
var res= new PageResult<StudentInfoRes>() { Data = new List<StudentInfoRes>() };
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<StudentInfoRes>()))
{
res.Data.Add(item);
if (!exDataDic.ContainsKey(item.Id)) continue;
var ex = exDataDic[item.Id].First();
item.Status = ex.Status;
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;
}
/// <summary>
/// 导入老师信息
/// </summary>
/// <returns></returns>
[HttpPost, ResultIgnore]
[HttpLogEnable]
public async Task<IActionResult> 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<TeacherInfoImportError> dataList;
using var stream = new MemoryStream();
{
await fl.CopyToAsync(stream);
dataList = stream.Query<TeacherInfoImportError>()
.Where(s => !string.IsNullOrEmpty(s.School));
}
if (dataList == null || dataList.Count() == 0)
Oh.ModelError("导入失败:无有效数据");
var insertInfo = new List<Student>();
var impError = new List<TeacherInfoImportError>();
var userCenterImp = new List<UserExcelExportData>();
foreach (var s in dataList)
{
var ginfo = GradeHelper.GetStudentGradeBaseByGrade(s.Grade);
var gStr = GradeHelper.GetGrade(ginfo.GradeLevel, ginfo.GradeYear);
if (gStr.ToEnum<GradeEnum>() == null) //无效的传入年级
{
s.ErrorMsg = "无效的年级 例如[初一/初2028] [年级范围应当是当前有效的就读年级]";
impError.Add(s);
continue;
}
//基础信息校验
if (string.IsNullOrEmpty(s.UserType) ||
string.IsNullOrEmpty(s.School)||
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<SubjectEnum>()==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<TeacherInfoImportError>());
//如果有错误数据则返回excel
if (errorExcelInfo.Count() != 0)
return File(errorExcelInfo.ExportExcel(), "application/ms-excel", $"导入错误的老师{DateTime.Now.ToString("MMddHHmm")}.xlsx");
return Ok();
}
/// <summary>
/// 导入学生信息
/// </summary>
/// <returns></returns>
[HttpPost, ResultIgnore]
[HttpLogEnable]
public async Task<IActionResult> 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<StudentInfoImportError> dataList;
using var stream = new MemoryStream();
{
await fl.CopyToAsync(stream);
dataList = stream.Query<StudentInfoImportError>()
.Where(s => !string.IsNullOrEmpty(s.School));
}
if (dataList == null || dataList.Count() == 0)
Oh.ModelError("导入失败:无有效数据");
var insertInfo = new List<Student>();
var impError = new List<StudentInfoImportError>();
var userCenterImp = new List<UserExcelExportData>();
foreach (var s in dataList)
{
var ginfo = GradeHelper.GetStudentGradeBaseByGrade(s.Grade);
var gStr = GradeHelper.GetGrade(ginfo.GradeLevel, ginfo.GradeYear);
if (gStr.ToEnum<GradeEnum>() == 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<UserStatusEnum>()??default,
UserCenterId = s.Id,
ReliefApplication=s.ReliefApplication?.Contains("已申请")??false,
ReliefSubTime = s.ReliefSubTime,
ReliefType =s.ReliefType,
StudentType =s.StudentType.ToEnum<StudentTypeEnum>(),
});
userCenterImp.Add(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()
});
}
//如果有错误数据则返回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<StudentInfoImportError>());
//如果有错误数据则返回excel
if (errorExcelInfo.Count() != 0)
return File(errorExcelInfo.ExportExcel(), "application/ms-excel", $"导入错误学生{DateTime.Now.ToString("MMddHHmm")}.xlsx");
return Ok();
}
/// <summary>
/// 下载导入模板
/// </summary>
/// <returns></returns>
[HttpGet, ResultIgnore, AllowAnonymous]
public IActionResult DwImportTemplate()
{
var resultList = new List<StudentInfoImport>() { 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="选填",
} };
return File(resultList.ExportExcel(), "application/ms-excel",
$"导入学生模板{DateTime.Now.ToString("MMddHHmm")}.xlsx");
}
/// <summary>
/// 下载导入老师模板
/// </summary>
/// <returns></returns>
[HttpGet, ResultIgnore, AllowAnonymous]
public IActionResult DwImportTeacherTemplate()
{
var resultList = new List<TeacherInfoImport>() {
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");
}
}
}