using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Tiku.Api.Contracts; using Tiku.Application.Catalog; using Tiku.Application.Content; using Tiku.Application.Security; using Tiku.Application.TenantAdmin; namespace Tiku.Api.Controllers; [ApiController] [Authorize(Policy = TikuPolicies.TenantAdmin)] [Produces("application/json")] [Route("api/tenant-admin")] public sealed class TenantAdminDirectController( ITenantAdminDirectService tenantAdminService, ICurrentUser currentUser, ICurrentTenant currentTenant) : ControllerBase { [HttpGet("classes")] [EndpointSummary("查询租户班级")] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> GetClasses( [FromQuery] TenantAdminClassQueryDto query, CancellationToken cancellationToken) { return Ok(await tenantAdminService.GetClassesAsync(ResolveActor(), query.ToFilter(), cancellationToken)); } [HttpPut("classes")] [EndpointSummary("新增或更新租户班级")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> UpsertClass( UpsertTenantAdminClassDto request, CancellationToken cancellationToken) { return Ok(await tenantAdminService.UpsertClassAsync(ResolveActor(), request.ToCommand(), cancellationToken)); } [HttpPost("classes/disable")] [EndpointSummary("停用租户班级")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> DisableClass( [FromBody] Guid classId, CancellationToken cancellationToken) { return Ok(await tenantAdminService.DisableClassAsync(ResolveActor(), classId, cancellationToken)); } [HttpGet("classes/members")] [EndpointSummary("查询班级成员")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> GetClassMembers( [FromQuery] TenantAdminClassMemberQueryDto query, CancellationToken cancellationToken) { return Ok(await tenantAdminService.GetClassMembersAsync(ResolveActor(), query.ToFilter(), cancellationToken)); } [HttpPut("classes/members")] [EndpointSummary("新增或更新班级成员")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> UpsertClassMember( UpsertTenantAdminClassMemberDto request, CancellationToken cancellationToken) { return Ok(await tenantAdminService.UpsertClassMemberAsync(ResolveActor(), request.ToCommand(), cancellationToken)); } [HttpPost("classes/members/remove")] [EndpointSummary("移除班级成员")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> RemoveClassMember( RemoveTenantAdminClassMemberDto request, CancellationToken cancellationToken) { return Ok(await tenantAdminService.RemoveClassMemberAsync(ResolveActor(), request.ClassMemberId, cancellationToken)); } [HttpGet("students")] [EndpointSummary("查询租户学生")] [ProducesResponseType(StatusCodes.Status200OK)] public async Task> GetStudents( [FromQuery] TenantAdminStudentQueryDto query, CancellationToken cancellationToken) { return Ok(await tenantAdminService.GetStudentsAsync(ResolveActor(), query.ToFilter(), cancellationToken)); } [HttpPut("students")] [EndpointSummary("新增或更新租户学生档案")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> UpsertStudent( UpsertTenantAdminStudentDto request, CancellationToken cancellationToken) { return Ok(await tenantAdminService.UpsertStudentAsync(ResolveActor(), request.ToCommand(), cancellationToken)); } [HttpPost("students/status")] [EndpointSummary("更新租户学生状态")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> UpdateStudentStatus( UpdateTenantAdminStudentStatusDto request, CancellationToken cancellationToken) { return Ok(await tenantAdminService.UpdateStudentStatusAsync(ResolveActor(), request.ToCommand(), cancellationToken)); } [HttpGet("student-notes")] [EndpointSummary("查询学生备注")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> GetStudentNotes( [FromQuery] TenantAdminStudentActivityQueryDto query, CancellationToken cancellationToken) { return Ok(await tenantAdminService.GetStudentNotesAsync(ResolveActor(), query.ToFilter(), cancellationToken)); } [HttpPut("student-notes")] [EndpointSummary("新增或更新学生备注")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> UpsertStudentNote( UpsertTenantAdminStudentNoteDto request, CancellationToken cancellationToken) { return Ok(await tenantAdminService.UpsertStudentNoteAsync(ResolveActor(), request.ToCommand(), cancellationToken)); } [HttpGet("student-followups")] [EndpointSummary("查询学生跟进")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> GetStudentFollowups( [FromQuery] TenantAdminStudentActivityQueryDto query, CancellationToken cancellationToken) { return Ok(await tenantAdminService.GetStudentFollowupsAsync(ResolveActor(), query.ToFilter(), cancellationToken)); } [HttpPut("student-followups")] [EndpointSummary("新增或更新学生跟进")] [ProducesResponseType>(StatusCodes.Status200OK)] public async Task>> UpsertStudentFollowup( UpsertTenantAdminStudentFollowupDto request, CancellationToken cancellationToken) { return Ok(await tenantAdminService.UpsertStudentFollowupAsync(ResolveActor(), request.ToCommand(), cancellationToken)); } private TenantAdminActor ResolveActor() { if (currentTenant.TenantId is null || currentUser.UserId is null) { throw new TenantAdminDirectException("Tenant admin actor was not resolved.", "tenant_admin_access_denied"); } return new TenantAdminActor(currentTenant.TenantId.Value, currentUser.UserId.Value); } }