已完成“组织与权限”优化:
基础数据拆分为:组织机构、学年学期、教学场所。 人员档案拆分为:教师档案、学生档案。 基础数据、教师、学生、用户权限均支持 Excel 模板下载、批量导入和导出。 导入按编码/工号/学号/账号新增或更新;整批校验,失败不写入,限制 2000 条、10 MB。 用户列表新增密码重置,包含双重确认、最低 8 位校验和服务端权限保护。 导入严格执行角色及学院数据范围校验,并保护当前超级管理员账号。 保留旧地址重定向,原有入口不会失效。
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
using Jiaowu.Api.Infrastructure.Excel;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Jiaowu.Api.Tests;
|
||||
|
||||
public sealed class ExcelWorkbookHelperTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task Workbook_round_trip_preserves_headers_and_values()
|
||||
{
|
||||
var bytes = ExcelWorkbookHelper.Create(
|
||||
"教师档案",
|
||||
["工号", "姓名", "入职日期"],
|
||||
[
|
||||
new object?[]
|
||||
{
|
||||
"T001",
|
||||
"陈老师",
|
||||
new DateOnly(2026, 9, 1)
|
||||
}
|
||||
],
|
||||
["测试说明"]);
|
||||
await using var stream = new MemoryStream(bytes);
|
||||
var file = new FormFile(stream, 0, bytes.Length, "file", "teachers.xlsx");
|
||||
|
||||
var rows = await ExcelWorkbookHelper.ReadAsync(
|
||||
file,
|
||||
["工号", "姓名", "入职日期"],
|
||||
CancellationToken.None);
|
||||
|
||||
var row = Assert.Single(rows);
|
||||
Assert.Equal(2, row.RowNumber);
|
||||
Assert.Equal("T001", row["工号"]);
|
||||
Assert.Equal("陈老师", row["姓名"]);
|
||||
Assert.Equal("2026-09-01", row["入职日期"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Workbook_reader_rejects_missing_required_headers()
|
||||
{
|
||||
var bytes = ExcelWorkbookHelper.Create(
|
||||
"账号导入",
|
||||
["登录账号"],
|
||||
[new object?[] { "admin" }]);
|
||||
await using var stream = new MemoryStream(bytes);
|
||||
var file = new FormFile(stream, 0, bytes.Length, "file", "users.xlsx");
|
||||
|
||||
var exception = await Assert.ThrowsAsync<InvalidDataException>(() =>
|
||||
ExcelWorkbookHelper.ReadAsync(
|
||||
file,
|
||||
["登录账号", "角色"],
|
||||
CancellationToken.None));
|
||||
|
||||
Assert.Contains("角色", exception.Message);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user