yxq 3 mesi fa
parent
commit
fbf0621d7d
57 ha cambiato i file con 2966 aggiunte e 502 eliminazioni
  1. +143
    -1
      SafeCampus.API/SafeCampus.Application/SafeCampus.Application.xml
  2. +75
    -0
      SafeCampus.API/SafeCampus.Application/Services/Business/DepartmentService/DepartmentService.cs
  3. +17
    -0
      SafeCampus.API/SafeCampus.Application/Services/Business/DepartmentService/Dto/DepartmentDto.cs
  4. +9
    -0
      SafeCampus.API/SafeCampus.Application/Services/Business/DepartmentService/Dto/DepartmentSearch.cs
  5. +40
    -0
      SafeCampus.API/SafeCampus.Application/Services/Business/DepartmentService/IDepartmentService.cs
  6. +35
    -0
      SafeCampus.API/SafeCampus.Application/Services/Business/MajorService/Dto/MajorDto.cs
  7. +17
    -0
      SafeCampus.API/SafeCampus.Application/Services/Business/MajorService/Dto/MajorSearch.cs
  8. +40
    -0
      SafeCampus.API/SafeCampus.Application/Services/Business/MajorService/IMajorService.cs
  9. +80
    -0
      SafeCampus.API/SafeCampus.Application/Services/Business/MajorService/MajorService.cs
  10. +9
    -1
      SafeCampus.API/SafeCampus.Application/Services/Business/PersonSetInfoService/Dto/PersonSetInfoDto.cs
  11. +1
    -1
      SafeCampus.API/SafeCampus.Application/Services/Business/PersonSetInfoService/IPersonSetInfoService.cs
  12. +3
    -1
      SafeCampus.API/SafeCampus.Application/Services/Business/PersonSetInfoService/PersonSetInfoService.cs
  13. +20
    -0
      SafeCampus.API/SafeCampus.System/Entity/DepartmentInfo.cs
  14. +39
    -0
      SafeCampus.API/SafeCampus.System/Entity/MajorInfo.cs
  15. +11
    -1
      SafeCampus.API/SafeCampus.System/Entity/PersonSetInfo.cs
  16. +0
    -2
      SafeCampus.API/SafeCampus.System/Entity/System/SysDict.cs
  17. +50
    -0
      SafeCampus.API/SafeCampus.System/SafeCampus.System.xml
  18. +1
    -11
      SafeCampus.API/SafeCampus.Web.Core/Components/AuthComponent.cs
  19. +1
    -11
      SafeCampus.API/SafeCampus.Web.Core/Components/WebSettingsComponent.cs
  20. +78
    -0
      SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/Business/DepartmentController.cs
  21. +5
    -4
      SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/Business/DfieldApi.cs
  22. +2
    -2
      SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/Business/DormitoryController.cs
  23. +4
    -0
      SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/Business/Dto/DfieldInput.cs
  24. +77
    -0
      SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/Business/MajorController.cs
  25. +26
    -3
      SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/LargeScreen/LargeScreenController.cs
  26. +112
    -2
      SafeCampus.API/SafeCampus.Web.Core/SafeCampus.Web.Core.xml
  27. +1
    -1
      SafeCampus.API/SafeCampus.Web.Entry/Properties/PublishProfiles/FolderProfile.pubxml.user
  28. +14
    -3
      SafeCampus.WEB/components.d.ts
  29. +1
    -0
      SafeCampus.WEB/package.json
  30. +33
    -25
      SafeCampus.WEB/pnpm-lock.yaml
  31. +34
    -0
      SafeCampus.WEB/src/api/interface/sys/usermanage/department.ts
  32. +2
    -0
      SafeCampus.WEB/src/api/interface/sys/usermanage/index.ts
  33. +35
    -0
      SafeCampus.WEB/src/api/interface/sys/usermanage/major.ts
  34. +4
    -0
      SafeCampus.WEB/src/api/interface/sys/usermanage/personnel.ts
  35. +2
    -2
      SafeCampus.WEB/src/api/modules/usermanage/classManage.ts
  36. +60
    -0
      SafeCampus.WEB/src/api/modules/usermanage/department.ts
  37. +2
    -0
      SafeCampus.WEB/src/api/modules/usermanage/index.ts
  38. +60
    -0
      SafeCampus.WEB/src/api/modules/usermanage/major.ts
  39. +21
    -0
      SafeCampus.WEB/src/mixin/index.ts
  40. +26
    -3
      SafeCampus.WEB/src/utils/index.ts
  41. +81
    -12
      SafeCampus.WEB/src/views/attendance/behaviorTrace/index.vue
  42. +40
    -21
      SafeCampus.WEB/src/views/attendance/roolcall/components/form/index.vue
  43. +76
    -35
      SafeCampus.WEB/src/views/attendance/roolcall/index.vue
  44. +1
    -1
      SafeCampus.WEB/src/views/login/index.vue
  45. +4
    -0
      SafeCampus.WEB/src/views/monitor/live/index.vue
  46. +15
    -2
      SafeCampus.WEB/src/views/userManage/classManage/components/formClass/index.vue
  47. +6
    -4
      SafeCampus.WEB/src/views/userManage/classManage/components/formTeacher/index.vue
  48. +211
    -0
      SafeCampus.WEB/src/views/userManage/classManage/index.vue
  49. +120
    -0
      SafeCampus.WEB/src/views/userManage/department/components/form.vue
  50. +115
    -0
      SafeCampus.WEB/src/views/userManage/department/index.vue
  51. +137
    -0
      SafeCampus.WEB/src/views/userManage/major/components/form.vue
  52. +138
    -0
      SafeCampus.WEB/src/views/userManage/major/index.vue
  53. +36
    -10
      SafeCampus.WEB/src/views/userManage/personnel/components/form/form_basic.vue
  54. +4
    -3
      SafeCampus.WEB/src/views/userManage/personnel/components/form/index.vue
  55. +74
    -129
      SafeCampus.WEB/src/views/userManage/personnel/index.vue
  56. +673
    -162
      SafeCampus.WEB/src/views/violation/portrait/detail.vue
  57. +45
    -49
      SafeCampus.WEB/src/views/warn/zjrq/index.vue

+ 143
- 1
SafeCampus.API/SafeCampus.Application/SafeCampus.Application.xml Vedi File

@@ -1020,6 +1020,67 @@
</summary>
<returns></returns>
</member>
<member name="P:SafeCampus.Application.Services.Business.DepartmentService.DepartmentDto.Id">
<summary>
id
</summary>
</member>
<member name="P:SafeCampus.Application.Services.Business.DepartmentService.DepartmentDto.Name">
<summary>
院系名称
</summary>
</member>
<member name="P:SafeCampus.Application.Services.Business.DepartmentService.DepartmentDto.Code">
<summary>
院系编码
</summary>
</member>
<member name="P:SafeCampus.Application.Services.Business.DepartmentService.DepartmentSearch.Name">
<summary>
院系名称
</summary>
</member>
<member name="M:SafeCampus.Application.Services.Business.DepartmentService.IDepartmentService.Add(SafeCampus.Application.Services.Business.DepartmentService.DepartmentDto)">
<summary>
添加
</summary>
<param name="input">添加参数</param>
<returns></returns>
</member>
<member name="M:SafeCampus.Application.Services.Business.DepartmentService.IDepartmentService.Update(SafeCampus.Application.Services.Business.DepartmentService.DepartmentDto)">
<summary>
修改
</summary>
<param name="input">添加参数</param>
<returns></returns>
</member>
<member name="M:SafeCampus.Application.Services.Business.DepartmentService.IDepartmentService.GetInfo(System.Int64)">
<summary>
获取详情
</summary>
<param name="id"></param>
<returns></returns>
</member>
<member name="M:SafeCampus.Application.Services.Business.DepartmentService.IDepartmentService.Delete(System.Collections.Generic.List{System.Int64})">
<summary>
删除
</summary>
<param name="id">id</param>
<returns></returns>
</member>
<member name="M:SafeCampus.Application.Services.Business.DepartmentService.IDepartmentService.GetPageList(SafeCampus.Application.Services.Business.DepartmentService.DepartmentSearch)">
<summary>
获取列表
</summary>
<returns></returns>
</member>
<member name="M:SafeCampus.Application.Services.Business.DepartmentService.IDepartmentService.GetNoPageList(SafeCampus.Application.Services.Business.DepartmentService.DepartmentSearch)">
<summary>
不分页获取列表
</summary>
<param name="search"></param>
<returns></returns>
</member>
<member name="P:SafeCampus.Application.Services.Business.DormitoryService.DormitoryInfoDto.Id">
<summary>
ID
@@ -1178,6 +1239,82 @@
<param name="search"></param>
<returns></returns>
</member>
<member name="P:SafeCampus.Application.Services.Business.MajorService.MajorDto.Name">
<summary>
专业名称
</summary>
</member>
<member name="P:SafeCampus.Application.Services.Business.MajorService.MajorDto.Code">
<summary>
专业编码
</summary>
</member>
<member name="P:SafeCampus.Application.Services.Business.MajorService.MajorDto.Introduce">
<summary>
专业简介
</summary>
</member>
<member name="P:SafeCampus.Application.Services.Business.MajorService.MajorDto.DepId">
<summary>
院系id
</summary>
</member>
<member name="P:SafeCampus.Application.Services.Business.MajorService.MajorSearch.Name">
<summary>
专业名称
</summary>
</member>
<member name="P:SafeCampus.Application.Services.Business.MajorService.MajorSearch.Code">
<summary>
专业编码
</summary>
</member>
<member name="P:SafeCampus.Application.Services.Business.MajorService.MajorSearch.DepId">
<summary>
院系id
</summary>
</member>
<member name="M:SafeCampus.Application.Services.Business.MajorService.IMajorService.Add(SafeCampus.Application.Services.Business.MajorService.MajorDto)">
<summary>
添加
</summary>
<param name="input">添加参数</param>
<returns></returns>
</member>
<member name="M:SafeCampus.Application.Services.Business.MajorService.IMajorService.Update(SafeCampus.Application.Services.Business.MajorService.MajorDto)">
<summary>
修改
</summary>
<param name="input">添加参数</param>
<returns></returns>
</member>
<member name="M:SafeCampus.Application.Services.Business.MajorService.IMajorService.GetInfo(System.Int64)">
<summary>
获取详情
</summary>
<param name="id"></param>
<returns></returns>
</member>
<member name="M:SafeCampus.Application.Services.Business.MajorService.IMajorService.Delete(System.Collections.Generic.List{System.Int64})">
<summary>
删除
</summary>
<param name="id">id</param>
<returns></returns>
</member>
<member name="M:SafeCampus.Application.Services.Business.MajorService.IMajorService.GetPageList(SafeCampus.Application.Services.Business.MajorService.MajorSearch)">
<summary>
获取列表
</summary>
<returns></returns>
</member>
<member name="M:SafeCampus.Application.Services.Business.MajorService.IMajorService.GetNoPageList(SafeCampus.Application.Services.Business.MajorService.MajorSearch)">
<summary>
获取列表不分页
</summary>
<param name="search"></param>
<returns></returns>
</member>
<member name="P:SafeCampus.Application.Services.Business.PassengerFlowService.Dto.PassengerFlowDto.Id">
<summary>
主键Id
@@ -1460,6 +1597,11 @@
班级名称
</summary>
</member>
<member name="P:SafeCampus.Application.Services.Business.PersonSetInfoService.PersonSetInfoDto.MajorId">
<summary>
专业id
</summary>
</member>
<member name="M:SafeCampus.Application.Services.Business.PersonSetInfoService.IPersonSetInfoService.Add(SafeCampus.Application.Services.Business.PersonSetInfoService.PersonSetInfoDto)">
<summary>
添加班级
@@ -1480,7 +1622,7 @@
<param name="input"></param>
<returns></returns>
</member>
<member name="M:SafeCampus.Application.Services.Business.PersonSetInfoService.IPersonSetInfoService.GetPageList">
<member name="M:SafeCampus.Application.Services.Business.PersonSetInfoService.IPersonSetInfoService.GetPageList(System.Nullable{System.Int64})">
<summary>
获取底库列表
</summary>


+ 75
- 0
SafeCampus.API/SafeCampus.Application/Services/Business/DepartmentService/DepartmentService.cs Vedi File

@@ -0,0 +1,75 @@
namespace SafeCampus.Application.Services.Business.DepartmentService;

public class DepartmentService: DbRepository<DepartmentInfo>, IDepartmentService
{
public async Task<bool> Add(DepartmentDto input)
{
var model = input.Adapt<DepartmentInfo>();
await InsertAsync(model);
return true;
}

public async Task<bool> Update(DepartmentDto input)
{
if (!input.Id.HasValue)
{
throw Oops.Oh("请填写ID");
}
var model = await GetFirstAsync(p => p.Id == input.Id);
if (model == null)
{
throw Oops.Oh("信息不存在");
}
var res = input.Adapt(model);
await UpdateAsync(res);
return true;
}

public async Task<DepartmentDto> GetInfo(long id)
{
var query = await Context.Queryable<DepartmentInfo>()
.FirstAsync(x => x.Id == id);
return query.Adapt<DepartmentDto>();
}

public async Task<bool> Delete(List<long> id)
{
var majorInfo = ChangeRepository<DbRepository<MajorInfo>>();//切换仓储

var model = await GetListAsync(x => id.Contains(x.Id));
if (!model.Any())
{
throw Oops.Oh("信息不存在");
}
foreach (var departmentInfo in model)
{
var isOK = await majorInfo.IsAnyAsync(x => x.DepId == departmentInfo.Id);
if (isOK)
{
throw Oops.Oh($"{departmentInfo.Name}院系下还有专业禁止删除!");
}
}
await DeleteAsync(model);
return true;
}

public async Task<SqlSugarPagedList<DepartmentDto>> GetPageList(DepartmentSearch search)
{
var query = Context.Queryable<DepartmentInfo>()
.WhereIF(!string.IsNullOrEmpty(search.Name), x => x.Name.Contains(search.Name));

var list = await query.OrderByDescending(x => x.Code)
.ToPagedListAsyncMapster<DepartmentInfo, DepartmentDto>(search.PageNum, search.PageSize);
return list;
}

public async Task<List<DepartmentDto>> GetNoPageList(DepartmentSearch search)
{
var query = Context.Queryable<DepartmentInfo>()
.WhereIF(!string.IsNullOrEmpty(search.Name), x => x.Name.Contains(search.Name));

var list = await query.OrderByDescending(x => x.Code)
.ToListAsync();
return list.Adapt<List<DepartmentDto>>();
}
}

+ 17
- 0
SafeCampus.API/SafeCampus.Application/Services/Business/DepartmentService/Dto/DepartmentDto.cs Vedi File

@@ -0,0 +1,17 @@
namespace SafeCampus.Application.Services.Business.DepartmentService;

public class DepartmentDto
{
/// <summary>
/// id
/// </summary>
public long? Id { get; set; }
/// <summary>
/// 院系名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 院系编码
/// </summary>
public string Code { get; set; }
}

+ 9
- 0
SafeCampus.API/SafeCampus.Application/Services/Business/DepartmentService/Dto/DepartmentSearch.cs Vedi File

@@ -0,0 +1,9 @@
namespace SafeCampus.Application.Services.Business.DepartmentService;

public class DepartmentSearch: BasePageInput
{
/// <summary>
/// 院系名称
/// </summary>
public string Name { get; set; }
}

+ 40
- 0
SafeCampus.API/SafeCampus.Application/Services/Business/DepartmentService/IDepartmentService.cs Vedi File

@@ -0,0 +1,40 @@
namespace SafeCampus.Application.Services.Business.DepartmentService;

public interface IDepartmentService : ITransient
{
/// <summary>
/// 添加
/// </summary>
/// <param name="input">添加参数</param>
/// <returns></returns>
Task<bool> Add(DepartmentDto input);
/// <summary>
/// 修改
/// </summary>
/// <param name="input">添加参数</param>
/// <returns></returns>
Task<bool> Update(DepartmentDto input);
/// <summary>
/// 获取详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Task<DepartmentDto> GetInfo(long id);
/// <summary>
/// 删除
/// </summary>
/// <param name="id">id</param>
/// <returns></returns>
Task<bool> Delete(List<long> id);
/// <summary>
/// 获取列表
/// </summary>
/// <returns></returns>
Task<SqlSugarPagedList<DepartmentDto>> GetPageList(DepartmentSearch search);
/// <summary>
/// 不分页获取列表
/// </summary>
/// <param name="search"></param>
/// <returns></returns>
Task<List<DepartmentDto>> GetNoPageList(DepartmentSearch search);
}

