feat: 接入体质评估报告生成与学员查询接口

教练提交学生体质数据前校验任教班级关系,调用评估服务生成报告并复用现有报告持久化逻辑。

新增当前登录学员或家长的最新报告查询接口,按令牌中的学校与学号限定查询范围;补充请求 DTO 与服务接口。

验证:dotnet build WeChatApplet/YD_WeChatApplet.Api.csproj --no-restore --nologo -clp:ErrorsOnly(0 错误)。
This commit is contained in:
ltx 2026-10-23 16:48:14 +08:00
parent e08fa8cbf3
commit f741d95a52
7 changed files with 120 additions and 1 deletions

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using YD_WeChatApplet.Api.Dto.Teacher;
using YD_WeChatApplet.Api.Services.Impl;
using YD_WeChatApplet.Commons.Dto;
using YD_WeChatApplet.Commons.Dto.HomeWork;
@ -69,6 +70,15 @@ namespace YD_WeChatApplet.Api.Controllers
return res;
}
/// <summary>
/// 当前登录学员或家长查看最新体质报告
/// </summary>
[HttpGet("GetPostureReport")]
public async Task<PostureReportContentDto> GetPostureReport()
{
return await _patriarchService.GetPostureReport();
}
/// <summary>
/// 训练记录
/// </summary>

View File

@ -1,4 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using System.Text;
using System.ComponentModel.Design;
using YD_WeChatApplet.Api.Dto.Teacher;
using YD_WeChatApplet.Api.Services.Impl;
@ -21,9 +24,13 @@ namespace YD_WeChatApplet.Api.Controllers
public class TeacherController : ControllerBase
{
private readonly ITeacherService _teacherService;
public TeacherController(ITeacherService teacherService)
private readonly IHttpClientFactory _httpClientFactory;
private readonly IConfiguration _configuration;
public TeacherController(ITeacherService teacherService, IHttpClientFactory httpClientFactory, IConfiguration configuration)
{
_teacherService = teacherService;
_httpClientFactory = httpClientFactory;
_configuration = configuration;
}
/// <summary>
@ -144,6 +151,39 @@ namespace YD_WeChatApplet.Api.Controllers
return res;
}
/// <summary>
/// 生成并保存学生体质报告
/// </summary>
[HttpPost("GeneratePostureReport")]
public async Task<PostureReportContentDto> GeneratePostureReport([FromBody] GeneratePostureReportDto dto)
{
if (dto?.Input == null || string.IsNullOrWhiteSpace(dto.StudentNo))
throw new Exception("学生和体质信息不能为空");
var studentNo = dto.StudentNo.Trim();
await _teacherService.VerifyPostureStudent(studentNo);
dto.Input.StudentId = studentNo;
var evaluateUrl = _configuration["PostureEvaluateUrl"] ?? "http://8.153.108.90:10001/api/evaluate";
using var client = _httpClientFactory.CreateClient();
client.Timeout = TimeSpan.FromSeconds(30);
using var body = new StringContent(JsonConvert.SerializeObject(dto.Input), Encoding.UTF8, "application/json");
using var response = await client.PostAsync(evaluateUrl, body);
if (!response.IsSuccessStatusCode)
throw new Exception("体质评价服务暂不可用");
var responseText = await response.Content.ReadAsStringAsync();
var report = JsonConvert.DeserializeObject<PostureReportContentDto>(responseText);
if (report?.Success != true || report.Result == null)
throw new Exception("体质评价服务未返回有效报告");
await _teacherService.AddPostureReport(new AddPostureReportDto
{
StudentNo = studentNo,
ReportContent = report
});
return report;
}
/// <summary>
/// 新增学生体态报告
/// </summary>

View File

