You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
512 lines
20 KiB
512 lines
20 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using System.Security.Claims; |
|
using System.Threading.Tasks; |
|
using AX.FireTrainingSys.DTOs; |
|
using AX.FireTrainingSys.Models; |
|
using Microsoft.AspNetCore.Authorization; |
|
using Microsoft.AspNetCore.Http; |
|
using Microsoft.AspNetCore.Mvc; |
|
using Microsoft.EntityFrameworkCore; |
|
using Mapster; |
|
|
|
namespace AX.FireTrainingSys.Controllers.V1 |
|
{ |
|
/// <summary> |
|
/// 课件库控制器。 |
|
/// </summary> |
|
[Produces("application/json")] |
|
[Route("api/[controller]")] |
|
[ApiVersion("1.0")] |
|
//[Authorize(Roles = "Profile")] |
|
[ApiController] |
|
public class CoursewaresController : ControllerBase |
|
{ |
|
private readonly DriveDbContext dbContext; |
|
|
|
public CoursewaresController(DriveDbContext dbContext) |
|
{ |
|
this.dbContext = dbContext; |
|
} |
|
|
|
/// <summary> |
|
/// 获得课件列表。 |
|
/// </summary> |
|
/// <param name="options"></param> |
|
/// <returns></returns> |
|
[ProducesResponseType(StatusCodes.Status400BadRequest)] |
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)] |
|
[ProducesResponseType(StatusCodes.Status403Forbidden)] |
|
[ProducesResponseType(StatusCodes.Status200OK)] |
|
[HttpGet] |
|
public async Task<ActionResult<Page<CoursewareInfo>>> Get([FromQuery] CoursewareQueryOptions options) |
|
{ |
|
if (options.PageNumber == null) |
|
options.PageNumber = 1; |
|
|
|
if (options.PageSize == null) |
|
options.PageSize = 10; |
|
|
|
var username = HttpContext.User.FindFirstValue(JwtClaimTypes.Subject); |
|
|
|
var queryable = dbContext.Coursewares |
|
.Include(e => e.User) |
|
.Include(e => e.BuildingTypes) |
|
.AsNoTracking(); |
|
|
|
if (options.Others != null) |
|
queryable = queryable.Where(e => options.Others.Value ? e.UserId != username : e.UserId == username); |
|
|
|
if (options.IsPublic != null) |
|
queryable = queryable.Where(e => e.IsPublic == options.IsPublic.Value); |
|
|
|
if (options.Name != null) |
|
queryable = queryable.Where(e => e.Name.Contains(options.Name)); |
|
|
|
if (options.ModifiedTime != null) |
|
{ |
|
var modifiedTime = options.ModifiedTime.Value.UtcDateTime; |
|
queryable = queryable.Where(e => e.ModifiedTime >= modifiedTime); |
|
} |
|
|
|
if (options.BuildingType != null) |
|
queryable = queryable.Where(e => e.BuildingTypes.Any(c => c.BuildingTypeId == options.BuildingType)); |
|
|
|
if (!string.IsNullOrEmpty(options.CompanyName)) |
|
queryable = queryable.Where(e => e.CompanyName.Contains(options.CompanyName)); |
|
|
|
var count = await queryable.CountAsync(); |
|
|
|
queryable = queryable.OrderByDescending(e => e.ModifiedTime); |
|
|
|
if (options.PageNumber > 1) |
|
queryable = queryable.Skip((options.PageNumber.Value - 1) * options.PageSize.Value - 1); |
|
|
|
queryable = queryable.Take(options.PageSize.Value); |
|
|
|
var list = await queryable.Select(e => e.ToDTO()) |
|
.ToListAsync(); |
|
|
|
var result = new Page<CoursewareInfo> |
|
{ |
|
PageNumber = (int)options.PageNumber, |
|
PageSize = (int)options.PageSize, |
|
TotalPages = (int)Math.Ceiling((double)count / (int)options.PageSize), |
|
TotalCount = count, |
|
Items = list |
|
}; |
|
|
|
return Ok(result); |
|
} |
|
|
|
/// <summary> |
|
/// 新建一个课件。 |
|
/// </summary> |
|
/// <param name="companyName">单位/场景名称</param> |
|
/// <param name="info"></param> |
|
/// <returns></returns> |
|
[ProducesResponseType(StatusCodes.Status400BadRequest)] |
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)] |
|
[ProducesResponseType(StatusCodes.Status403Forbidden)] |
|
[ProducesResponseType(StatusCodes.Status201Created)] |
|
[HttpPost] |
|
public async Task<ActionResult<CoursewareInfo>> Post([FromQuery] string companyName, [FromBody] CoursewareInfo info) |
|
{ |
|
if (string.IsNullOrEmpty(info.Name)) |
|
return BadRequest(nameof(info.Name)); |
|
|
|
if (info.BuildingTypes == null || info.BuildingTypes.Length == 0) |
|
return BadRequest(nameof(info.BuildingTypes)); |
|
|
|
var username = HttpContext.User.FindFirstValue(JwtClaimTypes.Subject); |
|
var realname = HttpContext.User.FindFirstValue(JwtClaimTypes.Name); |
|
|
|
using (var transaction = dbContext.Database.BeginTransaction()) |
|
{ |
|
var model = info.ToModel(username); |
|
|
|
dbContext.Coursewares.Add(model); |
|
|
|
var buildingTypes = info.Create(model.Id); |
|
|
|
dbContext.Set<CoursewareBuildingType>().AddRange(buildingTypes); |
|
|
|
await dbContext.SaveChangesAsync(); |
|
|
|
info.Id = model.Id; |
|
info.Creator = realname; |
|
info.ModifiedTime = model.ModifiedTime.ToLocalTime(); |
|
info.Referenced = false; |
|
|
|
//从模板数据库中初始化课件数据 |
|
await dbContext.Database.ExecuteSqlInterpolatedAsync($@" |
|
INSERT INTO BuildingAdjoins (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateBuildingAdjoins |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO BuildingBasicInfos (CoursewareId, Content) |
|
SELECT {info.Id}, Content FROM TemplateBuildingBasicInfos |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO BuildingFeatures (CoursewareId, Content) |
|
SELECT {info.Id}, Content FROM TemplateBuildingFeatures |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO Exits (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateExits |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO FireControlRooms (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateFireControlRooms |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO FireLifts (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateFireLifts |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO FireWaterMonitors (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateFireWaterMonitors |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO FoamHydrants (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateFoamHydrants |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO FoamPumpRooms (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateFoamPumpRooms |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO ImageMarkers (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateImageMarkers |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO ImportantLocations (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateImportantLocations |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO MunicipalFireHydrants (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateMunicipalFireHydrants |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO NoParkingAreas (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateNoParkingAreas |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO OutdoorFireHydrants (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateOutdoorFireHydrants |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO ProtectedStairways (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateProtectedStairways |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO PumpRooms (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplatePumpRooms |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO SiameseConnections (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateSiameseConnections |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO StorageTanks (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateStorageTanks |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO WaterTanks (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM TemplateWaterTanks |
|
WHERE CompanyName == {companyName}; |
|
|
|
INSERT INTO Organizations(CoursewareId, Id, Name, Level, [Order], X, Y, Z, ParentId) |
|
SELECT {info.Id}, Id, Name, Level, [Order], X, Y, Z, ParentId FROM TemplateOrganizations; |
|
|
|
INSERT INTO FireForces(CoursewareId, Id, Type, Content, OrganizationId) |
|
SELECT {info.Id}, Id, Type, Content, OrganizationId FROM TemplateFireForces; |
|
|
|
"); |
|
|
|
transaction.Commit(); |
|
|
|
return CreatedAtAction(nameof(Post), info); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 另存为一个课件。 |
|
/// </summary> |
|
/// <param name="coursewareId">课件编号</param> |
|
/// <returns></returns> |
|
[ProducesResponseType(StatusCodes.Status400BadRequest)] |
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)] |
|
[ProducesResponseType(StatusCodes.Status403Forbidden)] |
|
[ProducesResponseType(StatusCodes.Status201Created)] |
|
[HttpPost("[action]")] |
|
public async Task<ActionResult<CoursewareInfo>> SaveAs([FromQuery] string coursewareId) |
|
{ |
|
if (string.IsNullOrEmpty(coursewareId)) |
|
return BadRequest(coursewareId); |
|
|
|
var m = await dbContext.Coursewares |
|
.Include(e => e.BuildingTypes) |
|
.Include(e => e.User) |
|
.AsNoTracking() |
|
.Where(e => e.Id == coursewareId) |
|
.FirstOrDefaultAsync(); |
|
|
|
if (m == null) |
|
return NotFound(coursewareId); |
|
|
|
var info = m.ToDTO(); |
|
|
|
var username = HttpContext.User.FindFirstValue(JwtClaimTypes.Subject); |
|
|
|
using (var transaction = dbContext.Database.BeginTransaction()) |
|
{ |
|
var model = info.ToModel(username); |
|
|
|
dbContext.Coursewares.Add(model); |
|
|
|
var buildingTypes = info.Create(model.Id); |
|
|
|
dbContext.Set<CoursewareBuildingType>().AddRange(buildingTypes); |
|
|
|
await dbContext.SaveChangesAsync(); |
|
|
|
info.Id = model.Id; |
|
info.Creator = username; |
|
info.ModifiedTime = model.ModifiedTime.ToLocalTime(); |
|
info.Referenced = false; |
|
|
|
//从相关数据库中初始化课件数据 |
|
await dbContext.Database.ExecuteSqlInterpolatedAsync($@" |
|
INSERT INTO BuildingAdjoins (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM BuildingAdjoins |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO BuildingBasicInfos (CoursewareId, Content) |
|
SELECT {info.Id}, Content FROM BuildingBasicInfos |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO BuildingFeatures (CoursewareId, Content) |
|
SELECT {info.Id}, Content FROM BuildingFeatures |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO Exits (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM Exits |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO FireControlRooms (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM FireControlRooms |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO FireLifts (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM FireLifts |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO FireWaterMonitors (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM FireWaterMonitors |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO FoamHydrants (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM FoamHydrants |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO FoamPumpRooms (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM FoamPumpRooms |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO ImageMarkers (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM ImageMarkers |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO ImportantLocations (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM ImportantLocations |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO MunicipalFireHydrants (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM MunicipalFireHydrants |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO NoParkingAreas (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM NoParkingAreas |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO OutdoorFireHydrants (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM OutdoorFireHydrants |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO ProtectedStairways (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM ProtectedStairways |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO PumpRooms (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM PumpRooms |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO SiameseConnections (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM SiameseConnections |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO StorageTanks (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM StorageTanks |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO WaterTanks (CoursewareId, Id, Content) |
|
SELECT {info.Id}, Id, Content FROM WaterTanks |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO Organizations(CoursewareId, Id, Name, Level, [Order], X, Y, Z, ParentId) |
|
SELECT {info.Id}, Id, Name, Level, [Order], X, Y, Z, ParentId FROM Organizations |
|
WHERE CoursewareId == {coursewareId}; |
|
|
|
INSERT INTO FireForces(CoursewareId, Id, Type, Content, OrganizationId) |
|
SELECT {info.Id}, Id, Type, Content, OrganizationId FROM FireForces |
|
WHERE CoursewareId == {coursewareId}; |
|
"); |
|
|
|
transaction.Commit(); |
|
|
|
return CreatedAtAction(nameof(Post), info); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 修改指定的课件信息。 |
|
/// </summary> |
|
/// <param name="id"></param> |
|
/// <param name="info"></param> |
|
/// <returns></returns> |
|
//[ProducesResponseType(ErrorCodes.E620)] |
|
[ProducesResponseType(StatusCodes.Status400BadRequest)] |
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)] |
|
[ProducesResponseType(StatusCodes.Status403Forbidden)] |
|
[ProducesResponseType(StatusCodes.Status404NotFound)] |
|
[ProducesResponseType(StatusCodes.Status204NoContent)] |
|
[HttpPut("{id}")] |
|
public async Task<Microsoft.AspNetCore.Mvc.ActionResult> Put(string id, [FromBody] CoursewareInfo info) |
|
{ |
|
if (id != info.Id) |
|
return BadRequest(id); |
|
|
|
var username = HttpContext.User.FindFirstValue(JwtClaimTypes.Subject); |
|
|
|
var model = await dbContext.Coursewares |
|
.Include(e => e.BuildingTypes) |
|
.FirstOrDefaultAsync(e => e.Id == id); |
|
|
|
if (model == null) |
|
return NotFound(); |
|
|
|
// 不能修改他人课件 |
|
if (model.UserId != username) |
|
return Forbid(); |
|
|
|
// 不能撤销已被引用的公开课件 |
|
if (model.IsPublic && |
|
model.Referenced > 0 && |
|
info.IsPublic != null && |
|
info.IsPublic == false) |
|
return this.ErrorCode(ErrorCodes.E620); |
|
|
|
info.MapTo(model); |
|
|
|
var currItems = model.BuildingTypes; |
|
var newItems = info.Create(model.Id); |
|
|
|
var removedItems = currItems.Except(newItems); |
|
var addedItems = newItems.Except(currItems); |
|
|
|
dbContext.Set<CoursewareBuildingType>().RemoveRange(removedItems); |
|
dbContext.Set<CoursewareBuildingType>().AddRange(addedItems); |
|
|
|
await dbContext.SaveChangesAsync(); |
|
|
|
return NoContent(); |
|
} |
|
|
|
/// <summary> |
|
/// 删除指定的课件信息。 |
|
/// </summary> |
|
/// <param name="id"></param> |
|
/// <returns></returns> |
|
//[ProducesResponseType(ErrorCodes.E621)] |
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)] |
|
[ProducesResponseType(StatusCodes.Status403Forbidden)] |
|
[ProducesResponseType(StatusCodes.Status404NotFound)] |
|
[ProducesResponseType(StatusCodes.Status204NoContent)] |
|
[HttpDelete("{id}")] |
|
public async Task<Microsoft.AspNetCore.Mvc.ActionResult> Delete(string id) |
|
{ |
|
var username = HttpContext.User.FindFirstValue(JwtClaimTypes.Subject); |
|
var model = await dbContext.Coursewares.FindAsync(id); |
|
|
|
if (model == null) |
|
return NotFound(); |
|
|
|
// 不能删除他人课件 |
|
if (model.UserId != username) |
|
return Forbid(); |
|
|
|
// 不能删除已被引用的公开课件 |
|
if (model.IsPublic && |
|
model.Referenced > 0) |
|
return this.ErrorCode(ErrorCodes.E621); |
|
|
|
model.Deleted = true; |
|
model.Name = model.Name + "-" + ObjectId.NewId().ToString(); |
|
await dbContext.SaveChangesAsync(); |
|
|
|
return NoContent(); |
|
} |
|
} |
|
|
|
internal static class CoursewareExtensions |
|
{ |
|
public static Courseware ToModel(this CoursewareInfo dto, string creator) |
|
{ |
|
var model = dto.Adapt<Courseware>(); |
|
model.UserId = creator; |
|
return model; |
|
} |
|
|
|
public static CoursewareInfo ToDTO(this Courseware model) |
|
{ |
|
var buildingTypes = new int[model.BuildingTypes.Count]; |
|
|
|
var i = 0; |
|
|
|
foreach (var type in model.BuildingTypes) |
|
buildingTypes[i++] = type.BuildingTypeId; |
|
|
|
var dto = model.Adapt<CoursewareInfo>(); |
|
|
|
dto.BuildingTypes = buildingTypes; |
|
|
|
return dto; |
|
} |
|
|
|
public static void MapTo(this CoursewareInfo dto, Courseware model) |
|
{ |
|
dto.Adapt(model); |
|
model.ModifiedTime = DateTime.UtcNow; |
|
} |
|
|
|
public static IEnumerable<CoursewareBuildingType> Create(this CoursewareInfo dto, string id) |
|
{ |
|
var buildingTypes = new List<CoursewareBuildingType>(dto.BuildingTypes.Length); |
|
|
|
for (var i = 0; i < dto.BuildingTypes.Length; ++i) |
|
{ |
|
var buildingType = new CoursewareBuildingType |
|
{ |
|
CoursewareId = id, |
|
BuildingTypeId = dto.BuildingTypes[i] |
|
}; |
|
|
|
buildingTypes.Add(buildingType); |
|
} |
|
|
|
return buildingTypes; |
|
} |
|
} |
|
}
|
|
|