+ 35
- 0
SafeCampus.API/SafeCampus.Application/Services/Business/MajorService/Dto/MajorDto.cs Vedi File

@@ -0,0 +1,35 @@
using SafeCampus.Application.Services.Business.DepartmentService;

namespace SafeCampus.Application.Services.Business.MajorService;

public class MajorDto
{
public long? Id { get; set; }
/// <summary>
/// 专业名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 专业编码
/// </summary>
public string Code { get; set; }
/// <summary>
/// 专业简介
/// </summary>
public string Introduce { get; set; }
/// <summary>
/// 院系id
/// </summary>
public long DepId { get; set; }

public string DepartmentName { get; set; }
}

public class MajorDtoMapper : IRegister
{
public void Register(TypeAdapterConfig config)
{
config.ForType<MajorInfo, MajorDto>()
.Map(x => x.DepartmentName, x => x.DepartmentInfoItem.Name);
}
}

+ 17
- 0
SafeCampus.API/SafeCampus.Application/Services/Business/MajorService/Dto/MajorSearch.cs Vedi File

@@ -0,0 +1,17 @@
namespace SafeCampus.Application.Services.Business.MajorService;

public class MajorSearch:BasePageInput
{
/// <summary>
/// 专业名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 专业编码
/// </summary>
public string Code { get; set; }
/// <summary>
/// 院系id
/// </summary>
public long? DepId { get; set; }
}

+ 40
- 0
SafeCampus.API/SafeCampus.Application/Services/Business/MajorService/IMajorService.cs Vedi File

@@ -0,0 +1,40 @@
namespace SafeCampus.Application.Services.Business.MajorService;

public interface IMajorService : ITransient
{
/// <summary>
/// 添加
/// </summary>
/// <param name="input">添加参数</param>
/// <returns></returns>
Task<bool> Add(MajorDto input);
/// <summary>
/// 修改
/// </summary>
/// <param name="input">添加参数</param>
/// <returns></returns>
Task<bool> Update(MajorDto input);
/// <summary>
/// 获取详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Task<MajorDto> GetInfo(long id);
/// <summary>
/// 删除
/// </summary>
/// <param name="id">id</param>
/// <returns></returns>
Task<bool> Delete(List<long> id);
/// <summary>
/// 获取列表
/// </summary>
/// <returns></returns>
Task<SqlSugarPagedList<MajorDto>> GetPageList(MajorSearch search);
/// <summary>
/// 获取列表不分页
/// </summary>
/// <param name="search"></param>
/// <returns></returns>
Task<List<MajorDto>> GetNoPageList(MajorSearch search);
}

+ 80
- 0
SafeCampus.API/SafeCampus.Application/Services/Business/MajorService/MajorService.cs Vedi File

@@ -0,0 +1,80 @@
namespace SafeCampus.Application.Services.Business.MajorService;

public class MajorService: DbRepository<MajorInfo>, IMajorService
{
public async Task<bool> Add(MajorDto input)
{
var model = input.Adapt<MajorInfo>();
await InsertAsync(model);
return true;
}

public async Task<bool> Update(MajorDto input)
{
if (!input.Id.HasValue)
{
throw Oops.Oh("请填写ID");
}
var model = await GetFirstAsync(p => p.Id == input.Id);
if (model == null)
{
throw Oops.Oh("信息不存在");
}
var res = input.Adapt(model);
await UpdateAsync(res);
return true;
}

public async Task<MajorDto> GetInfo(long id)
{
var query = await Context.Queryable<MajorInfo>()
.Includes(x => x.DepartmentInfoItem)
.FirstAsync(x => x.Id == id);
return query.Adapt<MajorDto>();
}

public async Task<bool> Delete(List<long> id)
{
var personSetInfo = ChangeRepository<DbRepository<PersonSetInfo>>();//切换仓储
var model = await GetListAsync(x => id.Contains(x.Id));
if (!model.Any())
{
throw Oops.Oh("信息不存在");
}
foreach (var majorInfo in model)
{
var isOK = await personSetInfo.IsAnyAsync(x => x.MajorId == majorInfo.Id);
if (isOK)
{
throw Oops.Oh($"{majorInfo.Name}专业下还有班级禁止删除!");
}
}
await DeleteAsync(model);
return true;
}

public async Task<SqlSugarPagedList<MajorDto>> GetPageList(MajorSearch search)
{
var query = Context.Queryable<MajorInfo>()
.Includes(x=>x.DepartmentInfoItem)
.WhereIF(!string.IsNullOrEmpty(search.Name), x => x.Name.Contains(search.Name))
.WhereIF(!string.IsNullOrEmpty(search.Code),x=>x.Code.Contains(search.Code))
.WhereIF(search.DepId.HasValue,x=>x.DepId==search.DepId);

var list = await query.OrderByDescending(x => x.Sort)
.ToPagedListAsyncMapster<MajorInfo, MajorDto>(search.PageNum, search.PageSize);
return list;
}

public async Task<List<MajorDto>> GetNoPageList(MajorSearch search)
{
var query = Context.Queryable<MajorInfo>()
.Includes(x => x.DepartmentInfoItem)
.WhereIF(!string.IsNullOrEmpty(search.Name), x => x.Name.Contains(search.Name))
.WhereIF(!string.IsNullOrEmpty(search.Code), x => x.Code.Contains(search.Code))
.WhereIF(search.DepId.HasValue, x => x.DepId == search.DepId);

var list = await query.OrderByDescending(x => x.Sort).ToListAsync();
return list.Adapt<List<MajorDto>>();
}
}

+ 9
- 1
SafeCampus.API/SafeCampus.Application/Services/Business/PersonSetInfoService/Dto/PersonSetInfoDto.cs Vedi File

@@ -10,9 +10,15 @@ public class PersonSetInfoDto
/// 班级名称
/// </summary>
public string PersonSetName { get; set; }
/// <summary>
/// 专业id
/// </summary>
public long MajorId { get; set; }

public string UserId { get; set; }
public string UserName { get; set; }
public string MajorName { get; set; }
public string DepartmentName { get; set; }
}

public class PersonSetInfoDtoMapper : IRegister
@@ -21,6 +27,8 @@ public class PersonSetInfoDtoMapper : IRegister
{
config.ForType<PersonSetInfo, PersonSetInfoDto>()
.Map(x => x.UserId, x => x.ClassTeacherItem.UserId)
.Map(x => x.UserName, x => x.ClassTeacherItem.SysUserItem.Name);
.Map(x => x.UserName, x => x.ClassTeacherItem.SysUserItem.Name)
.Map(x=>x.DepartmentName,x=>x.MajorInfoItem.DepartmentInfoItem.Name)
.Map(x=>x.MajorName,x=>x.MajorInfoItem.Name);
}
}

+ 1
- 1
SafeCampus.API/SafeCampus.Application/Services/Business/PersonSetInfoService/IPersonSetInfoService.cs Vedi File

@@ -23,5 +23,5 @@ public interface IPersonSetInfoService:ITransient
/// 获取底库列表
/// </summary>
/// <returns></returns>
Task<List<PersonSetInfoDto>> GetPageList();
Task<List<PersonSetInfoDto>> GetPageList(long? majorId);
}

+ 3
- 1
SafeCampus.API/SafeCampus.Application/Services/Business/PersonSetInfoService/PersonSetInfoService.cs Vedi File

@@ -38,10 +38,12 @@ public class PersonSetInfoService:DbRepository<PersonSetInfo>, IPersonSetInfoSer
return true;
}

