feat: 新增操作日志功能并优化定时任务配置

1.  新增OperationLogAttribute与OperationLogActionFilter,实现自动化操作日志记录
2.  新增OperationLogRecordInput输入模型,重构IOperationLogService日志接口
3.  为所有业务控制器接口添加操作日志注解
4.  调整期刊AI批改任务的执行周期与方法适配异步调用
5.  优化Hangfire定时任务注册逻辑,支持异步任务
6.  补充完善操作日志类型与目标类型枚举
This commit is contained in:
glz
2026-07-09 18:01:37 +08:00
parent 4bb03aa0df
commit 766be485d0
25 changed files with 1001 additions and 92 deletions

View File

@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
@ -76,6 +77,7 @@ public class AdminController : BaseController
/// </summary>
/// <param name="input">修改密码输入</param>
/// <returns>修改密码结果</returns>
[OperationLog(OperationLogActionType.ChangePassword, OperationLogTargetType.AdminUser, UseOperatorAsTargetId = true, LogArguments = false)]
[HttpPost("changePassword")]
public async Task<BaseResponse<object>> ChangePasswordAsync([FromBody] ChangePasswordInput input)
{
@ -94,6 +96,7 @@ public class AdminController : BaseController
/// </summary>
/// <param name="input">管理员输入</param>
/// <returns>创建的管理员信息</returns>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.AdminUser, TargetNameProperty = "UserName")]
[HttpPost("users")]
public async Task<BaseResponse<AdminUserOutput>> CreateUserAsync([FromBody] AdminUserInput input)
{
@ -120,6 +123,7 @@ public class AdminController : BaseController
/// <param name="id">管理员ID</param>
/// <param name="input">管理员输入</param>
/// <returns>更新后的管理员信息</returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.AdminUser, TargetNameProperty = "UserName")]
[HttpPut("users/{id}")]
public async Task<BaseResponse<AdminUserOutput>> UpdateUserAsync(long id, [FromBody] AdminUserInput input)
{
@ -145,6 +149,7 @@ public class AdminController : BaseController
/// </summary>
/// <param name="id">管理员ID</param>
/// <returns>操作结果</returns>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.AdminUser)]
[HttpDelete("users/{id}")]
public async Task<BaseResponse<object>> DeleteUserAsync(long id)
{
@ -220,6 +225,7 @@ public class AdminController : BaseController
/// </summary>
/// <param name="id">管理员ID</param>
/// <returns>操作结果</returns>
[OperationLog(OperationLogActionType.StatusChange, OperationLogTargetType.AdminUser)]
[HttpPut("users/{id}/status")]
public async Task<BaseResponse<object>> ToggleUserStatusAsync(long id)
{

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
@ -28,6 +29,7 @@ public class AiBasePromptController : BaseController
/// </summary>
/// <param name="input">Prompt配置信息</param>
/// <returns>创建的Prompt配置信息</returns>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.AiBasePrompt)]
[HttpPost]
public async Task<BaseResponse<AiBasePromptOutput>> CreateAsync([FromBody] AiBasePromptInput input)
{
@ -54,6 +56,7 @@ public class AiBasePromptController : BaseController
/// <param name="id">Prompt配置ID</param>
/// <param name="input">Prompt配置信息</param>
/// <returns>更新后的Prompt配置信息</returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.AiBasePrompt)]
[HttpPut("{id}")]
public async Task<BaseResponse<AiBasePromptOutput>> UpdateAsync(long id, [FromBody] AiBasePromptInput input)
{
@ -79,6 +82,7 @@ public class AiBasePromptController : BaseController
/// </summary>
/// <param name="id">Prompt配置ID</param>
/// <returns>操作结果</returns>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.AiBasePrompt)]
[HttpDelete("{id}")]
public async Task<BaseResponse<object>> DeleteAsync(long id)
{
@ -178,6 +182,7 @@ public class AiBasePromptController : BaseController
/// </summary>
/// <param name="id">Prompt配置ID</param>
/// <returns>操作结果</returns>
[OperationLog(OperationLogActionType.StatusChange, OperationLogTargetType.AiBasePrompt)]
[HttpPut("{id}/toggle-status")]
public async Task<BaseResponse<object>> ToggleStatusAsync(long id)
{

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Dto.Banner;
@ -19,6 +20,7 @@ public class BannerController(IBannerService bannerService) : BaseController
/// </summary>
/// <param name="input">轮播图信息</param>
/// <returns>创建后的轮播图信息</returns>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.Banner)]
[HttpPost]
public async Task<BaseResponse<BannerOutput>> CreateAsync([FromBody] BannerInput input)
{
@ -32,6 +34,7 @@ public class BannerController(IBannerService bannerService) : BaseController
/// <param name="id">轮播图ID</param>
/// <param name="input">轮播图信息</param>
/// <returns>更新后的轮播图信息</returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.Banner)]
[HttpPut("{id}")]
public async Task<BaseResponse<BannerOutput>> UpdateAsync(long id, [FromBody] BannerInput input)
{
@ -44,6 +47,7 @@ public class BannerController(IBannerService bannerService) : BaseController
/// </summary>
/// <param name="id">轮播图ID</param>
/// <returns>操作结果</returns>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.Banner)]
[HttpDelete("{id}")]
public async Task<BaseResponse<object>> DeleteAsync(long id)
{
@ -80,6 +84,7 @@ public class BannerController(IBannerService bannerService) : BaseController
/// </summary>
/// <param name="id">轮播图ID</param>
/// <returns>操作结果</returns>
[OperationLog(OperationLogActionType.StatusChange, OperationLogTargetType.Banner)]
[HttpPut("{id}/status")]
public async Task<BaseResponse<bool>> UpdateStatusAsync(long id)
{

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
@ -29,6 +30,7 @@ public class CheckInConfigController : BaseController
/// </summary>
/// <param name="input">签到配置信息</param>
/// <returns>创建的签到配置信息</returns>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.CheckInConfig)]
[HttpPost]
public async Task<BaseResponse<CheckInConfigOutput>> CreateAsync([FromBody] CheckInConfigInput input)
{
@ -55,6 +57,7 @@ public class CheckInConfigController : BaseController
/// <param name="id">签到配置ID</param>
/// <param name="input">签到配置信息</param>
/// <returns>更新后的签到配置信息</returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.CheckInConfig)]
[HttpPut("{id}")]
public async Task<BaseResponse<CheckInConfigOutput>> UpdateAsync(long id, [FromBody] CheckInConfigInput input)
{
@ -80,6 +83,7 @@ public class CheckInConfigController : BaseController
/// </summary>
/// <param name="id">签到配置ID</param>
/// <returns>操作结果</returns>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.CheckInConfig)]
[HttpDelete("{id}")]
public async Task<BaseResponse<object>> DeleteAsync(long id)
{
@ -155,6 +159,7 @@ public class CheckInConfigController : BaseController
/// </summary>
/// <param name="id">签到配置ID</param>
/// <returns>操作结果</returns>
[OperationLog(OperationLogActionType.StatusChange, OperationLogTargetType.CheckInConfig)]
[HttpPut("{id}/status")]
public async Task<BaseResponse<bool>> UpdateStatusAsync(long id)
{

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
@ -72,6 +73,7 @@ public class CommunityMessageController : BaseController
/// <summary>
/// 删除消息
/// </summary>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.CommunityMessage)]
[HttpDelete("{id}")]
public async Task<BaseResponse<object>> DeleteAsync(long id)
{
@ -95,6 +97,7 @@ public class CommunityMessageController : BaseController
/// <summary>
/// 冻结/解冻消息
/// </summary>
[OperationLog(OperationLogActionType.StatusChange, OperationLogTargetType.CommunityMessage)]
[HttpPut("{id}/freeze")]
public async Task<BaseResponse<object>> FreezeAsync(long id, [FromBody] AdminFreezeInput input)
{
@ -118,6 +121,7 @@ public class CommunityMessageController : BaseController
/// <summary>
/// 设置/取消精选
/// </summary>
[OperationLog(OperationLogActionType.StatusChange, OperationLogTargetType.CommunityMessage)]
[HttpPut("{id}/featured")]
public async Task<BaseResponse<object>> SetFeaturedAsync(long id, [FromBody] AdminSetFeaturedInput input)
{
@ -141,6 +145,7 @@ public class CommunityMessageController : BaseController
/// <summary>
/// 设置排序权重
/// </summary>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.CommunityMessage)]
[HttpPut("{id}/sort")]
public async Task<BaseResponse<object>> SetSortOrderAsync(long id, [FromBody] AdminSetSortOrderInput input)
{
@ -164,6 +169,7 @@ public class CommunityMessageController : BaseController
/// <summary>
/// 批量发布消息
/// </summary>
[OperationLog(OperationLogActionType.StatusChange, OperationLogTargetType.CommunityMessage, TargetIdRouteKey = null)]
[HttpPost("batch-publish")]
public async Task<BaseResponse<object>> BatchPublishAsync([FromBody] AdminBatchPublishInput input)
{

View File

@ -6,6 +6,7 @@ using QYZH.InteractiveMagazine.Models.Enum;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
using QYZH.InteractiveMagazine.Infrastructure.OSS;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
@ -76,6 +77,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// </summary>
/// <param name="dto">创建杂志</param>
/// <returns></returns>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.Journal)]
[HttpPost, Route("journal/add")]
public async Task<BaseResponse<long>> AddAsync([FromBody] JournalAddDto dto)
{
@ -88,6 +90,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// </summary>
/// <param name="dto">书籍对象</param>
/// <returns></returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.Journal, TargetIdArgumentName = "dto")]
[HttpPost, Route("journal/update")]
public async Task<BaseResponse> Edit([FromBody] JournalEditDto dto)
{
@ -100,6 +103,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.Journal, TargetIdRouteKey = null)]
[HttpPost, Route("journal/delete")]
public async Task<BaseResponse<bool>> DeleteAsync([Required][FromBody] List<long> ids)
{
@ -111,6 +115,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// 书籍起始页
/// </summary>
/// <returns></returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.Journal)]
[HttpPost, Route("journal/startpage")]
public async Task<BaseResponse<bool>> StartPageAsync([FromQuery]long id, [FromQuery] int index)
{
@ -122,6 +127,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// 书籍归档
/// </summary>
/// <returns></returns>
[OperationLog(OperationLogActionType.StatusChange, OperationLogTargetType.Journal)]
[HttpPost, Route("journal/rchive/{id:long}")]
public async Task<BaseResponse<bool>> Archive(long id)
{
@ -133,6 +139,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// 书籍废弃
/// </summary>
/// <returns></returns>
[OperationLog(OperationLogActionType.StatusChange, OperationLogTargetType.Journal)]
[HttpPost]
[HttpPost, Route("journal/abandon/{id:long}")]
public async Task<BaseResponse<bool>> Abandon(long id)
@ -145,6 +152,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// 书籍发布
/// </summary>
/// <returns></returns>
[OperationLog(OperationLogActionType.StatusChange, OperationLogTargetType.Journal)]
[HttpPost, Route("journal/publish/{id:long}")]
public async Task<BaseResponse<bool>> Publish(long id)
{
@ -156,6 +164,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// 书籍铺码
/// </summary>
/// <returns></returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.Journal)]
[HttpPost, Route("journal/printcode/{id:long}")]
public async Task<BaseResponse<DotMatrixOutput>> PrintCodeAsync(long id)
{
@ -168,6 +177,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// <param name="input"></param>
/// <param name="file"></param>
/// <returns></returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.Journal, TargetIdArgumentName = "input")]
[HttpPost, Route("journal/resultreport")]
public async Task<BaseResponse<bool>> GenerateAsync([FromBody] DotMatrixNoteJournalReportInput input, [FromForm] IFormFile? file)
{
@ -185,6 +195,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.Journal)]
[HttpPost, Route("journal/import")]
public async Task<BaseResponse<long>> JournalImport(JournalImportDto input)
{
@ -266,6 +277,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// <param name="JournalId">file</param>
/// <param name="file">file</param>
/// <returns></returns>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.JournalCatalog, TargetIdRouteKey = "JournalId")]
[HttpPost, Route("catalog/import/{JournalId}")]
public async Task<BaseResponse<bool>> ImportAsync(long JournalId, [FromForm(Name = "file")] IFormFile file)
{
@ -283,6 +295,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.JournalCatalog)]
[HttpPost, Route("catalog/add")]
public async Task<BaseResponse<long>> CatalogAdd(JournalCatalogInput input)
{
@ -294,6 +307,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.JournalCatalog, TargetIdArgumentName = "input")]
[HttpPost, Route("catalog/update")]
public async Task<BaseResponse<bool>> CatalogUpdate(JournalCatalogUpdateInput input)
{
@ -305,6 +319,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.JournalCatalog)]
[HttpPost, Route("catalog/delete/{id:long}")]
public async Task<BaseResponse<bool>> CatalogDelete(long id)
{
@ -318,6 +333,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.JournalCatalog, TargetIdArgumentName = "input")]
[HttpPost, Route("catalog/move")]
public async Task<BaseResponse<bool>> CatalogMove(MoveInput input)
{
@ -333,6 +349,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// 书页新增
/// </summary>
/// <returns></returns>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.JournalPage)]
[HttpPost, Route("page/add")]
public async Task<BaseResponse<long>> PageAdd(JournalAddV2Input input)
{
@ -344,6 +361,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// 书页修改
/// </summary>
/// <returns></returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.JournalPage, TargetIdArgumentName = "input")]
[HttpPost, Route("page/update")]
public async Task<BaseResponse<bool>> PageUpdate(PageLayoutInput input)
{
@ -355,6 +373,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// 自动铺码
/// </summary>
/// <returns></returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.JournalPage, TargetIdRouteKey = "JournalId")]
[HttpPost, Route("page/updatepageno/{JournalId:long}")]
public async Task<BaseResponse<bool>> PageUpdatePageNo([Required(ErrorMessage = "书籍编号不允许为空")] long JournalId)
{
@ -418,6 +437,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// 书页问题新增
/// </summary>
/// <returns></returns>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.JournalPageTask)]
[HttpPost, Route("page/task/add")]
[ProducesResponseType(typeof(BaseResponse<long>), 200)]
public async Task<BaseResponse<long>> PageTaskAdd(JournalPageTaskAddInput input)
@ -430,6 +450,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// 书页问题更新
/// </summary>
/// <returns></returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.JournalPageTask, TargetIdArgumentName = "input")]
[HttpPost, Route("page/task/update")]
[ProducesResponseType(typeof(BaseResponse<bool>), 200)]
public async Task<BaseResponse<bool>> PageTaskUpdate(JournalPageTaskUpdateInput input)
@ -454,6 +475,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// 书页问题删除
/// </summary>
/// <returns></returns>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.JournalPageTask)]
[HttpPost, Route("page/task/delete/{id:long}")]
public async Task<BaseResponse<bool>> PageTaskDelete(long id)
{
@ -465,6 +487,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// 书页问题补充
/// </summary>
/// <returns></returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.JournalPageTask, TargetIdArgumentName = "input")]
[HttpPost, Route("page/task/complement")]
public async Task<BaseResponse<bool>> ComplementAnsync(JournalPageTaskComplementInput input)
{
@ -476,6 +499,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// 答案新增
/// </summary>
/// <returns></returns>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.JournalTaskAnswer)]
[HttpPost, Route("page/task/answer/add")]
public async Task<BaseResponse<long>> AnswerAdd(JournalTaskAnswerAddInput input)
{
@ -487,6 +511,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// 答案更新
/// </summary>
/// <returns></returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.JournalTaskAnswer, TargetIdArgumentName = "input")]
[HttpPost, Route("page/task/answer/update")]
public async Task<BaseResponse<bool>> AnswerUpdate(JournalTaskAnswerUpdateInput input)
{
@ -498,6 +523,7 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
/// 答案删除
/// </summary>
/// <returns></returns>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.JournalTaskAnswer)]
[HttpPost, Route("page/task/answer/delete/{id:long}")]
public async Task<BaseResponse<bool>> AnswerDelete(long id)
{

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Dto.Material;
@ -19,6 +20,7 @@ public class MaterialController(IMaterialService materialService) : BaseControll
/// </summary>
/// <param name="input">资料信息</param>
/// <returns>创建后的资料信息</returns>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.Material)]
[HttpPost]
public async Task<BaseResponse<MaterialOutput>> CreateAsync([FromBody] MaterialInput input)
{
@ -32,6 +34,7 @@ public class MaterialController(IMaterialService materialService) : BaseControll
/// <param name="id">资料ID</param>
/// <param name="input">资料信息</param>
/// <returns>更新后的资料信息</returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.Material)]
[HttpPut("{id}")]
public async Task<BaseResponse<MaterialOutput>> UpdateAsync(long id, [FromBody] MaterialInput input)
{
@ -44,6 +47,7 @@ public class MaterialController(IMaterialService materialService) : BaseControll
/// </summary>
/// <param name="id">资料ID</param>
/// <returns>操作结果</returns>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.Material)]
[HttpDelete("{id}")]
public async Task<BaseResponse<object>> DeleteAsync(long id)
{
@ -80,6 +84,7 @@ public class MaterialController(IMaterialService materialService) : BaseControll
/// </summary>
/// <param name="id">资料ID</param>
/// <returns>操作结果</returns>
[OperationLog(OperationLogActionType.StatusChange, OperationLogTargetType.Material)]
[HttpPut("{id}/status")]
public async Task<BaseResponse<bool>> UpdateStatusAsync(long id)
{

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
@ -28,6 +29,7 @@ public class MedalController : BaseController
/// </summary>
/// <param name="input">勋章信息</param>
/// <returns>创建的勋章信息</returns>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.Medal)]
[HttpPost]
public async Task<BaseResponse<MedalOutput>> CreateAsync([FromBody] MedalInput input)
{
@ -54,6 +56,7 @@ public class MedalController : BaseController
/// <param name="id">勋章ID</param>
/// <param name="input">勋章信息</param>
/// <returns>更新后的勋章信息</returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.Medal)]
[HttpPut("{id}")]
public async Task<BaseResponse<MedalOutput>> UpdateAsync(long id, [FromBody] MedalInput input)
{
@ -79,6 +82,7 @@ public class MedalController : BaseController
/// </summary>
/// <param name="id">勋章ID</param>
/// <returns>操作结果</returns>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.Medal)]
[HttpDelete("{id}")]
public async Task<BaseResponse<object>> DeleteAsync(long id)
{
@ -155,6 +159,7 @@ public class MedalController : BaseController
/// <param name="id">勋章ID</param>
/// <param name="status">状态: 0=禁用, 1=启用</param>
/// <returns>操作结果</returns>
[OperationLog(OperationLogActionType.StatusChange, OperationLogTargetType.Medal)]
[HttpPut("{id}/status")]
public async Task<BaseResponse<bool>> UpdateStatusAsync(long id)
{

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
@ -17,6 +18,7 @@ public class PermissionController(IAdminPermissionService adminPermissionService
/// <summary>
/// 创建菜单
/// </summary>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.AdminMenu)]
[HttpPost("menus")]
public async Task<BaseResponse<AdminMenuOutput>> CreateMenuAsync([FromBody] AdminMenuInput input)
{
@ -27,6 +29,7 @@ public class PermissionController(IAdminPermissionService adminPermissionService
/// <summary>
/// 更新菜单
/// </summary>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.AdminMenu)]
[HttpPut("menus/{id}")]
public async Task<BaseResponse<AdminMenuOutput>> UpdateMenuAsync(long id, [FromBody] AdminMenuInput input)
{
@ -37,6 +40,7 @@ public class PermissionController(IAdminPermissionService adminPermissionService
/// <summary>
/// 删除菜单
/// </summary>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.AdminMenu)]
[HttpDelete("menus/{id}")]
public async Task<BaseResponse<object>> DeleteMenuAsync(long id)
{
@ -70,6 +74,7 @@ public class PermissionController(IAdminPermissionService adminPermissionService
/// <summary>
/// 创建角色
/// </summary>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.AdminRole)]
[HttpPost("roles")]
public async Task<BaseResponse<AdminRoleOutput>> CreateRoleAsync([FromBody] AdminRoleInput input)
{
@ -80,6 +85,7 @@ public class PermissionController(IAdminPermissionService adminPermissionService
/// <summary>
/// 更新角色
/// </summary>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.AdminRole)]
[HttpPut("roles/{id}")]
public async Task<BaseResponse<AdminRoleOutput>> UpdateRoleAsync(long id, [FromBody] AdminRoleInput input)
{
@ -90,6 +96,7 @@ public class PermissionController(IAdminPermissionService adminPermissionService
/// <summary>
/// 删除角色
/// </summary>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.AdminRole)]
[HttpDelete("roles/{id}")]
public async Task<BaseResponse<object>> DeleteRoleAsync(long id)
{
@ -120,6 +127,7 @@ public class PermissionController(IAdminPermissionService adminPermissionService
/// <summary>
/// 分配角色菜单
/// </summary>
[OperationLog(OperationLogActionType.Assign, OperationLogTargetType.AdminRole, TargetIdRouteKey = "roleId")]
[HttpPut("roles/{roleId}/menus")]
public async Task<BaseResponse<object>> AssignRoleMenusAsync(long roleId, [FromBody] AssignRoleMenusInput input)
{
@ -130,6 +138,7 @@ public class PermissionController(IAdminPermissionService adminPermissionService
/// <summary>
/// 分配管理员角色
/// </summary>
[OperationLog(OperationLogActionType.Assign, OperationLogTargetType.AdminUser, TargetIdRouteKey = "adminUserId")]
[HttpPut("users/{adminUserId}/roles")]
public async Task<BaseResponse<object>> AssignAdminUserRolesAsync(long adminUserId, [FromBody] AssignAdminUserRolesInput input)
{

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
@ -29,6 +30,7 @@ public class PetManageController : BaseController
/// <summary>
/// 创建宠物模板
/// </summary>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.Pet)]
[HttpPost]
public async Task<BaseResponse<PetTemplateOutput>> CreateTemplateAsync([FromBody] PetTemplateInput input)
{
@ -52,6 +54,7 @@ public class PetManageController : BaseController
/// <summary>
/// 更新宠物模板
/// </summary>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.Pet)]
[HttpPut("{id}")]
public async Task<BaseResponse<PetTemplateOutput>> UpdateTemplateAsync(long id, [FromBody] PetTemplateInput input)
{
@ -75,6 +78,7 @@ public class PetManageController : BaseController
/// <summary>
/// 删除宠物模板
/// </summary>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.Pet)]
[HttpDelete("{id}")]
public async Task<BaseResponse<object>> DeleteTemplateAsync(long id)
{
@ -144,6 +148,7 @@ public class PetManageController : BaseController
/// <summary>
/// 更新宠物模板状态(启用/禁用)
/// </summary>
[OperationLog(OperationLogActionType.StatusChange, OperationLogTargetType.Pet)]
[HttpPut("{id}/status")]
public async Task<BaseResponse<object>> UpdateTemplateStatusAsync(long id)
{
@ -169,6 +174,7 @@ public class PetManageController : BaseController
/// <summary>
/// 创建进化阶段
/// </summary>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.PetEvolution)]
[HttpPost("evolution")]
public async Task<BaseResponse<PetEvolutionOutput>> CreateEvolutionAsync([FromBody] PetEvolutionInput input)
{
@ -192,6 +198,7 @@ public class PetManageController : BaseController
/// <summary>
/// 更新进化阶段
/// </summary>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.PetEvolution)]
[HttpPut("evolution/{id}")]
public async Task<BaseResponse<PetEvolutionOutput>> UpdateEvolutionAsync(long id, [FromBody] PetEvolutionInput input)
{
@ -215,6 +222,7 @@ public class PetManageController : BaseController
/// <summary>
/// 删除进化阶段
/// </summary>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.PetEvolution)]
[HttpDelete("evolution/{id}")]
public async Task<BaseResponse<object>> DeleteEvolutionAsync(long id)
{
@ -286,6 +294,7 @@ public class PetManageController : BaseController
/// <summary>
/// 创建皮肤
/// </summary>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.PetSkin)]
[HttpPost("skin")]
public async Task<BaseResponse<PetSkinOutput>> CreateSkinAsync([FromBody] PetSkinInput input)
{
@ -309,6 +318,7 @@ public class PetManageController : BaseController
/// <summary>
/// 更新皮肤
/// </summary>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.PetSkin)]
[HttpPut("skin/{id}")]
public async Task<BaseResponse<PetSkinOutput>> UpdateSkinAsync(long id, [FromBody] PetSkinInput input)
{
@ -332,6 +342,7 @@ public class PetManageController : BaseController
/// <summary>
/// 删除皮肤
/// </summary>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.PetSkin)]
[HttpDelete("skin/{id}")]
public async Task<BaseResponse<object>> DeleteSkinAsync(long id)
{
@ -403,6 +414,7 @@ public class PetManageController : BaseController
/// <summary>
/// 创建皮肤图片
/// </summary>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.PetSkinImage)]
[HttpPost("skin-image")]
public async Task<BaseResponse<PetSkinImageOutput>> CreateSkinImageAsync([FromBody] PetSkinImageInput input)
{
@ -426,6 +438,7 @@ public class PetManageController : BaseController
/// <summary>
/// 更新皮肤图片
/// </summary>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.PetSkinImage)]
[HttpPut("skin-image/{id}")]
public async Task<BaseResponse<PetSkinImageOutput>> UpdateSkinImageAsync(long id, [FromBody] PetSkinImageInput input)
{
@ -449,6 +462,7 @@ public class PetManageController : BaseController
/// <summary>
/// 删除皮肤图片
/// </summary>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.PetSkinImage)]
[HttpDelete("skin-image/{id}")]
public async Task<BaseResponse<object>> DeleteSkinImageAsync(long id)
{

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
@ -28,6 +29,7 @@ public class ProductController : BaseController
/// </summary>
/// <param name="input">商品信息</param>
/// <returns>创建的商品信息</returns>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.Product)]
[HttpPost]
public async Task<BaseResponse<ProductOutput>> CreateAsync([FromBody] ProductInput input)
{
@ -54,6 +56,7 @@ public class ProductController : BaseController
/// <param name="id">商品ID</param>
/// <param name="input">商品信息</param>
/// <returns>更新后的商品信息</returns>
[OperationLog(OperationLogActionType.Update, OperationLogTargetType.Product)]
[HttpPut("{id}")]
public async Task<BaseResponse<ProductOutput>> UpdateAsync(long id, [FromBody] ProductInput input)
{
@ -79,6 +82,7 @@ public class ProductController : BaseController
/// </summary>
/// <param name="id">商品ID</param>
/// <returns>操作结果</returns>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.Product)]
[HttpDelete("{id}")]
public async Task<BaseResponse<object>> DeleteAsync(long id)
{
@ -154,6 +158,7 @@ public class ProductController : BaseController
/// </summary>
/// <param name="id">商品ID</param>
/// <returns>操作结果</returns>
[OperationLog(OperationLogActionType.StatusChange, OperationLogTargetType.Product)]
[HttpPut("{id}/status")]
public async Task<BaseResponse<object>> UpdateSaleStatusAsync(long id)
{

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Enum;
@ -18,6 +19,7 @@ public class UserJournalQrCodeController(IUserJournalService userJournalService)
/// </summary>
/// <param name="input">生成输入</param>
/// <returns>二维码记录</returns>
[OperationLog(OperationLogActionType.Create, OperationLogTargetType.UserJournalQrCode)]
[HttpPost("add")]
public async Task<BaseResponse<CreateUserJournalQrCodeOutput>> AddAsync([FromBody] CreateUserJournalQrCodeInput input)
{
@ -66,6 +68,7 @@ public class UserJournalQrCodeController(IUserJournalService userJournalService)
/// </summary>
/// <param name="input">删除输入</param>
/// <returns>是否成功</returns>
[OperationLog(OperationLogActionType.Delete, OperationLogTargetType.UserJournalQrCode, TargetIdRouteKey = null)]
[HttpPost("delete")]
public async Task<BaseResponse<bool>> DeleteAsync([FromBody] DeleteUserJournalQrCodeInput input)
{

View File

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using QYZH.InteractiveMagazine.Infrastructure.Middleware;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
@ -82,6 +83,7 @@ public class UsersController : BaseController
/// <summary>
/// 更新用户状态
/// </summary>
[OperationLog(OperationLogActionType.StatusChange, OperationLogTargetType.User)]
[HttpPut("{id}/status")]
public async Task<BaseResponse> UpdateStatus(long id)
{