21
This commit is contained in:
parent
fa6b186563
commit
a7e5c11007
|
|
@ -155,6 +155,15 @@ public class AdminBusinessDbContext : DbContext
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region 报告页面配置
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 报告页面配置表
|
||||||
|
/// </summary>
|
||||||
|
public DbSet<ReportPageConfig> ReportPageConfigs { get; set; } = null!;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
base.OnModelCreating(modelBuilder);
|
base.OnModelCreating(modelBuilder);
|
||||||
|
|
@ -398,5 +407,15 @@ public class AdminBusinessDbContext : DbContext
|
||||||
entity.HasIndex(e => e.Status)
|
entity.HasIndex(e => e.Status)
|
||||||
.HasDatabaseName("IX_business_pages_status");
|
.HasDatabaseName("IX_business_pages_status");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// =============================================
|
||||||
|
// ReportPageConfig 配置
|
||||||
|
// =============================================
|
||||||
|
modelBuilder.Entity<ReportPageConfig>(entity =>
|
||||||
|
{
|
||||||
|
// SortOrder 索引
|
||||||
|
entity.HasIndex(e => e.SortOrder)
|
||||||
|
.HasDatabaseName("ix_rpc_sort_order");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace MiAssessment.Admin.Business.Entities;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 报告页面配置表
|
||||||
|
/// </summary>
|
||||||
|
[Table("report_page_configs")]
|
||||||
|
public class ReportPageConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主键ID
|
||||||
|
/// </summary>
|
||||||
|
[Key]
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 页面类型:1静态图片 2网页截图
|
||||||
|
/// </summary>
|
||||||
|
public int PageType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 页面标识名称
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[MaxLength(50)]
|
||||||
|
public string PageName { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 页面显示标题
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
[MaxLength(100)]
|
||||||
|
public string Title { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 排序序号
|
||||||
|
/// </summary>
|
||||||
|
public int SortOrder { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 静态图片路径(PageType=1 时使用)
|
||||||
|
/// </summary>
|
||||||
|
[MaxLength(500)]
|
||||||
|
public string? ImageUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 网页路由路径(PageType=2 时使用)
|
||||||
|
/// </summary>
|
||||||
|
[MaxLength(200)]
|
||||||
|
public string? RouteUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 状态:0禁用 1启用
|
||||||
|
/// </summary>
|
||||||
|
public int Status { get; set; } = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime UpdateTime { get; set; }
|
||||||
|
}
|
||||||
|
|
@ -265,6 +265,20 @@ public static class ErrorCodes
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region 报告页面配置模块错误 (3800-3899)
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 报告页面配置不存在
|
||||||
|
/// </summary>
|
||||||
|
public const int ReportPageConfigNotFound = 3801;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 页面标识名称已存在
|
||||||
|
/// </summary>
|
||||||
|
public const int ReportPageNameExists = 3802;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region 系统错误 (5000-5999)
|
#region 系统错误 (5000-5999)
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,135 @@
|
||||||
|
namespace MiAssessment.Admin.Business.Models.ReportPageConfig;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 报告页面配置 DTO
|
||||||
|
/// </summary>
|
||||||
|
public class ReportPageConfigDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主键ID
|
||||||
|
/// </summary>
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 页面类型:1静态图片 2网页截图
|
||||||
|
/// </summary>
|
||||||
|
public int PageType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 页面类型名称
|
||||||
|
/// </summary>
|
||||||
|
public string PageTypeName { get; set; } = "";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 页面标识名称
|
||||||
|
/// </summary>
|
||||||
|
public string PageName { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 页面显示标题
|
||||||
|
/// </summary>
|
||||||
|
public string Title { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 排序序号
|
||||||
|
/// </summary>
|
||||||
|
public int SortOrder { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 静态图片路径
|
||||||
|
/// </summary>
|
||||||
|
public string? ImageUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 网页路由路径
|
||||||
|
/// </summary>
|
||||||
|
public string? RouteUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 状态:0禁用 1启用
|
||||||
|
/// </summary>
|
||||||
|
public int Status { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 状态名称
|
||||||
|
/// </summary>
|
||||||
|
public string StatusName { get; set; } = "";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 报告页面配置查询请求
|
||||||
|
/// </summary>
|
||||||
|
public class ReportPageConfigQueryRequest : PagedRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 页面类型筛选
|
||||||
|
/// </summary>
|
||||||
|
public int? PageType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 状态筛选
|
||||||
|
/// </summary>
|
||||||
|
public int? Status { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 标题关键字
|
||||||
|
/// </summary>
|
||||||
|
public string? Title { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建报告页面配置请求
|
||||||
|
/// </summary>
|
||||||
|
public class CreateReportPageConfigRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 页面类型:1静态图片 2网页截图
|
||||||
|
/// </summary>
|
||||||
|
public int PageType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 页面标识名称
|
||||||
|
/// </summary>
|
||||||
|
public string PageName { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 页面显示标题
|
||||||
|
/// </summary>
|
||||||
|
public string Title { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 排序序号
|
||||||
|
/// </summary>
|
||||||
|
public int SortOrder { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 静态图片路径
|
||||||
|
/// </summary>
|
||||||
|
public string? ImageUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 网页路由路径
|
||||||
|
/// </summary>
|
||||||
|
public string? RouteUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 状态:0禁用 1启用
|
||||||
|
/// </summary>
|
||||||
|
public int Status { get; set; } = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新报告页面配置请求
|
||||||
|
/// </summary>
|
||||||
|
public class UpdateReportPageConfigRequest : CreateReportPageConfigRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主键ID
|
||||||
|
/// </summary>
|
||||||
|
public long Id { get; set; }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
using MiAssessment.Admin.Business.Models;
|
||||||
|
using MiAssessment.Admin.Business.Models.ReportPageConfig;
|
||||||
|
|
||||||
|
namespace MiAssessment.Admin.Business.Services.Interfaces;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 报告页面配置服务接口
|
||||||
|
/// </summary>
|
||||||
|
public interface IReportPageConfigService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取报告页面配置列表
|
||||||
|
/// </summary>
|
||||||
|
Task<PagedResult<ReportPageConfigDto>> GetListAsync(ReportPageConfigQueryRequest request);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建报告页面配置
|
||||||
|
/// </summary>
|
||||||
|
Task<long> CreateAsync(CreateReportPageConfigRequest request);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新报告页面配置
|
||||||
|
/// </summary>
|
||||||
|
Task<bool> UpdateAsync(UpdateReportPageConfigRequest request);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除报告页面配置
|
||||||
|
/// </summary>
|
||||||
|
Task<bool> DeleteAsync(long id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新状态
|
||||||
|
/// </summary>
|
||||||
|
Task<bool> UpdateStatusAsync(long id, int status);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量更新排序
|
||||||
|
/// </summary>
|
||||||
|
Task<bool> UpdateSortAsync(List<SortItem> items);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,207 @@
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using MiAssessment.Admin.Business.Data;
|
||||||
|
using MiAssessment.Admin.Business.Entities;
|
||||||
|
using MiAssessment.Admin.Business.Models;
|
||||||
|
using MiAssessment.Admin.Business.Models.Common;
|
||||||
|
using MiAssessment.Admin.Business.Models.ReportPageConfig;
|
||||||
|
using MiAssessment.Admin.Business.Services.Interfaces;
|
||||||
|
|
||||||
|
namespace MiAssessment.Admin.Business.Services;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 报告页面配置服务实现
|
||||||
|
/// </summary>
|
||||||
|
public class ReportPageConfigService : IReportPageConfigService
|
||||||
|
{
|
||||||
|
private readonly AdminBusinessDbContext _dbContext;
|
||||||
|
private readonly ILogger<ReportPageConfigService> _logger;
|
||||||
|
|
||||||
|
private static readonly Dictionary<int, string> PageTypeNames = new()
|
||||||
|
{
|
||||||
|
{ 1, "静态图片" },
|
||||||
|
{ 2, "网页截图" }
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly Dictionary<int, string> StatusNames = new()
|
||||||
|
{
|
||||||
|
{ 0, "禁用" },
|
||||||
|
{ 1, "启用" }
|
||||||
|
};
|
||||||
|
|
||||||
|
public ReportPageConfigService(
|
||||||
|
AdminBusinessDbContext dbContext,
|
||||||
|
ILogger<ReportPageConfigService> logger)
|
||||||
|
{
|
||||||
|
_dbContext = dbContext;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task<PagedResult<ReportPageConfigDto>> GetListAsync(ReportPageConfigQueryRequest request)
|
||||||
|
{
|
||||||
|
var query = _dbContext.ReportPageConfigs.AsNoTracking().AsQueryable();
|
||||||
|
|
||||||
|
if (request.PageType.HasValue)
|
||||||
|
query = query.Where(p => p.PageType == request.PageType.Value);
|
||||||
|
|
||||||
|
if (request.Status.HasValue)
|
||||||
|
query = query.Where(p => p.Status == request.Status.Value);
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(request.Title))
|
||||||
|
query = query.Where(p => p.Title.Contains(request.Title));
|
||||||
|
|
||||||
|
var total = await query.CountAsync();
|
||||||
|
|
||||||
|
var items = await query
|
||||||
|
.OrderBy(p => p.SortOrder)
|
||||||
|
.Skip(request.Skip)
|
||||||
|
.Take(request.PageSize)
|
||||||
|
.Select(p => new ReportPageConfigDto
|
||||||
|
{
|
||||||
|
Id = p.Id,
|
||||||
|
PageType = p.PageType,
|
||||||
|
PageName = p.PageName,
|
||||||
|
Title = p.Title,
|
||||||
|
SortOrder = p.SortOrder,
|
||||||
|
ImageUrl = p.ImageUrl,
|
||||||
|
RouteUrl = p.RouteUrl,
|
||||||
|
Status = p.Status,
|
||||||
|
CreateTime = p.CreateTime
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
// 内存中映射名称
|
||||||
|
foreach (var item in items)
|
||||||
|
{
|
||||||
|
item.PageTypeName = PageTypeNames.TryGetValue(item.PageType, out var pn) ? pn : "未知";
|
||||||
|
item.StatusName = StatusNames.TryGetValue(item.Status, out var sn) ? sn : "未知";
|
||||||
|
}
|
||||||
|
|
||||||
|
return PagedResult<ReportPageConfigDto>.Create(items, total, request.Page, request.PageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task<long> CreateAsync(CreateReportPageConfigRequest request)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(request.PageName))
|
||||||
|
throw new BusinessException(ErrorCodes.ParamError, "页面标识不能为空");
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(request.Title))
|
||||||
|
throw new BusinessException(ErrorCodes.ParamError, "页面标题不能为空");
|
||||||
|
|
||||||
|
// 检查 PageName 唯一性
|
||||||
|
var exists = await _dbContext.ReportPageConfigs
|
||||||
|
.AnyAsync(p => p.PageName == request.PageName);
|
||||||
|
if (exists)
|
||||||
|
throw new BusinessException(ErrorCodes.ReportPageNameExists, "页面标识已存在");
|
||||||
|
|
||||||
|
var entity = new ReportPageConfig
|
||||||
|
{
|
||||||
|
PageType = request.PageType,
|
||||||
|
PageName = request.PageName,
|
||||||
|
Title = request.Title,
|
||||||
|
SortOrder = request.SortOrder,
|
||||||
|
ImageUrl = request.ImageUrl,
|
||||||
|
RouteUrl = request.RouteUrl,
|
||||||
|
Status = request.Status,
|
||||||
|
CreateTime = DateTime.Now,
|
||||||
|
UpdateTime = DateTime.Now
|
||||||
|
};
|
||||||
|
|
||||||
|
_dbContext.ReportPageConfigs.Add(entity);
|
||||||
|
await _dbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
_logger.LogInformation("创建报告页面配置成功,ID: {Id}, 标题: {Title}", entity.Id, entity.Title);
|
||||||
|
return entity.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task<bool> UpdateAsync(UpdateReportPageConfigRequest request)
|
||||||
|
{
|
||||||
|
var entity = await _dbContext.ReportPageConfigs.FindAsync(request.Id);
|
||||||
|
if (entity == null)
|
||||||
|
throw new BusinessException(ErrorCodes.ReportPageConfigNotFound, "报告页面配置不存在");
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(request.PageName))
|
||||||
|
throw new BusinessException(ErrorCodes.ParamError, "页面标识不能为空");
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(request.Title))
|
||||||
|
throw new BusinessException(ErrorCodes.ParamError, "页面标题不能为空");
|
||||||
|
|
||||||
|
// 检查 PageName 唯一性(排除自身)
|
||||||
|
var exists = await _dbContext.ReportPageConfigs
|
||||||
|
.AnyAsync(p => p.PageName == request.PageName && p.Id != request.Id);
|
||||||
|
if (exists)
|
||||||
|
throw new BusinessException(ErrorCodes.ReportPageNameExists, "页面标识已存在");
|
||||||
|
|
||||||
|
entity.PageType = request.PageType;
|
||||||
|
entity.PageName = request.PageName;
|
||||||
|
entity.Title = request.Title;
|
||||||
|
entity.SortOrder = request.SortOrder;
|
||||||
|
entity.ImageUrl = request.ImageUrl;
|
||||||
|
entity.RouteUrl = request.RouteUrl;
|
||||||
|
entity.Status = request.Status;
|
||||||
|
entity.UpdateTime = DateTime.Now;
|
||||||
|
|
||||||
|
await _dbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
_logger.LogInformation("更新报告页面配置成功,ID: {Id}", entity.Id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task<bool> DeleteAsync(long id)
|
||||||
|
{
|
||||||
|
var entity = await _dbContext.ReportPageConfigs.FindAsync(id);
|
||||||
|
if (entity == null)
|
||||||
|
throw new BusinessException(ErrorCodes.ReportPageConfigNotFound, "报告页面配置不存在");
|
||||||
|
|
||||||
|
_dbContext.ReportPageConfigs.Remove(entity);
|
||||||
|
await _dbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
_logger.LogInformation("删除报告页面配置成功,ID: {Id}", id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task<bool> UpdateStatusAsync(long id, int status)
|
||||||
|
{
|
||||||
|
var entity = await _dbContext.ReportPageConfigs.FindAsync(id);
|
||||||
|
if (entity == null)
|
||||||
|
throw new BusinessException(ErrorCodes.ReportPageConfigNotFound, "报告页面配置不存在");
|
||||||
|
|
||||||
|
entity.Status = status;
|
||||||
|
entity.UpdateTime = DateTime.Now;
|
||||||
|
await _dbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
_logger.LogInformation("更新报告页面配置状态成功,ID: {Id}, 状态: {Status}", id, status);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task<bool> UpdateSortAsync(List<SortItem> items)
|
||||||
|
{
|
||||||
|
if (items == null || items.Count == 0) return true;
|
||||||
|
|
||||||
|
var ids = items.Select(i => i.Id).ToList();
|
||||||
|
var entities = await _dbContext.ReportPageConfigs
|
||||||
|
.Where(p => ids.Contains(p.Id))
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
foreach (var item in items)
|
||||||
|
{
|
||||||
|
var entity = entities.FirstOrDefault(e => e.Id == item.Id);
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
entity.SortOrder = item.Sort;
|
||||||
|
entity.UpdateTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await _dbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
_logger.LogInformation("批量更新报告页面排序成功,更新数量: {Count}", items.Count);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
@page "/report/full"
|
||||||
|
@model MiAssessment.Api.Pages.Report.FullReportModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "测评报告完整预览";
|
||||||
|
Layout = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>测评报告完整预览</title>
|
||||||
|
<link rel="stylesheet" href="/css/pages/full-report.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
@if (!string.IsNullOrEmpty(Model.ErrorMessage))
|
||||||
|
{
|
||||||
|
<div class="full-error">
|
||||||
|
<p>@Model.ErrorMessage</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="full-container">
|
||||||
|
<div class="full-header">
|
||||||
|
<span class="full-header-title">测评报告预览</span>
|
||||||
|
<span class="full-header-count">共 @Model.Pages.Count 页</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="full-pages">
|
||||||
|
@foreach (var item in Model.Pages)
|
||||||
|
{
|
||||||
|
<div class="full-page-wrapper">
|
||||||
|
<div class="full-page-frame">
|
||||||
|
<iframe class="full-page-iframe"
|
||||||
|
data-src="@Model.BuildPageUrl(item.RouteUrl!)"
|
||||||
|
frameborder="0"
|
||||||
|
scrolling="no"
|
||||||
|
title="@item.Title"></iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// IntersectionObserver 懒加载 iframe
|
||||||
|
(function () {
|
||||||
|
var iframes = document.querySelectorAll('iframe.full-page-iframe[data-src]');
|
||||||
|
if (!iframes.length) return;
|
||||||
|
|
||||||
|
var observer = new IntersectionObserver(function (entries) {
|
||||||
|
entries.forEach(function (entry) {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
var iframe = entry.target;
|
||||||
|
if (!iframe.src) {
|
||||||
|
iframe.src = iframe.getAttribute('data-src');
|
||||||
|
}
|
||||||
|
observer.unobserve(iframe);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, {
|
||||||
|
rootMargin: '500px 0px'
|
||||||
|
});
|
||||||
|
|
||||||
|
iframes.forEach(function (iframe) {
|
||||||
|
observer.observe(iframe);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using MiAssessment.Model.Data;
|
||||||
|
using MiAssessment.Model.Entities;
|
||||||
|
|
||||||
|
namespace MiAssessment.Api.Pages.Report;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 报告完整预览页 PageModel
|
||||||
|
/// 路由:/report/full?recordId=3
|
||||||
|
/// 读取 report_page_configs 表,按 SortOrder 顺序展示所有报告页面
|
||||||
|
/// </summary>
|
||||||
|
public class FullReportModel : PageModel
|
||||||
|
{
|
||||||
|
private readonly MiAssessmentDbContext _dbContext;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 测评记录ID
|
||||||
|
/// </summary>
|
||||||
|
public long RecordId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 所有启用的报告页面配置(按 SortOrder 排序)
|
||||||
|
/// </summary>
|
||||||
|
public List<ReportPageConfig> Pages { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 错误信息
|
||||||
|
/// </summary>
|
||||||
|
public string? ErrorMessage { get; set; }
|
||||||
|
|
||||||
|
public FullReportModel(MiAssessmentDbContext dbContext)
|
||||||
|
{
|
||||||
|
_dbContext = dbContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnGetAsync(long? recordId)
|
||||||
|
{
|
||||||
|
if (recordId == null || recordId <= 0)
|
||||||
|
{
|
||||||
|
ErrorMessage = "缺少测评记录参数";
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
RecordId = recordId.Value;
|
||||||
|
|
||||||
|
// 只加载网页截图页(PageType=2),静态图片页有专门的网页不需要在此展示
|
||||||
|
Pages = await _dbContext.ReportPageConfigs
|
||||||
|
.AsNoTracking()
|
||||||
|
.Where(p => p.Status == 1 && p.PageType == 2)
|
||||||
|
.OrderBy(p => p.SortOrder)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return Page();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建 iframe 的完整 URL(自动拼接 recordId)
|
||||||
|
/// </summary>
|
||||||
|
public string BuildPageUrl(string routeUrl)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(routeUrl)) return "";
|
||||||
|
// 如果已有查询参数,用 & 拼接;否则用 ?
|
||||||
|
var separator = routeUrl.Contains('?') ? "&" : "?";
|
||||||
|
return $"{routeUrl}{separator}recordId={RecordId}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
/* 报告完整预览页样式 */
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #e8e8e8;
|
||||||
|
font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 错误提示 */
|
||||||
|
.full-error {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
color: #ff4d4f;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 外层容器 */
|
||||||
|
.full-container {
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px 0 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 顶部信息栏 */
|
||||||
|
.full-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 16px 0 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-header-title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-header-count {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 页面列表 */
|
||||||
|
.full-pages {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 单个页面包装 */
|
||||||
|
.full-page-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 页面框架(固定 1309×926) */
|
||||||
|
.full-page-frame {
|
||||||
|
width: 1309px;
|
||||||
|
height: 926px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* iframe */
|
||||||
|
.full-page-iframe {
|
||||||
|
width: 1309px;
|
||||||
|
height: 926px;
|
||||||
|
border: none;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user