public async Task<List<PersonSetInfoDto>> GetPageList()
public async Task<List<PersonSetInfoDto>> GetPageList(long? majorId)
{
var list =await Context.Queryable<PersonSetInfo>()
.Includes(x=>x.MajorInfoItem,x=>x.DepartmentInfoItem)
.Where(x=>x.PersonSetId!=SafeCampusConst.ZDRY)
.WhereIF(majorId.HasValue,x=>x.MajorId==majorId)
.Includes(x => x.ClassTeacherItem, st => st.SysUserItem)
.ToListAsync();
return list.Adapt<List<PersonSetInfoDto>>();


+ 20
- 0
SafeCampus.API/SafeCampus.System/Entity/DepartmentInfo.cs Vedi File

@@ -0,0 +1,20 @@
namespace SafeCampus.System;
[SugarTable("DepartmentInfo", TableDescription = "院系信息表")]
[Tenant(SqlSugarConst.DB_DEFAULT)]
[BatchEdit]
[CodeGen]
//[IgnoreInitTable]
public class DepartmentInfo : PrimaryKeyEntity
{
/// <summary>
/// 院系名称
/// </summary>
[SugarColumn(ColumnName = "Name", ColumnDescription = "院系名称", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = false)]
public string Name { get; set; }
/// <summary>
/// 院系编码
/// </summary>
[SugarColumn(ColumnName = "Code", ColumnDescription = "院系编码", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = false)]
public string Code { get; set; }

}

+ 39
- 0
SafeCampus.API/SafeCampus.System/Entity/MajorInfo.cs Vedi File

@@ -0,0 +1,39 @@
namespace SafeCampus.System;
[SugarTable("MajorInfo", TableDescription = "专业信息表")]
[Tenant(SqlSugarConst.DB_DEFAULT)]
[BatchEdit]
[CodeGen]
//[IgnoreInitTable]
public class MajorInfo : PrimaryKeyEntity
{
/// <summary>
/// 专业名称
/// </summary>
[SugarColumn(ColumnName = "Name", ColumnDescription = "专业名称", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = false)]
public string Name { get; set; }
/// <summary>
/// 专业编码
/// </summary>
[SugarColumn(ColumnName = "Code", ColumnDescription = "专业编码", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = false)]
public string Code { get; set; }
/// <summary>
/// 专业简介
/// </summary>
[SugarColumn(ColumnName = "Introduce", ColumnDescription = "专业简介", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
public string Introduce { get; set; }
/// <summary>
/// 院系id
/// </summary>
[SugarColumn(ColumnName = "DepId", ColumnDescription = "院系id",IsNullable = false)]
public long DepId { get; set; }
/// <summary>
/// 排序
/// </summary>
[SugarColumn(ColumnName = "Sort", ColumnDescription = "排序", IsNullable = false)]
public int Sort { get; set; }
/// <summary>
/// 院系信息
/// </summary>
[Navigate(NavigateType.OneToOne, nameof(DepartmentInfo.Id), nameof(DepId))]
public DepartmentInfo DepartmentInfoItem { get; set; }
}

+ 11
- 1
SafeCampus.API/SafeCampus.System/Entity/PersonSetInfo.cs Vedi File

@@ -3,7 +3,7 @@
[Tenant(SqlSugarConst.DB_DEFAULT)]
[BatchEdit]
[CodeGen]
[IgnoreInitTable]
//[IgnoreInitTable]
public class PersonSetInfo
{
/// <summary>
@@ -17,6 +17,16 @@ public class PersonSetInfo
[SugarColumn(ColumnName = "PersonSetName", ColumnDescription = "班级名称", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = false)]
public string PersonSetName { get; set; }
/// <summary>
/// 专业id
/// </summary>
[SugarColumn(ColumnName = "MajorId", ColumnDescription = "专业id", IsNullable = false)]
public long MajorId { get; set; }
/// <summary>
/// 专业信息
/// </summary>
[Navigate(NavigateType.OneToOne, nameof(MajorInfo.Id), nameof(MajorId))]
public MajorInfo MajorInfoItem { get; set; }
/// <summary>
/// 班主任信息
/// </summary>
[Navigate(NavigateType.OneToOne, nameof(ClassTeacher.PersonSetId),nameof(PersonSetId))]


+ 0
- 2
SafeCampus.API/SafeCampus.System/Entity/System/SysDict.cs Vedi File

@@ -37,8 +37,6 @@ public class SysDict : BaseEntity
///</summary>
[SugarColumn(ColumnName = "SortCode", ColumnDescription = "排序码")]
public int SortCode { get; set; }


/// <summary>
/// 子节点
/// </summary>


+ 50
- 0
SafeCampus.API/SafeCampus.System/SafeCampus.System.xml Vedi File

@@ -1071,6 +1071,16 @@
班主任信息
</summary>
</member>
<member name="P:SafeCampus.System.DepartmentInfo.Name">
<summary>
院系名称
</summary>
</member>
<member name="P:SafeCampus.System.DepartmentInfo.Code">
<summary>
院系编码
</summary>
</member>
<member name="P:SafeCampus.System.DormitoryInfo.Name">
<summary>
寝室名称
@@ -1101,6 +1111,36 @@
宿舍楼信息
</summary>
</member>
<member name="P:SafeCampus.System.MajorInfo.Name">
<summary>
专业名称
</summary>
</member>
<member name="P:SafeCampus.System.MajorInfo.Code">
<summary>
专业编码
</summary>
</member>
<member name="P:SafeCampus.System.MajorInfo.Introduce">
<summary>
专业简介
</summary>
</member>
<member name="P:SafeCampus.System.MajorInfo.DepId">
<summary>
院系id
</summary>
</member>
<member name="P:SafeCampus.System.MajorInfo.Sort">
<summary>
排序
</summary>
</member>
<member name="P:SafeCampus.System.MajorInfo.DepartmentInfoItem">
<summary>
院系信息
</summary>
</member>
<member name="P:SafeCampus.System.PassengerFlow.QueryTime">
<summary>
查询时间
@@ -1241,6 +1281,16 @@
班级名称
</summary>
</member>
<member name="P:SafeCampus.System.PersonSetInfo.MajorId">
<summary>
专业id
</summary>
</member>
<member name="P:SafeCampus.System.PersonSetInfo.MajorInfoItem">
<summary>
专业信息
</summary>
</member>
<member name="P:SafeCampus.System.PersonSetInfo.ClassTeacherItem">
<summary>
班主任信息


+ 1
- 11
SafeCampus.API/SafeCampus.Web.Core/Components/AuthComponent.cs Vedi File

@@ -1,14 +1,4 @@

//








using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authentication.JwtBearer;

namespace SafeCampus.Web.Core;



+ 1
- 11
SafeCampus.API/SafeCampus.Web.Core/Components/WebSettingsComponent.cs Vedi File

@@ -1,14 +1,4 @@

//








namespace SafeCampus.Web.Core;
namespace SafeCampus.Web.Core;

/// <summary>
/// Web设置组件


+ 78
- 0
SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/Business/DepartmentController.cs Vedi File

@@ -0,0 +1,78 @@

using SafeCampus.Application.Services.Business.DepartmentService;

namespace SafeCampus.Web.Core.Controllers.Application.Business;
/// <summary>
///系部管理接口
/// </summary>
[ApiDescriptionSettings(ApiGroupConsts.SYSTEM_Business, Order = 83, Tag = "系部管理")]
[Route("/business/department")]
[RolePermission]
public class DepartmentController
{
private readonly IDepartmentService _departmentService;

public DepartmentController(IDepartmentService departmentService)
{
_departmentService = departmentService;
}

/// <summary>
/// 添加
/// </summary>
/// <param name="input">添加参数</param>
/// <returns></returns>
public async Task<bool> Add(DepartmentDto input)
{
return await _departmentService.Add(input);
}

/// <summary>
/// 修改
/// </summary>
/// <param name="input">添加参数</param>
/// <returns></returns>
public async Task<bool> Update(DepartmentDto input)
{
return await _departmentService.Update(input);
}

/// <summary>
/// 获取详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<DepartmentDto> GetInfo(long id)
{
return await _departmentService.GetInfo(id);
}

/// <summary>
/// 删除
/// </summary>
/// <param name="id">id</param>
/// <returns></returns>
public async Task<bool> Delete(List<long> id)
{
return await _departmentService.Delete(id);
}

/// <summary>
/// 获取列表
/// </summary>
/// <returns></returns>
public async Task<SqlSugarPagedList<DepartmentDto>> GetPageList(DepartmentSearch search)
{
return await _departmentService.GetPageList(search);
}

/// <summary>
/// 不分页获取列表
/// </summary>
/// <param name="search"></param>
/// <returns></returns>
public async Task<List<DepartmentDto>> GetNoPageList(DepartmentSearch search)
{
return await _departmentService.GetNoPageList(search);
}
}

+ 5
- 4
SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/Business/DfieldApi.cs Vedi File

@@ -45,7 +45,7 @@ public class DfieldApi : IDynamicApiController
var model = JsonConvert.DeserializeObject<JObject>(str);
if ((bool)model["success"])
{
await _personSetInfoService.Add(new PersonSetInfoDto{PersonSetId = personSetId ,PersonSetName = input.Name});
await _personSetInfoService.Add(new PersonSetInfoDto{PersonSetId = personSetId ,PersonSetName = input.Name,MajorId = input.MagjorId});
return model["data"];
}

@@ -55,9 +55,9 @@ public class DfieldApi : IDynamicApiController
/// 查询底库列表
/// </summary>
/// <returns></returns>
public async Task<dynamic> QueryAll()
public async Task<dynamic> QueryAll(long? majorId)
{
return await _personSetInfoService.GetPageList();
return await _personSetInfoService.GetPageList(majorId);
var appSettings = App.GetOptionsMonitor<AppInfoOptions>();
var str = await $"{appSettings.SXAPIURL}/dfield-api/ecology/person/set/queryAll"
.SetBody(new
@@ -151,7 +151,8 @@ public class DfieldApi : IDynamicApiController
await _personSetInfoService.Update(new PersonSetInfoDto
{
PersonSetId = input.Id,
PersonSetName = input.Name
PersonSetName = input.Name,
MajorId = input.MagjorId
});
}
return isOk;


+ 2
- 2
SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/Business/DormitoryController.cs Vedi File

@@ -112,7 +112,7 @@ public class DormitoryController
public async Task<ReturnDormitoryDto> GetReturnInfo(long id,DateTime returnTime)
{
var model= await _dormitoryService.GetReturnInfo(id, returnTime);
model.AttendanceDtos = model.AttendanceDtos?.GroupBy(x => x.PersonId).Select(x => x.FirstOrDefault()).ToList();
model.AttendanceDtos = model.AttendanceDtos?.GroupBy(x => x.PersonId).Select(x => x.MaxBy(xx=>xx.Tick)).ToList();
foreach (var modelPersonInfo in model.PersonInfos)
{
modelPersonInfo.Attendances = null;
@@ -145,7 +145,7 @@ public class DormitoryController
configId = queryList["data"][0]["configId"].ParseToInt();
}
var time = new { timeBegin = input.TimeBegin, timeEnd = input.TimeEnd };
var personSetIds = await _personSetInfoService.GetPageList();
var personSetIds = await _personSetInfoService.GetPageList(null);
var cameras = await _cameraInfoService.GetPageList(new CameraSearch{PageSize = 1000,PageNum = 1});
var body = new
{


+ 4
- 0
SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/Business/Dto/DfieldInput.cs Vedi File

@@ -10,6 +10,10 @@ public class ControllersNameInput
{
[IdNotNull(ErrorMessage = "name不能为空")]
public string Name { get; set; }
/// <summary>
/// 专业id
/// </summary>
public long MagjorId { get; set; }
}
public class ControllersIdInput
{


+ 77
- 0
SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/Business/MajorController.cs Vedi File

@@ -0,0 +1,77 @@
using SafeCampus.Application.Services.Business.MajorService;

namespace SafeCampus.Web.Core.Controllers.Application.Business;
/// <summary>
///专业管理接口
/// </summary>
[ApiDescriptionSettings(ApiGroupConsts.SYSTEM_Business, Order = 82, Tag = "专业管理")]
[Route("/business/major")]
[RolePermission]
public class MajorController
{
private readonly IMajorService _majorService;

public MajorController(IMajorService majorService)
{
_majorService = majorService;
}

/// <summary>
/// 添加
/// </summary>
/// <param name="input">添加参数</param>
/// <returns></returns>
public async Task<bool> Add(MajorDto input)
{
return await _majorService.Add(input);
}

/// <summary>
/// 修改
/// </summary>
/// <param name="input">添加参数</param>
/// <returns></returns>
public async Task<bool> Update(MajorDto input)
{
return await _majorService.Update(input);
}

/// <summary>
/// 获取详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<MajorDto> GetInfo(long id)
{
return await _majorService.GetInfo(id);
}

/// <summary>
/// 删除
/// </summary>
/// <param name="id">id</param>
/// <returns></returns>
public async Task<bool> Delete(List<long> id)
{
return await _majorService.Delete(id);
}

/// <summary>
/// 获取列表
/// </summary>
/// <returns></returns>
public async Task<SqlSugarPagedList<MajorDto>> GetPageList(MajorSearch search)
{
return await _majorService.GetPageList(search);
}

/// <summary>
/// 获取列表不分页
/// </summary>
/// <param name="search"></param>
/// <returns></returns>
public async Task<List<MajorDto>> GetNoPageList(MajorSearch search)
{
return await _majorService.GetNoPageList(search);
}
}

+ 26
- 3
SafeCampus.API/SafeCampus.Web.Core/Controllers/Application/LargeScreen/LargeScreenController.cs Vedi File

@@ -13,6 +13,8 @@ using SafeCampus.Web.Core.Controllers.Application.Business;
using MoYu.RemoteRequest.Extensions;
using Newtonsoft.Json.Linq;
using SafeCampus.Application.Manager.DeepelephManager;
using SafeCampus.Application.Services.Business.DepartmentService;
using SafeCampus.Application.Services.Business.MajorService;
using SafeCampus.Application.Services.Business.PersonSetInfoService;

namespace SafeCampus.Web.Core.Controllers.Application.LargeScreen;
@@ -37,9 +39,11 @@ public class LargeScreenController
private readonly IClassRoomCallService _classRoomCallService;
private readonly IDeepelephManager _deepelephManager;
private readonly IPersonSetInfoService _personSetInfoService;
private readonly IMajorService _majorService;
private readonly IDepartmentService _departmentService;


public LargeScreenController(IPersonInfoService personInfoService, ICameraGroupService cameraGroupService, IWarnInfoService warnInfoService, ISimpleCacheService simpleCacheService, IAttendanceService attendanceService, IBuildingService buildingService, IDormitoryService dormitoryService, IConfigService configService, IClassRoomCallTaskService classRoomCallTaskService, IClassRoomCallService classRoomCallService, IDeepelephManager deepelephManager, IPersonSetInfoService personSetInfoService)
public LargeScreenController(IPersonInfoService personInfoService, ICameraGroupService cameraGroupService, IWarnInfoService warnInfoService, ISimpleCacheService simpleCacheService, IAttendanceService attendanceService, IBuildingService buildingService, IDormitoryService dormitoryService, IConfigService configService, IClassRoomCallTaskService classRoomCallTaskService, IClassRoomCallService classRoomCallService, IDeepelephManager deepelephManager, IPersonSetInfoService personSetInfoService, IMajorService majorService, IDepartmentService departmentService)
{
_personInfoService = personInfoService;
_cameraGroupService = cameraGroupService;
@@ -53,6 +57,8 @@ public class LargeScreenController
_classRoomCallService = classRoomCallService;
_deepelephManager = deepelephManager;
_personSetInfoService = personSetInfoService;
_majorService = majorService;
_departmentService = departmentService;
}

/// <summary>
@@ -302,8 +308,25 @@ public class LargeScreenController
/// 获取班级列表
/// </summary>
/// <returns></returns>
public async Task<dynamic> GetPersonSetNoPageList()
public async Task<dynamic> GetPersonSetNoPageList(long? majorId)
{
return await _personSetInfoService.GetPageList();
return await _personSetInfoService.GetPageList(majorId);
}
/// <summary>
/// 获取专业
/// </summary>
/// <param name="depId">院系id</param>
/// <returns></returns>
public async Task<dynamic> GetMajorNoPageList(long? depId)
{
return await _majorService.GetNoPageList(new MajorSearch{DepId = depId});
}
/// <summary>
/// 获取院系
/// </summary>
/// <returns></returns>
public async Task<dynamic> GetDepartment()
{
return await _departmentService.GetNoPageList(new DepartmentSearch());
}
}

+ 112
- 2
SafeCampus.API/SafeCampus.Web.Core/SafeCampus.Web.Core.xml Vedi File

@@ -385,6 +385,52 @@
</summary>
<returns></returns>
</member>
<member name="T:SafeCampus.Web.Core.Controllers.Application.Business.DepartmentController">
<summary>
系部管理接口
</summary>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.Business.DepartmentController.Add(SafeCampus.Application.Services.Business.DepartmentService.DepartmentDto)">
<summary>
添加
</summary>
<param name="input">添加参数</param>
<returns></returns>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.Business.DepartmentController.Update(SafeCampus.Application.Services.Business.DepartmentService.DepartmentDto)">
<summary>
修改
</summary>
<param name="input">添加参数</param>
<returns></returns>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.Business.DepartmentController.GetInfo(System.Int64)">
<summary>
获取详情
</summary>
<param name="id"></param>
<returns></returns>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.Business.DepartmentController.Delete(System.Collections.Generic.List{System.Int64})">
<summary>
删除
</summary>
<param name="id">id</param>
<returns></returns>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.Business.DepartmentController.GetPageList(SafeCampus.Application.Services.Business.DepartmentService.DepartmentSearch)">
<summary>
获取列表
</summary>
<returns></returns>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.Business.DepartmentController.GetNoPageList(SafeCampus.Application.Services.Business.DepartmentService.DepartmentSearch)">
<summary>
不分页获取列表
</summary>
<param name="search"></param>
<returns></returns>
</member>
<member name="T:SafeCampus.Web.Core.Controllers.Application.Business.DeviceApi">
<summary>
设备管理接口
@@ -470,7 +516,7 @@
</summary>
<returns></returns>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.Business.DfieldApi.QueryAll">
<member name="M:SafeCampus.Web.Core.Controllers.Application.Business.DfieldApi.QueryAll(System.Nullable{System.Int64})">
<summary>
查询底库列表
</summary>
@@ -791,6 +837,11 @@
结束时间
</summary>
</member>
<member name="P:SafeCampus.Web.Core.Controllers.Application.Business.ControllersNameInput.MagjorId">
<summary>
专业id
</summary>
</member>
<member name="P:SafeCampus.Web.Core.Controllers.Application.Business.PersonUnBindDfieInput.PersonId">
<summary>
人员id
@@ -882,6 +933,52 @@
<param name="info">删除信息</param>
<returns></returns>
</member>
<member name="T:SafeCampus.Web.Core.Controllers.Application.Business.MajorController">
<summary>
专业管理接口
</summary>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.Business.MajorController.Add(SafeCampus.Application.Services.Business.MajorService.MajorDto)">
<summary>
添加
</summary>
<param name="input">添加参数</param>
<returns></returns>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.Business.MajorController.Update(SafeCampus.Application.Services.Business.MajorService.MajorDto)">
<summary>
修改
</summary>
<param name="input">添加参数</param>
<returns></returns>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.Business.MajorController.GetInfo(System.Int64)">
<summary>
获取详情
</summary>
<param name="id"></param>
<returns></returns>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.Business.MajorController.Delete(System.Collections.Generic.List{System.Int64})">
<summary>
删除
</summary>
<param name="id">id</param>
<returns></returns>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.Business.MajorController.GetPageList(SafeCampus.Application.Services.Business.MajorService.MajorSearch)">
<summary>
获取列表
</summary>
<returns></returns>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.Business.MajorController.GetNoPageList(SafeCampus.Application.Services.Business.MajorService.MajorSearch)">
<summary>
获取列表不分页
</summary>
<param name="search"></param>
<returns></returns>
</member>
<member name="T:SafeCampus.Web.Core.Controllers.Application.Business.PassengerFlowApi">
<summary>
客流查询接口
@@ -1128,12 +1225,25 @@
</summary>
<returns></returns>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.LargeScreen.LargeScreenController.GetPersonSetNoPageList">
<member name="M:SafeCampus.Web.Core.Controllers.Application.LargeScreen.LargeScreenController.GetPersonSetNoPageList(System.Nullable{System.Int64})">
<summary>
获取班级列表
</summary>
<returns></returns>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.LargeScreen.LargeScreenController.GetMajorNoPageList(System.Nullable{System.Int64})">
<summary>
获取专业
</summary>
<param name="depId">院系id</param>
<returns></returns>
</member>
<member name="M:SafeCampus.Web.Core.Controllers.Application.LargeScreen.LargeScreenController.GetDepartment">
<summary>
获取院系
</summary>
<returns></returns>
</member>
<member name="P:SafeCampus.Web.Core.Controllers.Application.Violation.ReportExportInput.GroupCode">
<summary>
场景code


+ 1
- 1
SafeCampus.API/SafeCampus.Web.Entry/Properties/PublishProfiles/FolderProfile.pubxml.user Vedi File

@@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<Project>
<PropertyGroup>
<_PublishTargetUrl>F:\Project\QJKJ\SafeCampus\SafeCampus.API\SafeCampus.Web.Entry\bin\Release\net6.0\publish\</_PublishTargetUrl>
<History>True|2024-08-12T03:27:42.2864171Z;True|2024-08-09T14:54:42.9062124+08:00;True|2024-08-09T11:49:01.0339449+08:00;True|2024-08-09T11:43:21.9947939+08:00;True|2024-08-09T10:43:25.7641675+08:00;True|2024-08-08T15:23:17.0510180+08:00;True|2024-08-08T15:20:50.3450876+08:00;True|2024-08-08T11:06:43.0783261+08:00;True|2024-08-07T17:24:03.0780935+08:00;True|2024-08-07T17:20:50.6266614+08:00;True|2024-08-07T17:18:15.6367265+08:00;True|2024-08-06T17:31:40.3452266+08:00;True|2024-07-31T16:54:03.1890463+08:00;True|2024-07-30T17:11:33.2514194+08:00;True|2024-07-30T17:08:14.5888060+08:00;True|2024-07-30T09:56:08.6349163+08:00;True|2024-07-30T09:50:02.2368269+08:00;True|2024-07-29T16:20:12.3202393+08:00;True|2024-07-29T16:16:29.9634841+08:00;True|2024-07-29T16:09:51.7696392+08:00;True|2024-07-29T16:06:49.4145658+08:00;True|2024-07-29T15:58:50.6654249+08:00;True|2024-07-29T11:32:11.6206514+08:00;True|2024-07-29T11:26:26.1574563+08:00;True|2024-07-29T11:04:41.1896705+08:00;True|2024-07-29T10:38:38.4560275+08:00;True|2024-07-29T10:33:38.5288332+08:00;False|2024-07-29T10:33:21.0642261+08:00;False|2024-07-29T10:33:00.1005216+08:00;True|2024-07-29T09:54:59.2794860+08:00;True|2024-07-29T09:08:54.4899269+08:00;True|2024-07-26T18:02:13.5407348+08:00;True|2024-07-26T17:46:06.7922851+08:00;True|2024-07-26T15:50:48.6986834+08:00;True|2024-07-26T15:11:17.1696147+08:00;True|2024-07-26T13:58:49.6884964+08:00;True|2024-07-25T17:31:33.0050952+08:00;True|2024-07-25T17:09:12.7084910+08:00;True|2024-07-25T17:02:01.2617736+08:00;True|2024-07-25T16:59:51.6271873+08:00;True|2024-07-25T16:58:05.5249148+08:00;True|2024-07-25T14:14:10.2008367+08:00;False|2024-07-25T14:13:54.0300465+08:00;True|2024-07-25T14:08:57.0244482+08:00;True|2024-07-25T13:41:48.8201522+08:00;True|2024-07-25T10:41:30.7277553+08:00;True|2024-07-25T10:16:05.9105335+08:00;True|2024-07-24T15:31:54.7914854+08:00;True|2024-07-24T09:54:17.6182454+08:00;True|2024-07-23T17:01:18.1510211+08:00;True|2024-07-23T16:41:53.3366577+08:00;True|2024-07-23T16:07:25.4129335+08:00;True|2024-07-23T15:50:42.2437488+08:00;True|2024-07-23T15:19:00.1900116+08:00;True|2024-07-23T14:59:22.8551233+08:00;True|2024-07-23T14:19:55.1193373+08:00;True|2024-07-19T18:04:32.2703039+08:00;True|2024-07-19T15:56:25.4103701+08:00;True|2024-07-19T15:09:00.9662436+08:00;True|2024-07-19T15:05:35.7255851+08:00;True|2024-07-19T13:14:42.9559521+08:00;False|2024-07-19T11:37:52.4020673+08:00;True|2024-07-19T11:10:22.8661346+08:00;True|2024-07-19T11:00:00.8819251+08:00;True|2024-07-19T10:45:46.8271770+08:00;True|2024-07-19T10:45:03.8183458+08:00;True|2024-07-18T18:04:42.1000382+08:00;True|2024-07-18T18:01:51.3964409+08:00;True|2024-07-18T17:57:50.3509206+08:00;True|2024-07-18T16:32:46.2184830+08:00;True|2024-07-18T16:00:11.1381449+08:00;True|2024-07-18T15:11:52.6472758+08:00;True|2024-07-18T11:54:49.4848006+08:00;True|2024-07-18T09:25:58.7204846+08:00;True|2024-07-17T17:29:28.6175272+08:00;True|2024-07-17T17:10:54.5184246+08:00;True|2024-07-17T16:57:59.8174060+08:00;True|2024-07-17T16:18:13.8137834+08:00;True|2024-07-17T15:59:16.2360757+08:00;True|2024-07-17T15:31:41.9159909+08:00;True|2024-07-17T14:41:14.6127340+08:00;True|2024-07-17T14:28:53.4455461+08:00;True|2024-07-17T14:09:44.1826222+08:00;True|2024-07-17T13:57:12.3372528+08:00;True|2024-07-17T11:39:19.5754602+08:00;True|2024-07-16T17:44:10.6162562+08:00;True|2024-07-16T17:13:48.3928403+08:00;True|2024-07-16T17:00:47.7458109+08:00;True|2024-07-16T14:07:19.3463408+08:00;True|2024-07-15T16:05:13.3561511+08:00;True|2024-07-15T16:03:45.7866063+08:00;True|2024-07-15T13:25:00.0791938+08:00;True|2024-07-12T13:45:20.6945520+08:00;True|2024-07-12T13:07:01.3911178+08:00;False|2024-07-12T13:06:45.7048568+08:00;True|2024-07-12T13:06:03.7557254+08:00;False|2024-07-12T11:51:55.8228106+08:00;True|2024-07-12T09:11:11.9982410+08:00;True|2024-07-12T09:10:42.9689716+08:00;True|2024-07-12T09:08:04.7560729+08:00;</History>
<History>True|2024-08-19T05:38:29.9236695Z;False|2024-08-19T13:29:18.8873264+08:00;True|2024-08-19T12:31:57.9280692+08:00;True|2024-08-19T11:50:36.7241244+08:00;True|2024-08-19T10:24:05.0018377+08:00;True|2024-08-19T10:23:30.0445364+08:00;True|2024-08-19T10:12:33.8316906+08:00;True|2024-08-19T10:10:48.0967630+08:00;True|2024-08-16T12:17:51.5743944+08:00;True|2024-08-16T11:36:15.1880346+08:00;True|2024-08-12T11:27:42.2864171+08:00;True|2024-08-09T14:54:42.9062124+08:00;True|2024-08-09T11:49:01.0339449+08:00;True|2024-08-09T11:43:21.9947939+08:00;True|2024-08-09T10:43:25.7641675+08:00;True|2024-08-08T15:23:17.0510180+08:00;True|2024-08-08T15:20:50.3450876+08:00;True|2024-08-08T11:06:43.0783261+08:00;True|2024-08-07T17:24:03.0780935+08:00;True|2024-08-07T17:20:50.6266614+08:00;True|2024-08-07T17:18:15.6367265+08:00;True|2024-08-06T17:31:40.3452266+08:00;True|2024-07-31T16:54:03.1890463+08:00;True|2024-07-30T17:11:33.2514194+08:00;True|2024-07-30T17:08:14.5888060+08:00;True|2024-07-30T09:56:08.6349163+08:00;True|2024-07-30T09:50:02.2368269+08:00;True|2024-07-29T16:20:12.3202393+08:00;True|2024-07-29T16:16:29.9634841+08:00;True|2024-07-29T16:09:51.7696392+08:00;True|2024-07-29T16:06:49.4145658+08:00;True|2024-07-29T15:58:50.6654249+08:00;True|2024-07-29T11:32:11.6206514+08:00;True|2024-07-29T11:26:26.1574563+08:00;True|2024-07-29T11:04:41.1896705+08:00;True|2024-07-29T10:38:38.4560275+08:00;True|2024-07-29T10:33:38.5288332+08:00;False|2024-07-29T10:33:21.0642261+08:00;False|2024-07-29T10:33:00.1005216+08:00;True|2024-07-29T09:54:59.2794860+08:00;True|2024-07-29T09:08:54.4899269+08:00;True|2024-07-26T18:02:13.5407348+08:00;True|2024-07-26T17:46:06.7922851+08:00;True|2024-07-26T15:50:48.6986834+08:00;True|2024-07-26T15:11:17.1696147+08:00;True|2024-07-26T13:58:49.6884964+08:00;True|2024-07-25T17:31:33.0050952+08:00;True|2024-07-25T17:09:12.7084910+08:00;True|2024-07-25T17:02:01.2617736+08:00;True|2024-07-25T16:59:51.6271873+08:00;True|2024-07-25T16:58:05.5249148+08:00;True|2024-07-25T14:14:10.2008367+08:00;False|2024-07-25T14:13:54.0300465+08:00;True|2024-07-25T14:08:57.0244482+08:00;True|2024-07-25T13:41:48.8201522+08:00;True|2024-07-25T10:41:30.7277553+08:00;True|2024-07-25T10:16:05.9105335+08:00;True|2024-07-24T15:31:54.7914854+08:00;True|2024-07-24T09:54:17.6182454+08:00;True|2024-07-23T17:01:18.1510211+08:00;True|2024-07-23T16:41:53.3366577+08:00;True|2024-07-23T16:07:25.4129335+08:00;True|2024-07-23T15:50:42.2437488+08:00;True|2024-07-23T15:19:00.1900116+08:00;True|2024-07-23T14:59:22.8551233+08:00;True|2024-07-23T14:19:55.1193373+08:00;True|2024-07-19T18:04:32.2703039+08:00;True|2024-07-19T15:56:25.4103701+08:00;True|2024-07-19T15:09:00.9662436+08:00;True|2024-07-19T15:05:35.7255851+08:00;True|2024-07-19T13:14:42.9559521+08:00;False|2024-07-19T11:37:52.4020673+08:00;True|2024-07-19T11:10:22.8661346+08:00;True|2024-07-19T11:00:00.8819251+08:00;True|2024-07-19T10:45:46.8271770+08:00;True|2024-07-19T10:45:03.8183458+08:00;True|2024-07-18T18:04:42.1000382+08:00;True|2024-07-18T18:01:51.3964409+08:00;True|2024-07-18T17:57:50.3509206+08:00;True|2024-07-18T16:32:46.2184830+08:00;True|2024-07-18T16:00:11.1381449+08:00;True|2024-07-18T15:11:52.6472758+08:00;True|2024-07-18T11:54:49.4848006+08:00;True|2024-07-18T09:25:58.7204846+08:00;True|2024-07-17T17:29:28.6175272+08:00;True|2024-07-17T17:10:54.5184246+08:00;True|2024-07-17T16:57:59.8174060+08:00;True|2024-07-17T16:18:13.8137834+08:00;True|2024-07-17T15:59:16.2360757+08:00;True|2024-07-17T15:31:41.9159909+08:00;True|2024-07-17T14:41:14.6127340+08:00;True|2024-07-17T14:28:53.4455461+08:00;True|2024-07-17T14:09:44.1826222+08:00;True|2024-07-17T13:57:12.3372528+08:00;True|2024-07-17T11:39:19.5754602+08:00;True|2024-07-16T17:44:10.6162562+08:00;True|2024-07-16T17:13:48.3928403+08:00;True|2024-07-16T17:00:47.7458109+08:00;True|2024-07-16T14:07:19.3463408+08:00;True|2024-07-15T16:05:13.3561511+08:00;</History>
<LastFailureDetails />
</PropertyGroup>
</Project>

+ 14
- 3
SafeCampus.WEB/components.d.ts Vedi File

@@ -12,6 +12,7 @@ declare module 'vue' {
500: typeof import('./src/components/ErrorMessage/500.vue')['default']
CheckCard: typeof import('./src/components/CheckCard/index.vue')['default']
ChooseModule: typeof import('./src/components/ChooseModule/index.vue')['default']
ClassUserselector: typeof import('./src/components/Selectors/ClassUserselector/index.vue')['default']
CodeHighLight: typeof import('./src/components/CodeHighLight/index.vue')['default']
ColSetting: typeof import('./src/components/ProTable/components/ColSetting.vue')['default']
CropUpload: typeof import('./src/components/CropUpload/index.vue')['default']
@@ -19,13 +20,14 @@ declare module 'vue' {
ECharts: typeof import('./src/components/ECharts/index.vue')['default']
ElAside: typeof import('element-plus/es')['ElAside']
ElAutocomplete: typeof import('element-plus/es')['ElAutocomplete']
ElBadge: typeof import('element-plus/es')['ElBadge']
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
ElButton: typeof import('element-plus/es')['ElButton']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCol: typeof import('element-plus/es')['ElCol']
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDivider: typeof import('element-plus/es')['ElDivider']
ElDrawer: typeof import('element-plus/es')['ElDrawer']
@@ -38,14 +40,21 @@ declare module 'vue' {
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElImage: typeof import('element-plus/es')['ElImage']
ElInput: typeof import('element-plus/es')['ElInput']
ElLink: typeof import('element-plus/es')['ElLink']
ElMain: typeof import('element-plus/es')['ElMain']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSlider: typeof import('element-plus/es')['ElSlider']
ElSpace: typeof import('element-plus/es')['ElSpace']
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
@@ -54,9 +63,11 @@ declare module 'vue' {
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
ElText: typeof import('element-plus/es')['ElText']
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTree: typeof import('element-plus/es')['ElTree']
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
ElUpload: typeof import('element-plus/es')['ElUpload']
ESign: typeof import('./src/components/ESign/index.vue')['default']
FormContainer: typeof import('./src/components/Form/FormContainer/index.vue')['default']
Grid: typeof import('./src/components/Grid/index.vue')['default']


+ 1
- 0
SafeCampus.WEB/package.json Vedi File

@@ -52,6 +52,7 @@
"nprogress": "^0.2.0",
"pinia": "^2.1.7",
"pinia-plugin-persistedstate": "^3.2.1",
"pinyin-pro": "^3.24.2",
"print-js": "^1.6.0",
"qs": "^6.11.2",
"screenfull": "^6.0.2",


+ 33
- 25
SafeCampus.WEB/pnpm-lock.yaml Vedi File

@@ -56,6 +56,9 @@ importers:
pinia-plugin-persistedstate:
specifier: ^3.2.1
version: 3.2.1(pinia@2.1.7(typescript@5.3.3)(vue@3.4.21(typescript@5.3.3)))
pinyin-pro:
specifier: ^3.24.2
version: 3.24.2
print-js:
specifier: ^1.6.0
version: 1.6.0
@@ -167,7 +170,7 @@ importers:
version: 3.2.5
rollup-plugin-visualizer:
specifier: ^5.12.0
version: 5.12.0(rollup@4.6.1)
version: 5.12.0(rollup@2.79.1)
sass:
specifier: ^1.71.1
version: 1.71.1
@@ -203,16 +206,16 @@ importers:
version: 5.3.3
unocss:
specifier: ^0.58.5
version: 0.58.5(postcss@8.4.35)(rollup@4.6.1)(vite@5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2))
version: 0.58.5(postcss@8.4.35)(rollup@2.79.1)(vite@5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2))
unplugin-auto-import:
specifier: ^0.17.5
version: 0.17.5(@vueuse/core@10.9.0(vue@3.4.21(typescript@5.3.3)))(rollup@4.6.1)
version: 0.17.5(@vueuse/core@10.9.0(vue@3.4.21(typescript@5.3.3)))(rollup@2.79.1)
unplugin-icons:
specifier: ^0.18.5
version: 0.18.5(@vue/compiler-sfc@3.4.21)(vue-template-compiler@2.7.14)
unplugin-vue-components:
specifier: ^0.26.0
version: 0.26.0(@babel/parser@7.24.0)(rollup@4.6.1)(vue@3.4.21(typescript@5.3.3))
version: 0.26.0(@babel/parser@7.24.0)(rollup@2.79.1)(vue@3.4.21(typescript@5.3.3))
unplugin-vue-setup-extend-plus:
specifier: ^1.0.1
version: 1.0.1
@@ -4090,6 +4093,9 @@ packages:
typescript:
optional: true

pinyin-pro@3.24.2:
resolution: {integrity: sha512-5tPyLhxT4CZ9dWqQRqm3X5ADdS18Sb2w0ranNBgr6jCrqO4O8gtfuyqG7Y6+1Mre+0n2VlhKDz+3P5oqSLrkOw==}

pkcs7@0.2.3:
resolution: {integrity: sha512-kJRwmADEQUg+qJyRgWLtpEL9q9cFjZschejTEK3GRjKvnsU9G5WWoe/wKqRgbBoqWdVSeTUKP6vIA3Y72M3rWA==}
engines: {node: ^0.10, npm: ^1.4.6}
@@ -6867,13 +6873,13 @@ snapshots:
estree-walker: 2.0.2
picomatch: 2.3.1

'@rollup/pluginutils@5.1.0(rollup@4.6.1)':
'@rollup/pluginutils@5.1.0(rollup@2.79.1)':
dependencies:
'@types/estree': 1.0.0
estree-walker: 2.0.2
picomatch: 2.3.1
optionalDependencies:
rollup: 4.6.1
rollup: 2.79.1

'@rollup/rollup-android-arm-eabi@4.6.1':
optional: true
@@ -7073,20 +7079,20 @@ snapshots:

'@ungap/structured-clone@1.2.0': {}

'@unocss/astro@0.58.5(rollup@4.6.1)(vite@5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2))':
'@unocss/astro@0.58.5(rollup@2.79.1)(vite@5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2))':
dependencies:
'@unocss/core': 0.58.5
'@unocss/reset': 0.58.5
'@unocss/vite': 0.58.5(rollup@4.6.1)(vite@5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2))
'@unocss/vite': 0.58.5(rollup@2.79.1)(vite@5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2))
optionalDependencies:
vite: 5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2)
transitivePeerDependencies:
- rollup

'@unocss/cli@0.58.5(rollup@4.6.1)':
'@unocss/cli@0.58.5(rollup@2.79.1)':
dependencies:
'@ampproject/remapping': 2.2.1
'@rollup/pluginutils': 5.1.0(rollup@4.6.1)
'@rollup/pluginutils': 5.1.0(rollup@2.79.1)
'@unocss/config': 0.58.5
'@unocss/core': 0.58.5
'@unocss/preset-uno': 0.58.5
@@ -7210,10 +7216,10 @@ snapshots:
dependencies:
'@unocss/core': 0.58.5

'@unocss/vite@0.58.5(rollup@4.6.1)(vite@5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2))':
'@unocss/vite@0.58.5(rollup@2.79.1)(vite@5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2))':
dependencies:
'@ampproject/remapping': 2.2.1
'@rollup/pluginutils': 5.1.0(rollup@4.6.1)
'@rollup/pluginutils': 5.1.0(rollup@2.79.1)
'@unocss/config': 0.58.5
'@unocss/core': 0.58.5
'@unocss/inspector': 0.58.5
@@ -9901,6 +9907,8 @@ snapshots:
optionalDependencies:
typescript: 5.3.3

pinyin-pro@3.24.2: {}

pkcs7@0.2.3: {}

pkcs7@1.0.4:
@@ -10176,14 +10184,14 @@ snapshots:
serialize-javascript: 4.0.0
terser: 5.19.2

rollup-plugin-visualizer@5.12.0(rollup@4.6.1):
rollup-plugin-visualizer@5.12.0(rollup@2.79.1):
dependencies:
open: 8.4.2
picomatch: 2.3.1
source-map: 0.7.4
yargs: 17.7.1
optionalDependencies:
rollup: 4.6.1
rollup: 2.79.1

rollup@0.25.8:
dependencies:
@@ -10905,9 +10913,9 @@ snapshots:

unicorn-magic@0.1.0: {}

unimport@3.7.1(rollup@4.6.1):
unimport@3.7.1(rollup@2.79.1):
dependencies:
'@rollup/pluginutils': 5.1.0(rollup@4.6.1)
'@rollup/pluginutils': 5.1.0(rollup@2.79.1)
acorn: 8.11.2
escape-string-regexp: 5.0.0
estree-walker: 3.0.3
@@ -10936,10 +10944,10 @@ snapshots:

universalify@2.0.0: {}

unocss@0.58.5(postcss@8.4.35)(rollup@4.6.1)(vite@5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2)):
unocss@0.58.5(postcss@8.4.35)(rollup@2.79.1)(vite@5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2)):
dependencies:
'@unocss/astro': 0.58.5(rollup@4.6.1)(vite@5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2))
'@unocss/cli': 0.58.5(rollup@4.6.1)
'@unocss/astro': 0.58.5(rollup@2.79.1)(vite@5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2))
'@unocss/cli': 0.58.5(rollup@2.79.1)
'@unocss/core': 0.58.5
'@unocss/extractor-arbitrary-variants': 0.58.5
'@unocss/postcss': 0.58.5(postcss@8.4.35)
@@ -10957,7 +10965,7 @@ snapshots:
'@unocss/transformer-compile-class': 0.58.5
'@unocss/transformer-directives': 0.58.5
'@unocss/transformer-variant-group': 0.58.5
'@unocss/vite': 0.58.5(rollup@4.6.1)(vite@5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2))
'@unocss/vite': 0.58.5(rollup@2.79.1)(vite@5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2))
optionalDependencies:
vite: 5.1.4(@types/node@20.14.10)(sass@1.71.1)(terser@5.19.2)
transitivePeerDependencies:
@@ -10965,15 +10973,15 @@ snapshots:
- rollup
- supports-color

