using AX.FireTrainingSys.DTOs;
using AX.FireTrainingSys.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace AX.FireTrainingSys.Controllers
{
///
/// 学习记录控制器。
///
[Produces("application/json")]
[Route("api/[controller]")]
[ApiVersion("1.0")]
[ApiController]
public class StudyRecordsController : ControllerBase
{
private readonly DriveDbContext dbContext;
public StudyRecordsController(DriveDbContext dbContext)
{
this.dbContext = dbContext;
}
///
/// 获得所有学习记录。
///
/// 查询条件
///
[Authorize(Roles = nameof(RoleType.Admin))]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status200OK)]
[HttpGet]
public async Task>> Get([FromQuery] StudyRecordQueryOptions options)
{
var rangeEnd = DateTimeOffset.Now;
var rangeStart = rangeEnd.AddYears(-1);
if (string.IsNullOrEmpty(options.Name))
return BadRequest($"{nameof(options.Name)} can not be empty.");
if (options.StartTime != default && (options.StartTime < rangeStart || options.StartTime > rangeEnd))
return BadRequest($"{nameof(options.StartTime)} is out of range.");
if (options.EndTime != default && (options.EndTime < rangeStart || options.EndTime > rangeEnd))
return BadRequest($"{nameof(options.EndTime)} is out of range.");
if (options.EndTime == default)
options.EndTime = rangeEnd;
if (options.StartTime == default)
options.StartTime = options.EndTime.Value.AddMonths(-1);
if (options.PageNumber == default)
options.PageNumber = 1;
if (options.PageSize == default)
options.PageSize = 100;
var query = dbContext.StudyRecords
.Include(e => e.User)
.AsNoTracking();
query = query.Where(e => e.User.Name == options!.Name);
query = query.Where(e => e.CreationTime >= options.StartTime!.Value.UtcDateTime);
query = query.Where(e => e.CreationTime <= options.EndTime!.Value.UtcDateTime);
if (!string.IsNullOrEmpty(options.PostName))
query = query.Where(e => e.PostName == options.PostName);
if (!string.IsNullOrEmpty(options.Catalog))
query = query.Where(e => e.Catalog == options.Catalog);
var count = await query.CountAsync();
query = query.OrderByDescending(e => e.CreationTime);
if (options.PageNumber > 1)
query = query.Skip((options.PageNumber.Value - 1) * options.PageSize.Value);
query = query.Take(options.PageSize.Value);
var items = await query.Select(e => e.ToDTO())
.ToListAsync();
var page = new Page
{
PageNumber = (int)options.PageNumber,
PageSize = (int)options.PageSize,
TotalPages = (int)Math.Ceiling((double)count / (int)options.PageSize),
TotalCount = count,
Items = items
};
return Ok(page);
}
///
/// 统计学习记录。
///
/// 查询条件
///
[Authorize(Roles = nameof(RoleType.Admin))]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status200OK)]
[HttpGet("[action]")]
public async Task>> Statistics([FromQuery] StudyStatisticsQueryOptions options)
{
var rangeEnd = DateTimeOffset.Now;
var rangeStart = rangeEnd.AddYears(-1);
if (string.IsNullOrEmpty(options.Name))
return BadRequest($"{nameof(options.Name)} can not be empty.");
if (options.StartTime != default && (options.StartTime < rangeStart || options.StartTime > rangeEnd))
return BadRequest($"{nameof(options.StartTime)} is out of range.");
if (options.EndTime != default && (options.EndTime < rangeStart || options.EndTime > rangeEnd))
return BadRequest($"{nameof(options.EndTime)} is out of range.");
if (options.EndTime == default)
options.EndTime = rangeEnd;
if (options.StartTime == default)
options.StartTime = options.EndTime.Value.AddMonths(-1);
var query = dbContext.StudyRecords
.Include(e => e.User)
.AsNoTracking();
query = query.Where(e => e.User.Name == options!.Name);
query = query.Where(e => e.CreationTime >= options.StartTime!.Value.UtcDateTime);
query = query.Where(e => e.CreationTime <= options.EndTime!.Value.UtcDateTime);
var result = await query.GroupBy(e => new { e.PostName, e.Catalog })
.Select(g => new StudyStatisticsInfo
{
PostName = g.Key.PostName,
Catalog = g.Key.Catalog,
Count = g.Count()
})
.OrderBy(e => e.PostName)
.ThenBy(e => e.Catalog)
.ToListAsync();
return Ok(result);
}
///
/// 创建学习记录。
///
/// 用户信息
///
[Authorize(Roles = "Profile")]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status201Created)]
[HttpPost]
public async Task> Post([FromBody] StudyRecordInfo info)
{
var userid = HttpContext.User.FindFirstValue(JwtClaimTypes.Subject);
var model = info.ToModel(userid);
dbContext.StudyRecords.Add(model);
await dbContext.SaveChangesAsync();
info.Id = model.Id;
info.CreationTime = model.CreationTime.ToLocalTime();
return CreatedAtAction(nameof(Post), info);
}
}
internal static partial class Extensions
{
public static StudyRecord ToModel(this StudyRecordInfo info, string userid) => new StudyRecord
{
Operation = info.Operation,
PostName = info.PostName,
Catalog = info.Catalog,
Target = info.Target,
UserId = userid
};
public static StudyRecordInfo ToDTO(this StudyRecord model) => new StudyRecordInfo
{
Id = model.Id,
CreationTime = model.CreationTime.ToLocalTime(),
Operation = model.Operation,
PostName = model.PostName,
Catalog = model.Catalog,
Target = model.Target
};
}
}