@ -5,6 +5,15 @@ namespace YD_WeChatApplet.Api.Dto.Teacher
/// <summary>
/// 新增体态报告
/// </summary>
public class GeneratePostureReportDto
{
[Required]
public string StudentNo { get; set; } = string.Empty;
[Required]
public PostureReportInputDto? Input { get; set; }
}
public class AddPostureReportDto
{
/// <summary>

View File

@ -1,5 +1,7 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using YD_WeChatApplet.Api.Dto.Teacher;
using YD_WeChatApplet.Api.Entitys;
using YD_WeChatApplet.Api.SmartSportsEntitys;
using YD_WeChatApplet.Api.Utilities;
@ -24,6 +26,32 @@ namespace YD_WeChatApplet.Api.Services.Impl
public UserContext _userContext;
public SmartSportsContext _sportsContext;
private readonly IMapper _mapper;
public async Task<PostureReportContentDto> GetPostureReport()
{
var roleId = UserLoginContext.Current.RoleId;
if (roleId != 3 && roleId != 5)
throw new Exception("当前账号无权查看学员体质报告");
var schoolCode = UserLoginContext.Current.SchoolCode;
var studentNo = UserLoginContext.Current.UserNo;
if (string.IsNullOrWhiteSpace(schoolCode) || string.IsNullOrWhiteSpace(studentNo))
throw new Exception("未找到当前学员信息");
var content = await _userContext.PostureReport.AsNoTracking()
.Where(x => x.SchoolCode == schoolCode && x.StudentNo == studentNo)
.OrderByDescending(x => x.CreateTime)
.ThenByDescending(x => x.Id)
.Select(x => x.ReportContent)
.FirstOrDefaultAsync();
if (string.IsNullOrWhiteSpace(content))
throw new Exception("未找到该学生的体态报告");
return JsonConvert.DeserializeObject<PostureReportContentDto>(content)
?? throw new Exception("报告内容不是有效的JSON对象");
}
public PatriarchService(UserContext userContext, SmartSportsContext sportsContext, IMapper mapper)
{
_userContext = userContext;

View File

@ -745,6 +745,33 @@ namespace YD_WeChatApplet.Services
/// </summary>
/// <param name="dto"></param>
/// <returns>报告Id</returns>
public async Task VerifyPostureStudent(string studentNo)
{
if (UserLoginContext.Current.RoleId != 4)
throw new Exception("当前账号无权生成学生体质报告");
var schoolCode = UserLoginContext.Current.SchoolCode;
var phoneNo = UserLoginContext.Current.PhoneNo;
var teacherId = await _sportsContext.Teacher.AsNoTracking()
.Where(x => x.SchoolCode == schoolCode && x.TeacherPhoneNo == phoneNo)
.Select(x => (int?)x.Id)
.FirstOrDefaultAsync();
if (!teacherId.HasValue)
throw new Exception("未找到当前教师信息");
var classId = await _sportsContext.Student.AsNoTracking()
.Where(x => x.SchoolCode == schoolCode && x.StudentNo == studentNo)
.Select(x => (int?)x.ClassId)
.FirstOrDefaultAsync();
if (!classId.HasValue)
throw new Exception("未找到学生或班级信息");
var canCreate = await _sportsContext.ClassAssocTeacher.AsNoTracking()
.AnyAsync(x => x.TeacherId == teacherId.Value && x.ClassId == classId.Value);
if (!canCreate)
throw new Exception("当前教师无权新增该学生的体质报告");
}
public async Task<int> AddPostureReport(AddPostureReportDto dto)
{
if (dto == null)

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using YD_WeChatApplet.Api.Dto.Teacher;
using TGJ.NetworkFreight.SeckillAggregateServices.Pos.UserService;
using YD_WeChatApplet.Api;
using YD_WeChatApplet.Api.Entitys;
@ -44,6 +45,8 @@ namespace YD_WeChatApplet.Services
/// <returns></returns>
Task<StudentReportDto> StudentReport(string? studentNo);
Task<PostureReportContentDto> GetPostureReport();
/// <summary>
/// 训练记录
/// </summary>

View File

@ -87,6 +87,8 @@ namespace YD_WeChatApplet.Services
/// <returns>报告Id</returns>
Task<int> AddPostureReport(AddPostureReportDto dto);
Task VerifyPostureStudent(string studentNo);
/// <summary>
/// 根据学生学号获取最新体态报告内容
/// </summary>