unplugin-auto-import@0.17.5(@vueuse/core@10.9.0(vue@3.4.21(typescript@5.3.3)))(rollup@4.6.1):
unplugin-auto-import@0.17.5(@vueuse/core@10.9.0(vue@3.4.21(typescript@5.3.3)))(rollup@2.79.1):
dependencies:
'@antfu/utils': 0.7.7
'@rollup/pluginutils': 5.1.0(rollup@4.6.1)
'@rollup/pluginutils': 5.1.0(rollup@2.79.1)
fast-glob: 3.3.2
local-pkg: 0.5.0
magic-string: 0.30.5
minimatch: 9.0.3
unimport: 3.7.1(rollup@4.6.1)
unimport: 3.7.1(rollup@2.79.1)
unplugin: 1.7.1
optionalDependencies:
'@vueuse/core': 10.9.0(vue@3.4.21(typescript@5.3.3))
@@ -10995,10 +11003,10 @@ snapshots:
transitivePeerDependencies:
- supports-color

unplugin-vue-components@0.26.0(@babel/parser@7.24.0)(rollup@4.6.1)(vue@3.4.21(typescript@5.3.3)):
unplugin-vue-components@0.26.0(@babel/parser@7.24.0)(rollup@2.79.1)(vue@3.4.21(typescript@5.3.3)):
dependencies:
'@antfu/utils': 0.7.6
'@rollup/pluginutils': 5.1.0(rollup@4.6.1)
'@rollup/pluginutils': 5.1.0(rollup@2.79.1)
chokidar: 3.5.3
debug: 4.3.4
fast-glob: 3.3.1


