From 138caae4ad5023e6c026ea978e2ce9338ab47a9b Mon Sep 17 00:00:00 2001 From: zpc Date: Wed, 25 Feb 2026 11:20:05 +0800 Subject: [PATCH] 21 --- .../Constants/BusinessPermissions.cs | 6 ++++ .../Controllers/AssessmentRecordController.cs | 29 +++++++++++++++ .../Services/AssessmentRecordService.cs | 19 ++++++++++ .../Interfaces/IAssessmentRecordService.cs | 6 ++++ .../src/api/business/assessmentRecord.ts | 9 +++++ .../business/assessment/record/index.vue | 36 +++++++++++++++++-- .../Cache/RedisService.cs | 20 +++++++---- 7 files changed, 116 insertions(+), 9 deletions(-) diff --git a/server/MiAssessment/src/MiAssessment.Admin.Business/Constants/BusinessPermissions.cs b/server/MiAssessment/src/MiAssessment.Admin.Business/Constants/BusinessPermissions.cs index 6d4992c..8d6090b 100644 --- a/server/MiAssessment/src/MiAssessment.Admin.Business/Constants/BusinessPermissions.cs +++ b/server/MiAssessment/src/MiAssessment.Admin.Business/Constants/BusinessPermissions.cs @@ -257,6 +257,11 @@ public static class BusinessPermissions /// 导出测评记录 /// public const string Export = "assessmentRecord:export"; + + /// + /// 删除测评记录 + /// + public const string Delete = "assessmentRecord:delete"; } #endregion @@ -344,6 +349,7 @@ public static class BusinessPermissions // 测评记录管理模块 new PermissionDefinition(AssessmentRecord.View, "查看测评记录", AssessmentRecord.Module, "查看测评记录列表和详情"), new PermissionDefinition(AssessmentRecord.Export, "导出测评记录", AssessmentRecord.Module, "导出测评记录为Excel文件"), + new PermissionDefinition(AssessmentRecord.Delete, "删除测评记录", AssessmentRecord.Module, "删除测评记录"), // 业务介绍页管理模块 new PermissionDefinition(BusinessPage.View, "查看业务介绍页", BusinessPage.Module, "查看业务介绍页列表和详情"), diff --git a/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/AssessmentRecordController.cs b/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/AssessmentRecordController.cs index 91ee32f..0a243f0 100644 --- a/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/AssessmentRecordController.cs +++ b/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/AssessmentRecordController.cs @@ -184,4 +184,33 @@ public class AssessmentRecordController : BusinessControllerBase } } + /// + /// 删除测评记录 + /// + /// 删除请求 + /// 操作结果 + [HttpPost("delete")] + [BusinessPermission(BusinessPermissions.AssessmentRecord.Delete)] + public async Task Delete([FromBody] RegenerateReportRequest request) + { + if (request.Id <= 0) + { + return ValidationError("测评记录ID无效"); + } + + try + { + await _assessmentRecordService.DeleteRecordAsync(request.Id); + return Ok(); + } + catch (BusinessException ex) + { + return Error(ex.Code, ex.Message); + } + catch (Exception) + { + return Error(ErrorCodes.SystemError, "删除测评记录失败"); + } + } + } diff --git a/server/MiAssessment/src/MiAssessment.Admin.Business/Services/AssessmentRecordService.cs b/server/MiAssessment/src/MiAssessment.Admin.Business/Services/AssessmentRecordService.cs index 475cc44..a4050f7 100644 --- a/server/MiAssessment/src/MiAssessment.Admin.Business/Services/AssessmentRecordService.cs +++ b/server/MiAssessment/src/MiAssessment.Admin.Business/Services/AssessmentRecordService.cs @@ -595,6 +595,25 @@ public class AssessmentRecordService : IAssessmentRecordService }; } + /// + public async Task DeleteRecordAsync(long id) + { + var record = await _dbContext.AssessmentRecords + .FirstOrDefaultAsync(r => r.Id == id && !r.IsDeleted); + + if (record == null) + { + throw new BusinessException(ErrorCodes.AssessmentRecordNotFound, "测评记录不存在"); + } + + // 软删除 + record.IsDeleted = true; + record.UpdateTime = DateTime.Now; + await _dbContext.SaveChangesAsync(); + + _logger.LogInformation("测评记录已删除,ID: {RecordId}", id); + } + #region 私有方法 /// diff --git a/server/MiAssessment/src/MiAssessment.Admin.Business/Services/Interfaces/IAssessmentRecordService.cs b/server/MiAssessment/src/MiAssessment.Admin.Business/Services/Interfaces/IAssessmentRecordService.cs index d6abff5..1c9e750 100644 --- a/server/MiAssessment/src/MiAssessment.Admin.Business/Services/Interfaces/IAssessmentRecordService.cs +++ b/server/MiAssessment/src/MiAssessment.Admin.Business/Services/Interfaces/IAssessmentRecordService.cs @@ -48,4 +48,10 @@ public interface IAssessmentRecordService /// 测评记录ID列表 /// 批量操作结果 Task BatchRegenerateReportAsync(List recordIds); + + /// + /// 删除测评记录(软删除) + /// + /// 记录ID + Task DeleteRecordAsync(long id); } diff --git a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/api/business/assessmentRecord.ts b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/api/business/assessmentRecord.ts index d73df56..b076af0 100644 --- a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/api/business/assessmentRecord.ts +++ b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/api/business/assessmentRecord.ts @@ -158,3 +158,12 @@ export function batchRegenerateReport(ids: number[]): Promise> { + return request({ + url: '/admin/assessmentRecord/delete', + method: 'post', + data: { id } + }) +} diff --git a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/business/assessment/record/index.vue b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/business/assessment/record/index.vue index efd872a..31c3112 100644 --- a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/business/assessment/record/index.vue +++ b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/business/assessment/record/index.vue @@ -108,7 +108,7 @@ - + @@ -286,7 +295,7 @@ * @description 查看用户测评记录、答案详情和测评报告,支持搜索、导出 */ import { reactive, ref, onMounted } from 'vue' -import { Search, Refresh, View, Download, Document, RefreshRight } from '@element-plus/icons-vue' +import { Search, Refresh, View, Download, Document, RefreshRight, Delete } from '@element-plus/icons-vue' import { ElMessage, ElMessageBox } from 'element-plus' import { getRecordList, @@ -295,6 +304,7 @@ import { exportRecords, regenerateReport, batchRegenerateReport, + deleteRecord, type AssessmentRecordItem, type AssessmentRecordDetail, type AssessmentReport, @@ -629,6 +639,28 @@ async function handleBatchRegenerate() { } } +/** 删除测评记录 */ +async function handleDelete(row: AssessmentRecordItem) { + try { + await ElMessageBox.confirm( + `确定要删除记录 ID=${row.id} 吗?删除后不可恢复。`, + '删除测评记录', + { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' } + ) + const res = await deleteRecord(row.id) + if (res.code === 0) { + ElMessage.success('删除成功') + loadRecordList() + } else { + throw new Error(res.message || '删除失败') + } + } catch (error) { + if (error === 'cancel' || (error as any)?.toString?.().includes('cancel')) return + const message = error instanceof Error ? error.message : '删除失败' + ElMessage.error(message) + } +} + async function handleExport() { state.exportLoading = true try { diff --git a/server/MiAssessment/src/MiAssessment.Infrastructure/Cache/RedisService.cs b/server/MiAssessment/src/MiAssessment.Infrastructure/Cache/RedisService.cs index 5f93524..95ab959 100644 --- a/server/MiAssessment/src/MiAssessment.Infrastructure/Cache/RedisService.cs +++ b/server/MiAssessment/src/MiAssessment.Infrastructure/Cache/RedisService.cs @@ -120,14 +120,20 @@ public class RedisService : IRedisService, IDisposable if (_database == null || !_isConnected) return null; - // 使用 BRPOP 命令实现阻塞弹出 - var result = await _database.ExecuteAsync("BRPOP", key, (int)timeout.TotalSeconds); - if (result.IsNull) - return null; + // 使用非阻塞 RPOP + 轮询代替 BRPOP,避免 StackExchange.Redis 命令超时 + // BRPOP 的阻塞时间会超过客户端的 syncTimeout/asyncTimeout 导致 RedisTimeoutException + var deadline = DateTime.UtcNow.Add(timeout); + while (DateTime.UtcNow < deadline) + { + var value = await _database.ListRightPopAsync(key); + if (!value.IsNullOrEmpty) + return value.ToString(); - // BRPOP 返回数组:[key, value] - var results = (RedisResult[])result!; - return results[1].ToString(); + // 空队列时等待 1 秒后重试,避免频繁轮询 + await Task.Delay(1000); + } + + return null; } ///