+ 34
- 0
SafeCampus.WEB/src/api/interface/sys/usermanage/department.ts Vedi File

@@ -0,0 +1,34 @@
/**
* @description 用户管理接口
* @license Apache License Version 2.0
* @Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
* @remarks
* SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
* 1.请不要删除和修改根目录下的LICENSE文件。
* 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
* 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
* 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
* 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。
* 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关
*/

import { ReqPage } from "@/api";
/**
* @Description: 院系管理接口
* @Author: wwp
* @Date: 2024-07-24 15:34:54
*/

export namespace SysDepartment {
// 院系信息
export interface DepartmentInfo {
id?: string | number | undefined;
name?: string | undefined;
code?: string | undefined;
introduce?: string | undefined;
depId?: string | number | undefined;
departmentName?: string | undefined;
}
// 院系列表传参
export interface Page extends ReqPage {}
}

+ 2
- 0
SafeCampus.WEB/src/api/interface/sys/usermanage/index.ts Vedi File

@@ -15,3 +15,5 @@
export * from "./personnel";
export * from "./clothing";
export * from "./dormitory";
export * from "./department";
export * from "./major";

+ 35
- 0
SafeCampus.WEB/src/api/interface/sys/usermanage/major.ts Vedi File

@@ -0,0 +1,35 @@
/**
* @description 用户管理接口
* @license Apache License Version 2.0
* @Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
* @remarks
* SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
* 1.请不要删除和修改根目录下的LICENSE文件。
* 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
* 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
* 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
* 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。
* 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关
*/

import { ReqPage } from "@/api";
/**
* @Description: 专业管理接口
* @Author: wwp
* @Date: 2024-07-24 15:34:54
*/

export namespace SysMajor {
// 院系信息
export interface MajorInfo {
id?: string | number | undefined;
name?: string | undefined;
code?: string | undefined;
introduce?: string | undefined;
depId?: string | number | undefined;
departmentName?: string | undefined;
sort?: string | number | undefined;
}
// 院系列表传参
export interface Page extends ReqPage {}
}

+ 4
- 0
SafeCampus.WEB/src/api/interface/sys/usermanage/personnel.ts Vedi File

@@ -33,6 +33,8 @@ export namespace SysUserPersonnel {
userId?: string | number | undefined;
personId?: string | number | undefined;
userName?: string | number | undefined;
majorId?: any;
majorName?: any;
}
/** 人脸信息 */
export interface SysUserAvatar {
@@ -68,5 +70,7 @@ export namespace SysUserPersonnel {
personSets: any;
personSetId?: number | string;
status?: number | string;
depId?: any;
majorId?: any;
}
}

+ 2
- 2
SafeCampus.WEB/src/api/modules/usermanage/classManage.ts Vedi File

@@ -23,8 +23,8 @@ const http = moduleRequest("/business/dfieldApi/");
*/
const userManageClassManageApi = {
/** 查询底库列表 */
page() {
return http.get("queryAll");
page(params: SysUserPersonnel.ClassPage) {
return http.get("queryAll", params);
},
/** 删除底库 */
delete(params: ReqId) {


+ 60
- 0
SafeCampus.WEB/src/api/modules/usermanage/department.ts Vedi File

@@ -0,0 +1,60 @@
/**
* @description 单页管理接口
* @license Apache License Version 2.0
* @Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
* @remarks
* SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
* 1.请不要删除和修改根目录下的LICENSE文件。
* 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
* 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
* 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
* 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。
* 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关
* @see https://gitee.com/dotnetmoyu/SimpleAdmin
*/
import { moduleRequest } from "@/api/request";
import { ReqId, ResPage, ReqPersonId, SysDepartment } from "@/api/interface";
const http = moduleRequest("/business/department/");

/**
* @Description: 单页管理
* @Author: wwp
* @Date: 2023-12-15 15:34:54
*/
const userManageDepartmentApi = {
// 获取院系分页列表
page(params: SysDepartment.Page) {
return http.get("getPageList", params);
},
/** 新增院系 */
add(params: SysDepartment.DepartmentInfo) {
return http.post("add", params);
},
/** 修改院系 */
update(params: SysDepartment.DepartmentInfo) {
return http.put("update", params);
},
/** 删除院系 */
delete(params: ReqId) {
return http.post("delete", params);
},
// 院系详情
detail(params: ReqId) {
return http.get("getInfo", params);
},
/**院系列表(不分页)*/
list(params: any) {
return http.get("getNoPageList", params);
}
};

const departmentButtonCode = {
/** 新增院系 */
add: "userManageDepartmentAdd",
/** 删除院系 */
edit: "userManageDepartmentEdit",
/** 删除院系 */
delete: "userManageDepartmentDelete"
};

export { userManageDepartmentApi, departmentButtonCode };

+ 2
- 0
SafeCampus.WEB/src/api/modules/usermanage/index.ts Vedi File

@@ -18,3 +18,5 @@ export * from "./clothing";
export * from "./teacher";
export * from "./keyPersonnel";
export * from "./dormitory";
export * from "./department";
export * from "./major";

+ 60
- 0
SafeCampus.WEB/src/api/modules/usermanage/major.ts Vedi File

@@ -0,0 +1,60 @@
/**
* @description 单页管理接口
* @license Apache License Version 2.0
* @Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
* @remarks
* SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
* 1.请不要删除和修改根目录下的LICENSE文件。
* 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
* 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
* 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
* 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。
* 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关
* @see https://gitee.com/dotnetmoyu/SimpleAdmin
*/
import { moduleRequest } from "@/api/request";
import { ReqId, ResPage, ReqPersonId, SysMajor } from "@/api/interface";
const http = moduleRequest("/business/major/");

/**
* @Description: 单页管理
* @Author: wwp
* @Date: 2023-12-15 15:34:54
*/
const userManageMajorApi = {
// 获取专业分页列表
page(params: SysMajor.Page) {
return http.get("getPageList", params);
},
/** 新增专业 */
add(params: SysMajor.MajorInfo) {
return http.post("add", params);
},
/** 修改专业 */
update(params: SysMajor.MajorInfo) {
return http.put("update", params);
},
/** 删除专业 */
delete(params: ReqId) {
return http.post("delete", params);
},
// 专业详情
detail(params: ReqId) {
return http.get("getInfo", params);
},
/**专业列表(不分页)*/
list(params: any) {
return http.get("getNoPageList", params);
}
};

const majorButtonCode = {
/** 新增专业 */
add: "userManageMajorAdd",
/** 删除专业 */
edit: "userManageMajorEdit",
/** 删除专业 */
delete: "userManageMajorDelete"
};

export { userManageMajorApi, majorButtonCode };

+ 21
- 0
SafeCampus.WEB/src/mixin/index.ts Vedi File

@@ -0,0 +1,21 @@
import { userManageClassManageApi, userManageMajorApi, userManageDepartmentApi } from "@/api";

// 获取专业列表
const getMajorList = async (depId: any) => {
const res: any = await userManageMajorApi.list({ depId });
return res.data;
};
/* 获取系部 */

const getDepartmentList = async () => {
const res: any = await userManageDepartmentApi.list({});
return res.data;
};
/* 获取所属班级 */

const getClassList = async (majorId: any) => {
const res: any = await userManageClassManageApi.page({ majorId });
return res.data;
};

export { getMajorList, getDepartmentList, getClassList };

+ 26
- 3
SafeCampus.WEB/src/utils/index.ts Vedi File

@@ -327,7 +327,7 @@ export function findItemNested(enumData: any, callValue: any, value: string, chi
/**
* @description 时间戳转化为日期
* */
export function formatDate(timestamp:number) {
export function formatDate(timestamp: number) {
let date = new Date(timestamp);
let year = date.getFullYear();
let month = "0" + (date.getMonth() + 1); // getMonth返回的月份是从0开始的
@@ -336,6 +336,29 @@ export function formatDate(timestamp:number) {
let minutes = "0" + date.getMinutes();
let seconds = "0" + date.getSeconds();

return year + "-" + month.substr(-2) + "-" + day.substr(-2)
+ " " + hours.substr(-2) + ":" + minutes.substr(-2) + ":" + seconds.substr(-2);
return year + "-" + month.substr(-2) + "-" + day.substr(-2) + " " + hours.substr(-2) + ":" + minutes.substr(-2) + ":" + seconds.substr(-2);
}

/**
* 日期格式化
*/
export function dateFormat(date: any, format: any) {
format = format || "yyyy-MM-dd hh:mm:ss";
if (date !== "Invalid Date") {
let o: any = {
"M+": date.getMonth() + 1, //month
"d+": date.getDate(), //day
"h+": date.getHours(), //hour
"m+": date.getMinutes(), //minute
"s+": date.getSeconds(), //second
"q+": Math.floor((date.getMonth() + 3) / 3), //quarter
S: date.getMilliseconds() //millisecond
};
if (/(y+)/.test(format)) format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
for (let k in o)
if (new RegExp("(" + k + ")").test(format))
format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
return format;
}
return "";
}

+ 81
- 12
SafeCampus.WEB/src/views/attendance/behaviorTrace/index.vue Vedi File

@@ -5,7 +5,7 @@
-->
<template>
<div class="main-box">
<TreeFilter
<!-- <TreeFilter
ref="treeFilter"
label="personSetName"
id="personSetId"
@@ -22,7 +22,7 @@
<span>{{ row.node.label }}</span>
</span>
</template>
</TreeFilter>
</TreeFilter> -->
<div class="table-box">
<ProTable ref="proTable" title="人员管理" :columns="columns" rowKey="personId" :request-api="userManagePersonnelApi.page">
<!-- 表格操作栏 -->
@@ -44,19 +44,84 @@
</div>
</template>
<script setup lang="tsx" name="SysUserPersonnel">
import { userManagePersonnelApi,SysUserPersonnel,userManageClassManageApi,userManageTeacherApi } from "@/api";
import { userManagePersonnelApi,SysUserPersonnel } from "@/api";
import { getMajorList, getDepartmentList, getClassList } from "@/mixin";
import { FormOptEnum } from "@/enums";
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
import TreeFilter from "@/components/TreeFilter/index.vue";
import { useUserStore } from "@/stores/modules";
import TraceShow from "./components/traceShow/index.vue";
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
const faceUrl = ref('');
const visible = ref(false); //预览头像
const proTable = ref<ProTableInstance>();
const treeFilter = ref<InstanceType<typeof TreeFilter> | null>(null);
const departmentOptions = ref<any>([])
const majorOptions = ref<any>([])
const classOptions = ref<any>([])
//监听depId/majorId变化
watch(
() => [proTable.value!?.searchParam?.depId,proTable.value!?.searchParam?.majorId],
async ([newDepId,newMajorId],[oldDepId,oldMajorId]) => {
if(newDepId !== oldDepId){
majorOptions.value =await getMajorList(newDepId)
classOptions.value = [];
proTable.value!.searchParam.majorId = "";
proTable.value!.searchParam.personSetId = ""
}
if(newMajorId !== oldMajorId){
classOptions.value = await getClassList(newMajorId)
}
} ,{ deep: true, immediate: false }
);
// 表格配置项
const columns: ColumnProps<SysUserPersonnel.SysUserPerInfo>[] = [
{
prop: "depId",
label: "所属系部",
enum: departmentOptions,
fieldNames: { label: "name", value: "id" },
search: {
el: "select",
span:1,
props: {
clearable: false,
placeholder: "请选择系部",
},
},
isShow: false
},
{
prop: "majorId",
label: "所属专业",
enum: majorOptions,
fieldNames: { label: "name", value: "id" },
search: {
el: "select",
span:1,
props: {
clearable: false,
placeholder: "请选择专业",
},
},
isShow: false
},
{
prop: "personSetId",
label: "所属班级",
enum: classOptions,
fieldNames: { label: "personSetName", value: "personSetId" },
search: {
el: "select",
span:1,
props: {
clearable: false,
placeholder: "请选择所属班级",
},
},
isShow: false
},
{
prop: "faceUrl",
label: "人脸",
@@ -99,26 +164,30 @@ const RefreshTable = () => {
}

/** 部门切换 */
const personSetId = ref<number | string>()
function changeTreeFilter(val: number | string) {
personSetId.value = val
proTable.value!.pageable.pageNum = 1;
proTable.value!.searchParam.personSetId = val;
proTable.value!.search();
}
// const personSetId = ref<number | string>()
// function changeTreeFilter(val: number | string) {
// personSetId.value = val
// proTable.value!.pageable.pageNum = 1;
// proTable.value!.searchParam.personSetId = val;
// proTable.value!.search();
// }
const detialRef = ref<InstanceType<typeof TraceShow> | null>(null);
/**
* 详情
* @param opt 操作类型
* @param record 弹框数据
*/
function onOpenDetail(opt: FormOptEnum, record: {} | AttendanceStudentsReturn.studentsReturnInfo = {}) {
function onOpenDetail(opt: FormOptEnum, record: {}) {
switch (opt) {
case FormOptEnum.VIEW:
detialRef.value?.onOpen({ opt: opt, record: record, successful: RefreshTable });
break;
}
}
onMounted(async () => {
// 获取系部下拉数据
departmentOptions.value = await getDepartmentList()
});
</script>
<style scoped lang="scss">
.table-box {


+ 40
- 21
SafeCampus.WEB/src/views/attendance/roolcall/components/form/index.vue Vedi File

@@ -32,15 +32,22 @@
</s-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<s-form-item label="所属系部" prop="depId">
<s-select v-model="sysUserProps.record.depId" :options="departmentOptions" label="name" value="id"></s-select
></s-form-item>
</el-col>
<el-col :span="12">
<s-form-item label="所属专业" prop="majorId">
<s-select v-model="sysUserProps.record.majorId" :options="majorOptions" label="name" value="id"></s-select>
</s-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<s-form-item label="所属班级" prop="personSetId">
<s-select
v-model="sysUserProps.record.personSetId"
:options="sysUserProps.treeAllData"
label="personSetName"
value="personSetId"
></s-select>
<s-select v-model="sysUserProps.record.personSetId" :options="classOptions" label="personSetName" value="personSetId"></s-select>
</s-form-item>
</el-col>
<el-col :span="12">
@@ -67,10 +74,15 @@
</template>

<script setup lang="ts" name="SysUserPersonnelForm">
import { attendanceRoolcallApi, userManagePersonnelApi, monitorLIVEApi } from "@/api";
import { attendanceRoolcallApi, monitorLIVEApi } from "@/api";
import { required } from "@/utils/formRules";
import { FormInstance } from "element-plus";
import { getMajorList, getDepartmentList, getClassList } from "@/mixin";
const visible = ref(false); //是否显示表单
const CameraList = ref<any>([]);
const departmentOptions = ref<any>([]);
const majorOptions = ref<any>([]);
const classOptions = ref<any>([]);
/** 表单操作类型枚举 */
enum FormOptEnums {
/** 发起 */
@@ -80,10 +92,8 @@ enum FormOptEnums {
const sysUserProps = reactive<FormProps.Base<any>>({
opt: FormOptEnums.INITIATE,
record: {},
treeAllData: [],
disabled: false
});
const CameraList = ref<any>([]);

// 表单验证规则
const rules = reactive({
@@ -91,26 +101,35 @@ const rules = reactive({
similarity: [required("请选择相似度")],
cameraId: [required("请选择摄像头")],
continueTime: [required("请选择持续时间")],
personSetId: [required("请选择所属班级")]
personSetId: [required("请选择所属班级")],
depId: [required("请选择系部")],
majorId: [required("请选择专业")]
});

/**
* 打开表单
* @param props 表单参数
*/
function onOpen(props: FormProps.Base<any>) {
async function onOpen(props: FormProps.Base<any>) {
departmentOptions.value = await getDepartmentList();
Object.assign(sysUserProps, props); //合并参数
if (props.opt == FormOptEnums.INITIATE) {
//如果是新增,设置默认值
// sysUserProps.record.sortCode = 99;
}
visible.value = true; //显示表单
if (props.record.personId) {
//如果传了id,就去请求api获取record
userManagePersonnelApi.detail({ id: props.record.personId }).then((res: any) => {
sysUserProps.record = res.data;
});
}
/* 监听系部、专业 */
watch(
() => [sysUserProps.record?.depId, sysUserProps.record?.majorId],
async ([newDepId, newMajorId], [oldDepId, oldMajorId]) => {
if (newDepId != oldDepId) {
majorOptions.value = await getMajorList(newDepId);
classOptions.value = [];
sysUserProps.record.personSetId = "";
sysUserProps.record.majorId = "";
}
if (newMajorId && newMajorId != oldMajorId) {
classOptions.value = await getClassList(newMajorId);
}
},
{ deep: true, immediate: false }
);
}

const handleChange = async (val: any, data: any) => {


+ 76
- 35
SafeCampus.WEB/src/views/attendance/roolcall/index.vue Vedi File

@@ -5,27 +5,11 @@
-->
<template>
<div class="main-box">
<TreeFilter
ref="treeFilter"
label="personSetName"
id="personSetId"
width="300px"
title="班级管理"
:show-all="true"
:request-api="userManageClassManageApi.page"
@change="changeTreeFilter"
>
<template v-slot:label="{ row }">
<span class="custom-tree-node">
<span>{{ row.node.label }} {{ row.node.userName ? `(${row.node.userName})` : "" }}</span>
</span>
</template>
</TreeFilter>
<div class="table-box">
<ProTable ref="proTable" title="任务列表" :columns="columns" rowKey="id" :request-api="attendanceRoolcallApi.getTaskPageList">
<!-- 表格 header 按钮 -->
<template #tableHeader="scope">
<s-button :opt="FormOptEnums.INITIATE" @click="onOpen(FormOptEnums.INITIATE, { personSetId: personSetId }, treeFilter.treeAllData)" />
<s-button :opt="FormOptEnums.INITIATE" @click="onOpen(FormOptEnums.INITIATE, {})" />
<s-button
type="danger"
:opt="FormOptEnum.DELETE"
@@ -49,15 +33,36 @@
</div>
</template>
<script setup lang="tsx" name="SysUserPersonnel">
import { attendanceRoolcallApi,userManageClassManageApi} from "@/api";
import { attendanceRoolcallApi} from "@/api";
import { getMajorList, getDepartmentList, getClassList } from "@/mixin";
import { useHandleData } from "@/hooks/useHandleData";
import { FormOptEnum } from "@/enums";
import Form from "./components/form/index.vue";
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
import TreeFilter from "@/components/TreeFilter/index.vue";
import { useRouter } from "vue-router";
const router = useRouter();

// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
const proTable = ref<ProTableInstance>();
const departmentOptions = ref<any>([])
const majorOptions = ref<any>([])
const classOptions = ref<any>([])
//监听depId/majorId变化
watch(
() => [proTable.value!?.searchParam?.depId,proTable.value!?.searchParam?.majorId],
async ([newDepId,newMajorId],[oldDepId,oldMajorId]) => {
if(newDepId !== oldDepId){
majorOptions.value =await getMajorList(newDepId)
classOptions.value = [];
proTable.value!.searchParam.majorId = "";
proTable.value!.searchParam.personSetId = ""
}
if(newMajorId !== oldMajorId){
classOptions.value = await getClassList(newMajorId)
}
} ,{ deep: true, immediate: false }
);
/** 表单操作类型枚举 */
enum FormOptEnums {
/** 发起 */
@@ -68,13 +73,54 @@ enum FormOptEnums {
EDITTASK = "修改点名记录"
}

// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
const visible = ref(false); //是否显示人员表单
const proTable = ref<ProTableInstance>();
const treeFilter = ref<any>();
// 表格配置项
const columns: ColumnProps[] = [
{ type: "selection", fixed: "left", width: 50 },
{
prop: "depId",
label: "所属系部",
enum: departmentOptions,
fieldNames: { label: "name", value: "id" },
search: {
el: "select",
span:1,
props: {
clearable: false,
placeholder: "请选择系部",
},
},
isShow: false
},
{
prop: "majorId",
label: "所属专业",
enum: majorOptions,
fieldNames: { label: "name", value: "id" },
search: {
el: "select",
span:1,
props: {
clearable: false,
placeholder: "请选择专业",
},
},
isShow: false
},
{
prop: "personSetId",
label: "所属班级",
enum: classOptions,
fieldNames: { label: "personSetName", value: "personSetId" },
search: {
el: "select",
span:1,
props: {
clearable: false,
placeholder: "请选择所属班级",
},
},
isShow: false
},
{
prop: "cameraName",
label: "摄像头名称"
@@ -106,8 +152,8 @@ const formRef = ref<InstanceType<typeof Form> | null>(null);
* @param opt 操作类型
* @param record 记录
*/
function onOpen(opt: FormOptEnums, record: {},treeAllData:any) {
formRef.value?.onOpen({ opt: opt, record: record,treeAllData:treeAllData, successful: RefreshTable });
function onOpen(opt: FormOptEnums, record: {}) {
formRef.value?.onOpen({ opt: opt, record: record, successful: RefreshTable });
}


@@ -133,15 +179,10 @@ const formRef = ref<InstanceType<typeof Form> | null>(null);
const RefreshTable = () => {
proTable.value?.refresh();
}

/** 班级切换 */
const personSetId = ref<number | string>()
function changeTreeFilter(val: number | string) {
personSetId.value = val
proTable.value!.pageable.pageNum = 1;
proTable.value!.searchParam.personSetId = val;
proTable.value!.search();
}
onMounted(async () => {
// 获取系部下拉数据
departmentOptions.value = await getDepartmentList()
});
</script>
<style scoped lang="scss">
.table-box {


+ 1
- 1
SafeCampus.WEB/src/views/login/index.vue Vedi File

@@ -62,7 +62,7 @@ interface LoginProps {

//默认值
const props = reactive<LoginProps>({
sysName: "校园监控智能分析平台",
sysName: "AI监控预警分析平台",
sysVersion: "",
sysLogo: "",
sysTenantOption: TenantEnum.CLOSE,


+ 4
- 0
SafeCampus.WEB/src/views/monitor/live/index.vue Vedi File

@@ -257,10 +257,14 @@ const append = (type: string, data: Tree) => {
groupVisible.value = true;
groupFormType.value = type
if (type == "edit") {
groupTitle.value = "编辑分组";
groupForm.name = data.name;
groupForm.id = data.id;
} else if(type == "addChild") {
groupTitle.value = "新增分组";
groupForm.parentId = data.id
} else {
groupTitle.value = "新增分组";
}
};
// 删除分组


SafeCampus.WEB/src/views/userManage/personnel/components/formClass/index.vue → SafeCampus.WEB/src/views/userManage/classManage/components/formClass/index.vue Vedi File

@@ -18,6 +18,9 @@
<div>
<el-row :gutter="16">
<el-col :span="22">
<s-form-item label="所属专业" prop="majorId">
<s-select v-model="sysUserProps.record.majorId" :options="majorIdData" label="name" value="id"></s-select>
</s-form-item>
<s-form-item label="班级名称" prop="personSetName">
<s-input v-model="sysUserProps.record.personSetName"></s-input>
</s-form-item>
@@ -35,12 +38,13 @@

<script setup lang="ts" name="SysUserPerformClass">
import { ref } from "vue";
import { SysUserPersonnel, userManageClassManageApi } from "@/api";
import { SysUserPersonnel, userManageClassManageApi, userManageMajorApi } from "@/api";
import { FormOptEnum } from "@/enums";
import { required } from "@/utils/formRules";
import { FormInstance } from "element-plus";

const visibleClass = ref(false); //是否显示表单
const majorIdData = ref<any>([]); //专业数据
// 表单参数
const sysUserProps = reactive<FormProps.Base<SysUserPersonnel.ClassPage>>({
opt: FormOptEnum.ADD,
@@ -49,6 +53,7 @@ const sysUserProps = reactive<FormProps.Base<SysUserPersonnel.ClassPage>>({
});
// 表单验证规则
const rules = reactive({
majorId: [required("请选择专业")],
personSetName: [required("请输入班级名称")]
});

@@ -59,9 +64,17 @@ const rules = reactive({
function onOpen(props: FormProps.Base<SysUserPersonnel.ClassPage>) {
Object.assign(sysUserProps, props); //合并参数
visibleClass.value = true; //显示表单
sysUserProps.record = props.record;
getRequestData(() => {
sysUserProps.record = props.record;
}); //获取专业数据
}

/* 获取专业数据 */
const getRequestData = async (callback: Function | null = null) => {
const { data } = await userManageMajorApi.list({});
majorIdData.value = data;
if (callback) callback;
};
// 提交数据(新增/编辑)
const sysUserFormRef = ref<FormInstance>();
/** 提交表单 */

SafeCampus.WEB/src/views/userManage/personnel/components/formTeacher/index.vue → SafeCampus.WEB/src/views/userManage/classManage/components/formTeacher/index.vue Vedi File

@@ -62,15 +62,17 @@ const rules = reactive({
* @param props 表单参数
*/
function onOpen(props: FormProps.Base<SysUserPersonnel.ClassPage>) {
getRequestData();
Object.assign(sysUserProps, props); //合并参数
visibleClass.value = true; //显示表单
sysUserProps.record = props.record;
getRequestData(() => {
Object.assign(sysUserProps, props); //合并参数
sysUserProps.record = props.record;
});
}

const getRequestData = async () => {
const getRequestData = async (callback: Function | null = null) => {
const { data } = await userManageTeacherApi.page();
teacherData.value = data;
if (callback) callback();
};

// 提交数据(新增/编辑)

+ 211
- 0
SafeCampus.WEB/src/views/userManage/classManage/index.vue Vedi File

@@ -0,0 +1,211 @@
<!--
* @Description: 人员管理
* @Author: syy
* @Date: 2024-7-15
-->
<template>
<div class="main-box">
<div class="table-box">
<ProTable
ref="proTable"
:pagination="false"
title="班级管理"
:columns="columns"
rowKey="personSetId"
:request-api="userManageClassManageApi.page"
>
<!-- 表格 header 按钮 -->
<template #tableHeader="scope">
<s-button suffix="班级" @click="addClass(FormOptEnum.ADD)" />
<s-button
type="danger"
:opt="FormOptEnum.DELETE"
plain
suffix="班级"
:disabled="!scope.isSelected"
@click="addDelete(scope.selectedListIds, '删除所选班级')"
/>
</template>
<!-- 表格操作栏 -->
<template #operation="scope">
<el-space>
<s-button link :opt="FormOptEnum.EDIT" @click="addClass(FormOptEnum.EDIT, scope.row)" />
<s-button link :opt="FormOptEnum.DELETE" @click="addDelete([scope.row.personSetId], `删除班级`)" />
<el-dropdown @command="handleCommandTree">
<el-link type="primary" :underline="false" :icon="ArrowDown"> 更多 </el-link>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-if="!scope.row.userId" :command="commander(scope.row, cmdEnumTree.AddTeacher)">
{{ cmdEnumTree.AddTeacher }}
</el-dropdown-item>
<el-dropdown-item v-if="scope.row.userId" :command="commander(scope.row, cmdEnumTree.UpdateTeacher)">
{{ cmdEnumTree.UpdateTeacher }}
</el-dropdown-item>
<el-dropdown-item v-if="scope.row.userId" :command="commander(scope.row, cmdEnumTree.DeleteTeacher)">
{{ cmdEnumTree.DeleteTeacher }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-space>
</template>
</ProTable>
</div>

<!-- 班级新增/编辑表单 -->
<FormClass ref="formRefC" />
<!-- 班主任绑定/修改 -->
<FormTeacher ref="formRefT" />
</div>
</template>
<script setup lang="tsx" name="SysUserKeyPersonnel">
import { userManageClassManageApi,userManageTeacherApi,SysUserPersonnel,userManageMajorApi,userManageDepartmentApi } from "@/api";
import { useHandleData } from "@/hooks/useHandleData";
import { FormOptEnum } from "@/enums";
import FormClass from "./components/formClass/index.vue";
import FormTeacher from "./components/formTeacher/index.vue";
import { ArrowDown } from "@element-plus/icons-vue";
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
const proTable = ref<ProTableInstance>();
const majorOptions = ref<any>([])
// 获取专业列表
const getMajorList = async () => {
const res:any = await userManageMajorApi.list({});
if (res.code === 200) {
majorOptions.value = res.data;
}
};
/* 获取系部 */
const departmentOptions = ref<any>([])
const getDepartmentList = async () => {
const res:any = await userManageDepartmentApi.list({});
if (res.code === 200) {
departmentOptions.value = res.data;
}
};
// 表格配置项
const columns: ColumnProps<SysUserPersonnel.ClassPage>[] = [
{ type: "selection", fixed: "left", width: 50 },
{
prop: "majorId",
label: "所属专业",
enum: majorOptions,
fieldNames: { label: "name", value: "id" },
search: {
el: "select",
span:1,
props: {
clearable: false,
placeholder: "请选择专业",
},
},
isShow: false
},
{
prop: "personSetName",
label: "班级名称",
search: { el: "input",span:1, }
},
{
prop: "majorName",
label: "所属专业",
},
{
prop: "departmentName",
label: "所属系部",
},
{
prop: "userName",
label: "班主任"
},
{ prop: "operation", label: "操作", width: 250, fixed: "right" }
];


// 班级表单引用
const formRefC = ref<InstanceType<typeof FormClass> | null>(null);
// 班级表单引用
const formRefT = ref<InstanceType<typeof FormTeacher> | null>(null);


/**
* 打开班级表单
* @param opt 操作类型
* @param record 记录
*/

function addClass(opt: FormOptEnum, record: {} | SysUserPersonnel.ClassPage = {}) {
formRefC.value?.onOpen({ opt: opt, record: JSON.parse(JSON.stringify(record)), successful: RefreshTable });
}

/**
* 班级删除
* @param ids id数组
*/
async function addDelete(id: string[],msg: string) {
// 二次确认 => 请求api => 刷新表格
await useHandleData(userManageClassManageApi.delete, { id:id.join(",") }, msg);
RefreshTable(); //刷新表格
}

// 刷新表格
const RefreshTable = () => {
proTable.value?.refresh();
}


/** 更多下拉菜单命令枚举 */
enum cmdEnumTree {
AddTeacher = "绑定班主任",
UpdateTeacher = "修改班主任",
DeleteTeacher = "解绑班主任",
}

/** 树下拉菜单参数接口 */
interface CommandTree {
row: SysUserPersonnel.ClassPage;
commander: cmdEnumTree;
}

/**配置command的参数 */
function commander(row: SysUserPersonnel.ClassPage, commander: cmdEnumTree): CommandTree {
return {
row: row,
commander: commander,
};
}
/**
* 树更多下拉菜单点击事件
* @param commandtree
*/
async function handleCommandTree(commander: CommandTree) {
switch (commander.commander) {
case cmdEnumTree.AddTeacher:
formRefT.value?.onOpen({ opt: commander.commander, record: commander.row, successful: RefreshTable });
break
case cmdEnumTree.UpdateTeacher:
formRefT.value?.onOpen({ opt: commander.commander, record: commander.row, successful: RefreshTable });
break;
case cmdEnumTree.DeleteTeacher:
// 二次确认 => 请求api => 刷新表格
await useHandleData(userManageTeacherApi.delete, {id: commander.row.userId}, '解绑教师');
RefreshTable(); //刷新表格
break;
}
}

onMounted(() => {
// 获取专业下拉数据
getMajorList();
});
</script>
<style scoped lang="scss">
.table-box {
width: 100%;
height: 100%;
}
</style>

+ 120
- 0
SafeCampus.WEB/src/views/userManage/department/components/form.vue Vedi File

@@ -0,0 +1,120 @@
<!--
* @Description: 表单
* @Author: huguodong
* @Date: 2023-12-15 15:45:28
!-->
<template>
<div>
<form-container v-model="visible" :title="`${departmentProps.opt}院系`" form-size="600px">
<el-form
ref="departmentFormRef"
:rules="rules"
:disabled="departmentProps.disabled"
:model="departmentProps.record"
:hide-required-asterisk="departmentProps.disabled"
label-width="auto"
label-suffix=" :"
>
<s-form-item label="院系编号" prop="code">
<s-input v-model="departmentProps.record.code"></s-input>
</s-form-item>
<s-form-item label="院系名称" prop="name">
<s-input v-model="departmentProps.record.name"></s-input>
</s-form-item>
</el-form>
<template #footer>
<el-button @click="onClose"> 取消 </el-button>
<el-button v-show="!departmentProps.disabled" type="primary" @click="handleSubmit"> 确定 </el-button>
</template>
</form-container>
</div>
</template>

<script setup lang="ts">
import { SysDepartment, userManageDepartmentApi } from "@/api";
import { FormOptEnum, SysDictEnum } from "@/enums";
import { required } from "@/utils/formRules";
import { FormInstance } from "element-plus";
import { useDictStore } from "@/stores/modules";

const visible = ref(false); //是否显示表单
const dictStore = useDictStore(); //字典仓库

// 表单参数
const departmentProps = reactive<FormProps.Base<any>>({
opt: FormOptEnum.ADD,
record: {},
disabled: false
});

// 表单验证规则
const rules = reactive({
code: [required("请输入院系编号")],
name: [required("请输入院系名称")]
});

/**
* 打开表单
* @param props 表单参数
*/
function onOpen(props: FormProps.Base<SysDepartment.DepartmentInfo>) {
Object.assign(departmentProps, props); //合并参数
if (props.opt == FormOptEnum.ADD) {
//如果是新增,设置默认值
// departmentProps.record.sortCode = 99;
// departmentProps.record.status = statusOptions[0].value;
}
visible.value = true; //显示表单
if (props.record.id) {
departmentProps.record = props.record;
//如果传了id,就去请求api获取record

userManageDepartmentApi.detail({ id: props.record.id }).then(res => {
departmentProps.record = res.data;
});
}
}

// 提交数据(新增/编辑)
const departmentFormRef = ref<FormInstance>();
/** 提交表单 */
async function handleSubmit() {
departmentFormRef.value?.validate(async valid => {
if (!valid) return; //表单验证失败
console.log(departmentProps);
// return;
//提交表单
if (departmentProps.opt == FormOptEnum.ADD) {
await userManageDepartmentApi
.add(departmentProps.record, departmentProps.record.id != undefined)
.then(() => {
departmentProps.successful!(); //调用父组件的successful方法
})
.finally(() => {
onClose();
});
} else {
await userManageDepartmentApi
.update(departmentProps.record, departmentProps.record.id != undefined)
.then(() => {
departmentProps.successful!(); //调用父组件的successful方法
})
.finally(() => {
onClose();
});
}
});
}

/** 关闭表单*/
function onClose() {
visible.value = false;
}

// 暴露给父组件的方法
defineExpose({
onOpen
});
</script>

<style lang="scss" scoped></style>

+ 115
- 0
SafeCampus.WEB/src/views/userManage/department/index.vue Vedi File

@@ -0,0 +1,115 @@
<!--
* @Description: 院系管理
* @Author: wwp
* @Date: 2024-7-15
-->
<template>
<div class="main-box">
<div class="table-box">
<ProTable ref="proTable" title="院系管理" :columns="columns" rowKey="id" :request-api="userManageDepartmentApi.page">
<!-- 表格 header 按钮 -->
<template #tableHeader="scope">
<s-button suffix="院系" @click="onOpen(FormOptEnum.ADD)" />
<s-button
type="danger"
:opt="FormOptEnum.DELETE"
plain
suffix="院系"
:disabled="!scope.isSelected"
@click="onDelete(scope.selectedListIds, '删除所选院系')"
/>
</template>
<!-- 表格操作栏 -->
<template #operation="scope">
<el-space>
<s-button link :opt="FormOptEnum.EDIT" @click="onOpen(FormOptEnum.EDIT, scope.row)" />
<s-button link :opt="FormOptEnum.DELETE" @click="onDelete([scope.row.id], `删除院系`)" />
</el-space>
</template>
</ProTable>
</div>
<!-- 院系新增/编辑表单 -->
<Form ref="formRef"></Form>
</div>
</template>
<script setup lang="tsx" name="SysUserKeyPersonnel">
import { userManageDepartmentApi,SysDepartment } from "@/api";
import { useHandleData } from "@/hooks/useHandleData";
import { FormOptEnum } from "@/enums";
import Form from "./components/form.vue";
import { ArrowDown } from "@element-plus/icons-vue";
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
import { ElMessage } from "element-plus";
import { useUserStore } from "@/stores/modules";
import { TokenEnum } from "@/enums";
import type { UploadProps } from "element-plus";
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
const faceUrl = ref('');
const visible = ref(false); //是否显示院系表单
const proTable = ref<ProTableInstance>();
const userStore = useUserStore();
const { accessToken } = userStore;
// 表格配置项
const columns: ColumnProps<SysDepartment.DepartmentInfo>[] = [
{ type: "selection", fixed: "left", width: 50 },
{
prop: "code",
label: "院系编号"
},
{
prop: "name",
label: "院系名称"
},
{ prop: "operation", label: "操作", width: 250, fixed: "right" }
];


// 院系表单引用
const formRef = ref<InstanceType<typeof Form> | null>(null);

/**
* 打开表单
* @param opt 操作类型
* @param record 记录
*/
function onOpen(opt: FormOptEnum, record: {} | SysDepartment.DepartmentInfo = {}) {
formRef.value?.onOpen({ opt: opt, record: record, successful: RefreshTable });
}

/**
* 院系删除
* @param ids id数组
*/
async function onDelete(ids: string[], msg: string) {
if(ids.length === 0){
ElMessage({
message: '请选择要删除的院系',
type: 'warning'
});
return
}
// 二次确认 => 请求api => 刷新表格
await useHandleData(userManageDepartmentApi.delete, {ids }, msg);
RefreshTable(); //刷新表格
}

// 刷新表格
const RefreshTable = () => {
proTable.value?.refresh();
}

</script>
<style scoped lang="scss">
.table-box {
width: 100%;
height: 100%;
}
.custom-tree-node {
display: flex;
flex: 1;
align-items: center;
justify-content: space-between;
padding-right: 8px;
font-size: 14px;
}
</style>

+ 137
- 0
SafeCampus.WEB/src/views/userManage/major/components/form.vue Vedi File

@@ -0,0 +1,137 @@
<!--
* @Description: 表单
* @Author: huguodong
* @Date: 2023-12-15 15:45:28
!-->
<template>
<div>
<form-container v-model="visible" :title="`${majorProps.opt}专业`" form-size="600px">
<el-form
ref="majorFormRef"
:rules="rules"
:disabled="majorProps.disabled"
:model="majorProps.record"
:hide-required-asterisk="majorProps.disabled"
label-width="auto"
label-suffix=" :"
>
<s-form-item label="专业编号" prop="code">
<s-input v-model="majorProps.record.code"></s-input>
</s-form-item>
<s-form-item label="专业名称" prop="name">
<s-input v-model="majorProps.record.name"></s-input>
</s-form-item>
<s-form-item label="所属院系" prop="depId">
<s-select v-model="majorProps.record.depId" :options="treeData" label="name" value="id"></s-select>
<!-- <org-selector v-model:org-value="majorProps.record.depId" :org-tree-api="userManageDepartmentApi.list" :show-all="false" /> -->
</s-form-item>
<s-form-item label="专业简介" prop="introduce">
<s-input v-model="majorProps.record.introduce" type="textarea" :autosize="{ minRows: 2, maxRows: 4 }"></s-input>
</s-form-item>
<s-form-item label="排序" prop="sort">
<el-slider v-model="majorProps.record.sort" show-input :min="0" />
</s-form-item>
</el-form>
<template #footer>
<el-button @click="onClose"> 取消 </el-button>
<el-button v-show="!majorProps.disabled" type="primary" @click="handleSubmit"> 确定 </el-button>
</template>
</form-container>
</div>
</template>

<script setup lang="ts">
import { SysMajor, userManageMajorApi, userManageDepartmentApi } from "@/api";
import { FormOptEnum, SysDictEnum } from "@/enums";
import { required } from "@/utils/formRules";
import { FormInstance } from "element-plus";
import { useDictStore } from "@/stores/modules";

const visible = ref(false); //是否显示表单
const dictStore = useDictStore(); //字典仓库
const treeData = ref<any>([]);
const getRequestData = async () => {
const { data } = await userManageDepartmentApi.list({});
treeData.value = data;
};
// 表单参数
const majorProps = reactive<FormProps.Base<any>>({
opt: FormOptEnum.ADD,
record: {},
disabled: false
});

// 表单验证规则
const rules = reactive({
code: [required("请输入专业编号")],
name: [required("请输入专业名称")],
depId: [required("请选择所属院系")],
introduce: [required("请输入专业简介")]
});

/**
* 打开表单
* @param props 表单参数
*/
function onOpen(props: FormProps.Base<SysMajor.MajorInfo>) {
getRequestData();
Object.assign(majorProps, props); //合并参数
if (props.opt == FormOptEnum.ADD) {
//如果是新增,设置默认值
// majorProps.record.sortCode = 99;
// majorProps.record.status = statusOptions[0].value;
}
visible.value = true; //显示表单
if (props.record.id) {
majorProps.record = props.record;
//如果传了id,就去请求api获取record

userManageMajorApi.detail({ id: props.record.id }).then(res => {
majorProps.record = res.data;
});
}
}

// 提交数据(新增/编辑)
const majorFormRef = ref<FormInstance>();
/** 提交表单 */
async function handleSubmit() {
majorFormRef.value?.validate(async valid => {
if (!valid) return; //表单验证失败
console.log(majorProps);
// return;
//提交表单
if (majorProps.opt == FormOptEnum.ADD) {
await userManageMajorApi
.add(majorProps.record, majorProps.record.id != undefined)
.then(() => {
majorProps.successful!(); //调用父组件的successful方法
})
.finally(() => {
onClose();
});
} else {
await userManageMajorApi
.update(majorProps.record, majorProps.record.id != undefined)
.then(() => {
majorProps.successful!(); //调用父组件的successful方法
})
.finally(() => {
onClose();
});
}
});
}

/** 关闭表单*/
function onClose() {
visible.value = false;
}

// 暴露给父组件的方法
defineExpose({
onOpen
});
</script>

<style lang="scss" scoped></style>

+ 138
- 0
SafeCampus.WEB/src/views/userManage/major/index.vue Vedi File

@@ -0,0 +1,138 @@
<!--
* @Description: 专业管理
* @Author: wwp
* @Date: 2024-7-15
-->
<template>
<div class="main-box">
<div class="table-box">
<ProTable ref="proTable" title="专业管理" :columns="columns" rowKey="id" :request-api="userManageMajorApi.page">
<!-- 表格 header 按钮 -->
<template #tableHeader="scope">
<s-button suffix="专业" @click="onOpen(FormOptEnum.ADD)" />
<s-button
type="danger"
:opt="FormOptEnum.DELETE"
plain
suffix="专业"
:disabled="!scope.isSelected"
@click="onDelete(scope.selectedListIds, '删除所选专业')"
/>
</template>
<!-- 表格操作栏 -->
<template #operation="scope">
<el-space>
<s-button link :opt="FormOptEnum.EDIT" @click="onOpen(FormOptEnum.EDIT, scope.row)" />
<s-button link :opt="FormOptEnum.DELETE" @click="onDelete([scope.row.id], `删除专业`)" />
</el-space>
</template>
</ProTable>
</div>
<!-- 专业新增/编辑表单 -->
<Form ref="formRef"></Form>
</div>
</template>
<script setup lang="tsx" name="SysUserKeyPersonnel">
import { userManageMajorApi,SysMajor,userManageDepartmentApi } from "@/api";
import { useHandleData } from "@/hooks/useHandleData";
import { FormOptEnum } from "@/enums";
import Form from "./components/form.vue";
import { ArrowDown } from "@element-plus/icons-vue";
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
import { ElMessage } from "element-plus";
import { useUserStore } from "@/stores/modules";
import { TokenEnum } from "@/enums";
import type { UploadProps } from "element-plus";
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
const faceUrl = ref('');
const visible = ref(false); //是否显示专业表单
const proTable = ref<ProTableInstance>();
const userStore = useUserStore();
const { accessToken } = userStore;
let departmentOptions = ref<any>([]);
onMounted(() => {
getDepartmentList();
});

const getDepartmentList = async () => {
const { data } = await userManageDepartmentApi.list({});
departmentOptions.value = data;
};

// 表格配置项
const columns: ColumnProps<SysMajor.MajorInfo>[] = [
{ type: "selection", fixed: "left", width: 50 },
{
prop: "depId",
label: "所属院系",
enum: departmentOptions,
search: {
el: "select",
// span: 1
},
fieldNames: { label: "name", value: "id" }
},
{
prop: "code",
label: "专业编号"
},
{
prop: "name",
label: "专业名称"
},
{
prop: "introduce",
label: "专业简介"
},
{ prop: "operation", label: "操作", width: 250, fixed: "right" }
];

// 专业表单引用
const formRef = ref<InstanceType<typeof Form> | null>(null);

/**
* 打开表单
* @param opt 操作类型
* @param record 记录
*/
function onOpen(opt: FormOptEnum, record: {} | SysMajor.MajorInfo = {}) {
formRef.value?.onOpen({ opt: opt, record: record, successful: RefreshTable });
}

/**
* 专业删除
* @param ids id数组
*/
async function onDelete(ids: string[], msg: string) {
if(ids.length === 0){
ElMessage({
message: '请选择要删除的专业',
type: 'warning'
});
return
}
// 二次确认 => 请求api => 刷新表格
await useHandleData(userManageMajorApi.delete, {ids}, msg);
RefreshTable(); //刷新表格
}

// 刷新表格
const RefreshTable = () => {
proTable.value?.refresh();
}

</script>
<style scoped lang="scss">
.table-box {
width: 100%;
height: 100%;
}
.custom-tree-node {
display: flex;
flex: 1;
align-items: center;
justify-content: space-between;
padding-right: 8px;
font-size: 14px;
}
</style>

+ 36
- 10
SafeCampus.WEB/src/views/userManage/personnel/components/form/form_basic.vue Vedi File

@@ -13,10 +13,21 @@
</s-form-item>
</el-col>
<el-col :span="12">
<s-form-item label="所属班级" prop="personSetId">
<s-select v-model="userInfo.personSetId" :options="treeData" label="personSetName" value="personSetId"></s-select>
<s-form-item label="所属系部" prop="depId">
<s-select v-model="userInfo.depId" :options="departmentOptions" label="name" value="id"></s-select
></s-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<s-form-item label="所属专业" prop="majorId">
<s-select v-model="userInfo.majorId" :options="majorOptions" label="name" value="id"></s-select>
</s-form-item>
</el-col>
<el-col :span="12">
<s-form-item label="所属班级" prop="personSetId">
<s-select v-model="userInfo.personSetId" :options="classOptions" label="personSetName" value="personSetId"></s-select> </s-form-item
></el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
@@ -72,12 +83,16 @@
</template>

<script setup lang="ts">
import { SysUserPersonnel, userManagePersonnelApi, userManageClassManageApi } from "@/api";
import { SysUserPersonnel, userManagePersonnelApi } from "@/api";
import { Plus } from "@element-plus/icons-vue";
import { useUserStore } from "@/stores/modules";
import type { UploadProps } from "element-plus";
import { ElMessage } from "element-plus";
import { TokenEnum } from "@/enums";
import { getMajorList, getDepartmentList, getClassList } from "@/mixin";
const departmentOptions = ref<any>([]);
const majorOptions = ref<any>([]);
const classOptions = ref<any>([]);
// props
interface FormProps {
modelValue: Partial<SysUserPersonnel.SysUserPerInfo>;
@@ -96,7 +111,6 @@ const fileList = ref<any>([]);
const faces = ref<SysUserPersonnel.SysUserAvatar[]>([]);
const dialogImageUrl = ref("");
const dialogVisible = ref(false);
const treeData = ref<any>([]);
const handleRemove: UploadProps["onRemove"] = (uploadFile: any) => {
const index = faces.value.findIndex(item => item.uid === uploadFile.uid);
if (index > -1) {
@@ -140,14 +154,10 @@ const genderOptions = ref([
value: "GENDER_FEMALE"
}
]);
const getRequestData = async () => {
const { data } = await userManageClassManageApi.page();
treeData.value = data;
};
onMounted(() => {
onMounted(async () => {
departmentOptions.value = await getDepartmentList();
// 初始化
userInfo.value.gender = userInfo.value.gender ? userInfo.value.gender : genderOptions.value[0].value;
getRequestData();
if (userInfo.value.personId) {
if (userInfo.value.faces?.length > 0) {
fileList.value = [
@@ -170,6 +180,22 @@ onMounted(() => {
];
}
}
/* 监听系部、专业 */
watch(
() => [userInfo.value?.depId, userInfo.value?.majorId],
async ([newDepId, newMajorId], [oldDepId, oldMajorId]) => {
if (newDepId != oldDepId) {
majorOptions.value = await getMajorList(newDepId);
classOptions.value = [];
userInfo.value.personSetId = "";
userInfo.value.majorId = "";
}
if (newMajorId && newMajorId != oldMajorId) {
classOptions.value = await getClassList(newMajorId);
}
},
{ deep: true, immediate: false }
);
});
</script>



+ 4
- 3
SafeCampus.WEB/src/views/userManage/personnel/components/form/index.vue Vedi File

@@ -45,12 +45,13 @@ const sysUserProps = reactive<FormProps.Base<SysUserPersonnel.SysUserPerInfo>>({

// 表单验证规则
const rules = reactive({
// personId: [required("请输入人员ID")],
name: [required("请输入姓名")],
gender: [required("请选择性别")],
faces: [required("请上传人脸图片")],
phone: [required("请输入手机号")]
// extData: [required("请输入扩展数据")]
phone: [required("请输入手机号")],
depId: [required("请选择系部")],
majorId: [required("请选择专业")],
personSetId: [required("请选择班级")]
});

/**


+ 74
- 129
SafeCampus.WEB/src/views/userManage/personnel/index.vue Vedi File

@@ -5,55 +5,11 @@
-->
<template>
<div class="main-box">
<TreeFilter
ref="treeFilter"
label="personSetName"
id="personSetId"
width="300px"
:show-all="true"
:request-api="userManageClassManageApi.page"
@change="changeTreeFilter"
>
<template v-slot:header>
<s-button suffix="班级" @click="addClass(FormOptEnum.ADD)" style="margin-bottom: 15px" />
</template>
<template v-slot:label="{ row }">
<span class="custom-tree-node">
<span>{{ row.node.label }}</span>
<span v-if="row.node.label != '全部'">
<a @click.stop="addClass(FormOptEnum.EDIT, row.node.data)">
<el-icon><Edit /></el-icon>
</a>
<a style="margin-left: 8px" @click.stop="addDelete(row.node.data.personSetId, '删除班级')">
<el-icon><Delete /></el-icon>
</a>
<a style="margin-left: 8px" @click.stop>
<el-dropdown @command="handleCommandTree">
<el-link :underline="false" :icon="More"> </el-link>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-if="!row.node.data.userId" :command="commander(row.node.data, cmdEnumTree.AddTeacher)">
{{ cmdEnumTree.AddTeacher }}
</el-dropdown-item>
<el-dropdown-item v-if="row.node.data.userId" :command="commander(row.node.data, cmdEnumTree.UpdateTeacher)">
{{ cmdEnumTree.UpdateTeacher }}
</el-dropdown-item>
<el-dropdown-item v-if="row.node.data.userId" :command="commander(row.node.data, cmdEnumTree.DeleteTeacher)">
{{ cmdEnumTree.DeleteTeacher }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</a>
</span>
</span>
</template>
</TreeFilter>
<div class="table-box">
<ProTable ref="proTable" title="人员管理" :columns="columns" rowKey="personId" :request-api="userManagePersonnelApi.page">
<!-- 表格 header 按钮 -->
<template #tableHeader="scope">
<s-button v-auth="userPerButtonCode.add" suffix="人员" @click="onOpen(FormOptEnum.ADD, { personSetId: personSetId })" />
<s-button v-auth="userPerButtonCode.add" suffix="人员" @click="onOpen(FormOptEnum.ADD)" />
<s-button
v-auth="userPerButtonCode.delete"
type="danger"
@@ -102,10 +58,6 @@
</div>
<!-- 人员新增/编辑表单 -->
<Form ref="formRef"></Form>
<!-- 班级新增/编辑表单 -->
<FormClass ref="formRefC" />
<!-- 班主任绑定/修改 -->
<FormTeacher ref="formRefT" />
<!-- 预览头像 -->
<el-dialog v-model="visible" title="查看头像" width="830px" :before-close="handleClose">
<div style="display: flex; align-items: center; justify-content: center">
@@ -115,15 +67,13 @@
</div>
</template>
<script setup lang="tsx" name="SysUserPersonnel">
import { userManagePersonnelApi,userPerButtonCode,SysUserPersonnel,userManageClassManageApi,userManageTeacherApi } from "@/api";
import { userManagePersonnelApi,userPerButtonCode,SysUserPersonnel } from "@/api";
import { getMajorList, getDepartmentList, getClassList } from "@/mixin";
import { useHandleData } from "@/hooks/useHandleData";
import { FormOptEnum } from "@/enums";
import Form from "./components/form/index.vue";
import FormClass from "./components/formClass/index.vue";
import FormTeacher from "./components/formTeacher/index.vue";
import { ArrowDown,More } from "@element-plus/icons-vue";
import { ArrowDown } from "@element-plus/icons-vue";
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
import TreeFilter from "@/components/TreeFilter/index.vue";
import { useUserStore } from "@/stores/modules";
import { TokenEnum } from "@/enums";
import type { UploadProps } from "element-plus";
@@ -131,12 +81,76 @@ import type { UploadProps } from "element-plus";
const faceUrl = ref('');
const visible = ref(false); //是否显示人员表单
const proTable = ref<ProTableInstance>();
const treeFilter = ref<InstanceType<typeof TreeFilter> | null>(null);
const userStore = useUserStore();
const { accessToken } = userStore;
const departmentOptions = ref<any>([])
const majorOptions = ref<any>([])
const classOptions = ref<any>([])
//监听depId/majorId变化
watch(
() => [proTable.value!?.searchParam?.depId,proTable.value!?.searchParam?.majorId],
async ([newDepId,newMajorId],[oldDepId,oldMajorId]) => {
if(newDepId !== oldDepId){
majorOptions.value =await getMajorList(newDepId)
classOptions.value = [];
proTable.value!.searchParam.majorId = "";
proTable.value!.searchParam.personSetId = ""
}
if(newMajorId !== oldMajorId){
classOptions.value = await getClassList(newMajorId)
}
} ,{ deep: true, immediate: false }
);
// 表格配置项
const columns: ColumnProps<SysUserPersonnel.SysUserPerInfo>[] = [
{ type: "selection", fixed: "left", width: 50 },
{
prop: "depId",
label: "所属系部",
enum: departmentOptions,
fieldNames: { label: "name", value: "id" },
search: {
el: "select",
span:1,
props: {
clearable: false,
placeholder: "请选择系部",
},
},
isShow: false
},
{
prop: "majorId",
label: "所属专业",
enum: majorOptions,
fieldNames: { label: "name", value: "id" },
search: {
el: "select",
span:1,
props: {
clearable: false,
placeholder: "请选择专业",
},
},
isShow: false
},
{
prop: "personSetId",
label: "所属班级",
enum: classOptions,
fieldNames: { label: "personSetName", value: "personSetId" },
search: {
el: "select",
span:1,
props: {
clearable: false,
placeholder: "请选择所属班级",
},
},
isShow: false
},
{
prop: "faceUrl",
label: "人脸",
@@ -176,10 +190,6 @@ const handleClose = () => {

// 人员表单引用
const formRef = ref<InstanceType<typeof Form> | null>(null);
// 班级表单引用
const formRefC = ref<InstanceType<typeof FormClass> | null>(null);
// 班级表单引用
const formRefT = ref<InstanceType<typeof FormTeacher> | null>(null);

/**
* 打开表单
@@ -190,25 +200,6 @@ function onOpen(opt: FormOptEnum, record: {} | SysUserPersonnel.SysUserPerInfo =
formRef.value?.onOpen({ opt: opt, record: record, successful: RefreshTable });
}

/**
* 打开班级表单
* @param opt 操作类型
* @param record 记录
*/

function addClass(opt: FormOptEnum, record: {} | SysUserPersonnel.ClassPage = {}) {
formRefC.value?.onOpen({ opt: opt, record: JSON.parse(JSON.stringify(record)), successful: RefreshTable });
}
/**
* 班级删除
* @param ids id数组
*/
async function addDelete(id: string[],msg: string) {
// 二次确认 => 请求api => 刷新表格
await useHandleData(userManageClassManageApi.delete, { id }, msg);
RefreshTable(); //刷新表格
}

/**
* 人员删除
* @param ids id数组
@@ -229,7 +220,7 @@ function onOpen(opt: FormOptEnum, record: {} | SysUserPersonnel.SysUserPerInfo =
// 刷新表格
const RefreshTable = () => {
proTable.value?.refresh();
treeFilter.value?.refresh(); //刷新树形筛选器
// treeFilter.value?.refresh(); //刷新树形筛选器
}


@@ -275,47 +266,6 @@ function handleCommand(command: Command) {



/** 更多下拉菜单命令枚举 */
enum cmdEnumTree {
AddTeacher = "绑定班主任",
UpdateTeacher = "修改班主任",
DeleteTeacher = "解绑班主任",
}

/** 树下拉菜单参数接口 */
interface CommandTree {
row: SysUserPersonnel.ClassPage;
commander: cmdEnumTree;
}

/**配置command的参数 */
function commander(row: SysUserPersonnel.ClassPage, commander: cmdEnumTree): CommandTree {
return {
row: row,
commander: commander,
};
}
/**
* 树更多下拉菜单点击事件
* @param commandtree
*/
async function handleCommandTree(commander: CommandTree) {
switch (commander.commander) {
case cmdEnumTree.AddTeacher:
formRefT.value?.onOpen({ opt: commander.commander, record: commander.row, successful: RefreshTable });
break
case cmdEnumTree.UpdateTeacher:
formRefT.value?.onOpen({ opt: commander.commander, record: commander.row, successful: RefreshTable });
break;
case cmdEnumTree.DeleteTeacher:
// 二次确认 => 请求api => 刷新表格
await useHandleData(userManageTeacherApi.delete, {id: commander.row.id}, '解绑教师');
RefreshTable(); //刷新表格
break;
}
}

const handleAvatarSuccess: UploadProps["onSuccess"] = (response) => {
if (response.code === 200) {
userManagePersonnelApi.addFace({
@@ -328,15 +278,10 @@ const handleAvatarSuccess: UploadProps["onSuccess"] = (response) => {
ElMessage.error(response.msg);
}
};

/** 部门切换 */
const personSetId = ref<number | string>()
function changeTreeFilter(val: number | string) {
personSetId.value = val
proTable.value!.pageable.pageNum = 1;
proTable.value!.searchParam.personSetId = val;
proTable.value!.search();
}
onMounted(async () => {
// 获取系部下拉数据
departmentOptions.value = await getDepartmentList()
});
</script>
<style scoped lang="scss">
.table-box {


+ 673
- 162
SafeCampus.WEB/src/views/violation/portrait/detail.vue
File diff soppresso perché troppo grande
Vedi File


+ 45
- 49
SafeCampus.WEB/src/views/warn/zjrq/index.vue Vedi File

@@ -11,13 +11,13 @@
label="label"
id="value"
:isData="true"
width="260px"
width="240px"
:data="warnOptions"
@change="changeType"
></TreeFilter>

<div class="table-box">
<ProTable ref="proTable" :searchCol="3" title="预警列表" :columns="columns" :request-api="warnZJRQApi.page" @reset="resetRecords">
<ProTable ref="proTable" title="预警列表" :columns="columns" :request-api="getTableList" @reset="resetRecords">
<!-- 表格 header 按钮 -->
<template #tableHeader="scope">
<!-- <s-button suffix="预警" @click="onOpen(FormOptEnum.ADD)" /> -->
@@ -30,6 +30,14 @@
@click="onDelete(scope.selectedListIds, '删除所选数据')"
/>
</template>
<!-- tick -->
<template #tick="scope">
{{ scope.row.tick }}
</template>
<template #warnHand="scope">
<el-tag v-if="scope.row.warnHand == 1" type="success">已处理</el-tag>
<el-tag v-else type="danger">未处理</el-tag>
</template>
<!-- 表格 菜单类型 按钮 -->
<template #menuType="scope">
<el-space wrap>
@@ -191,6 +199,13 @@ function getWarnTypeList() {
})
}
// 自定义渲染表头(使用tsx语法)
const headerRender = (scope: any) => {
return (
<span>{scope.column.label}</span>
);
};
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
const proTable = ref<ProTableInstance>();
const dictStore = useDictStore();
@@ -249,7 +264,20 @@ const columns: ColumnProps<ZJRQ.WarnInfo>[] = [
// // span: 1
// }
},
{
prop: "tick",
label: "预警时间",
headerRender,
width: 180,
search: {
el: "date-picker",
span: 2,
props: { type: "datetimerange", valueFormat: "YYYY-MM-DD HH:mm:ss" },
// defaultValue: ["2022-11-12 11:35:00", "2022-12-12 11:35:00"]
}
},
{
prop: "warnHand",
label: "处理状态",
enum: [
@@ -262,61 +290,29 @@ const columns: ColumnProps<ZJRQ.WarnInfo>[] = [
value: 0
}
],
render: scope => {
if (scope.row.warnHand === 1) {
return "已处理";
} else {
return "未处理";
}
},
// render: scope => {
// if (scope.row.warnHand === 1) {
// return "已处理";
// } else {
// return "未处理";
// }
// },
search: {
el: "tree-select",
span: 0.1
span: 1
}
},
{
prop: "tick",
label: "预警时间",
width: 180,
search: {
// 自定义 search 组件
span: 1,
render: ({ searchParam }) => {
return (
<div class="flex-center">
<el-date-picker
v-model={searchParam.StartTick}
type="datetime"
placeholder="开始时间"
format="YYYY-MM-DD HH:mm:ss"
date-format="YYYY-MM-DD"
time-format="HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
{/* <span class="mr10 ml10">-</span> */}
<span style="margin: 0 4px;">-</span>
<el-date-picker
v-model={searchParam.EndTick}
type="datetime"
placeholder="结束时间"
format="YYYY-MM-DD HH:mm:ss"
date-format="YYYY-MM-DD"
time-format="HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</div>
);
}
}

},
{ prop: "operation", label: "操作", width: 250, fixed: "right" }
];


/**
const getTableList = (params: any) => {
let newParams = JSON.parse(JSON.stringify(params));
newParams.tick && (newParams.StartTick = newParams.tick[0]);
newParams.tick && (newParams.EndTick = newParams.tick[1]);
delete newParams.tick;
return warnZJRQApi.page(newParams);
};/**
* 删除
* @param ids id数组
*/


Caricamento…
Annulla
Salva