21
This commit is contained in:
parent
ebb5225b2d
commit
934530c7f9
|
|
@ -135,3 +135,26 @@ export function exportRecords(params: AssessmentRecordQuery): Promise<ApiRespons
|
||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
/** 批量重新生成结果 */
|
||||||
|
export interface BatchRegenerateResult {
|
||||||
|
successCount: number
|
||||||
|
skippedCount: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重新生成报告 */
|
||||||
|
export function regenerateReport(id: number): Promise<ApiResponse<null>> {
|
||||||
|
return request<null>({
|
||||||
|
url: '/admin/assessmentRecord/regenerateReport',
|
||||||
|
method: 'post',
|
||||||
|
data: { id }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 批量重新生成报告 */
|
||||||
|
export function batchRegenerateReport(ids: number[]): Promise<ApiResponse<BatchRegenerateResult>> {
|
||||||
|
return request<BatchRegenerateResult>({
|
||||||
|
url: '/admin/assessmentRecord/batchRegenerateReport',
|
||||||
|
method: 'post',
|
||||||
|
data: { ids }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,10 @@
|
||||||
<span class="page-description">查看用户测评记录、答案详情和测评报告</span>
|
<span class="page-description">查看用户测评记录、答案详情和测评报告</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
|
<el-button type="warning" @click="handleBatchRegenerate" :loading="state.batchRegenerateLoading">
|
||||||
|
<el-icon><RefreshRight /></el-icon>
|
||||||
|
批量重新生成
|
||||||
|
</el-button>
|
||||||
<el-button type="success" @click="handleExport" :loading="state.exportLoading">
|
<el-button type="success" @click="handleExport" :loading="state.exportLoading">
|
||||||
<el-icon><Download /></el-icon>
|
<el-icon><Download /></el-icon>
|
||||||
导出Excel
|
导出Excel
|
||||||
|
|
@ -33,6 +37,7 @@
|
||||||
<el-option label="测评中" :value="2" />
|
<el-option label="测评中" :value="2" />
|
||||||
<el-option label="生成中" :value="3" />
|
<el-option label="生成中" :value="3" />
|
||||||
<el-option label="已完成" :value="4" />
|
<el-option label="已完成" :value="4" />
|
||||||
|
<el-option label="生成失败" :value="5" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="创建时间">
|
<el-form-item label="创建时间">
|
||||||
|
|
@ -62,7 +67,8 @@
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
<!-- 数据表格 -->
|
||||||
<el-card v-loading="state.loading" class="table-card">
|
<el-card v-loading="state.loading" class="table-card">
|
||||||
<el-table :data="state.tableData" row-key="id" stripe>
|
<el-table :data="state.tableData" row-key="id" stripe @selection-change="handleSelectionChange">
|
||||||
|
<el-table-column type="selection" width="50" />
|
||||||
<el-table-column prop="id" label="ID" width="80" />
|
<el-table-column prop="id" label="ID" width="80" />
|
||||||
<el-table-column label="用户" min-width="120">
|
<el-table-column label="用户" min-width="120">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
|
|
@ -102,7 +108,7 @@
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createTime" label="创建时间" width="170" align="center" />
|
<el-table-column prop="createTime" label="创建时间" width="170" align="center" />
|
||||||
<el-table-column label="操作" width="160" fixed="right" align="center">
|
<el-table-column label="操作" width="230" fixed="right" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button type="primary" link size="small" @click="handleViewDetail(row)">
|
<el-button type="primary" link size="small" @click="handleViewDetail(row)">
|
||||||
<el-icon><View /></el-icon>
|
<el-icon><View /></el-icon>
|
||||||
|
|
@ -118,6 +124,16 @@
|
||||||
<el-icon><Document /></el-icon>
|
<el-icon><Document /></el-icon>
|
||||||
报告
|
报告
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="row.status === 3 || row.status === 5"
|
||||||
|
type="warning"
|
||||||
|
link
|
||||||
|
size="small"
|
||||||
|
@click="handleRegenerate(row)"
|
||||||
|
>
|
||||||
|
<el-icon><RefreshRight /></el-icon>
|
||||||
|
重新生成
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
@ -270,13 +286,15 @@
|
||||||
* @description 查看用户测评记录、答案详情和测评报告,支持搜索、导出
|
* @description 查看用户测评记录、答案详情和测评报告,支持搜索、导出
|
||||||
*/
|
*/
|
||||||
import { reactive, ref, onMounted } from 'vue'
|
import { reactive, ref, onMounted } from 'vue'
|
||||||
import { Search, Refresh, View, Download, Document } from '@element-plus/icons-vue'
|
import { Search, Refresh, View, Download, Document, RefreshRight } from '@element-plus/icons-vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import {
|
import {
|
||||||
getRecordList,
|
getRecordList,
|
||||||
getRecordDetail,
|
getRecordDetail,
|
||||||
getRecordReport,
|
getRecordReport,
|
||||||
exportRecords,
|
exportRecords,
|
||||||
|
regenerateReport,
|
||||||
|
batchRegenerateReport,
|
||||||
type AssessmentRecordItem,
|
type AssessmentRecordItem,
|
||||||
type AssessmentRecordDetail,
|
type AssessmentRecordDetail,
|
||||||
type AssessmentReport,
|
type AssessmentReport,
|
||||||
|
|
@ -331,6 +349,8 @@ interface RecordPageState {
|
||||||
report: AssessmentReport | null
|
report: AssessmentReport | null
|
||||||
exportLoading: boolean
|
exportLoading: boolean
|
||||||
scoreOptionMap: Map<number, ScoreOptionItem>
|
scoreOptionMap: Map<number, ScoreOptionItem>
|
||||||
|
batchRegenerateLoading: boolean
|
||||||
|
selectedRows: AssessmentRecordItem[]
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============ Refs ============
|
// ============ Refs ============
|
||||||
|
|
@ -359,7 +379,9 @@ const state = reactive<RecordPageState>({
|
||||||
reportLoading: false,
|
reportLoading: false,
|
||||||
report: null,
|
report: null,
|
||||||
exportLoading: false,
|
exportLoading: false,
|
||||||
scoreOptionMap: new Map()
|
scoreOptionMap: new Map(),
|
||||||
|
batchRegenerateLoading: false,
|
||||||
|
selectedRows: []
|
||||||
})
|
})
|
||||||
|
|
||||||
// ============ Helper Functions ============
|
// ============ Helper Functions ============
|
||||||
|
|
@ -368,12 +390,13 @@ const state = reactive<RecordPageState>({
|
||||||
* 获取状态标签类型
|
* 获取状态标签类型
|
||||||
* 待测评=info, 测评中=primary, 生成中=warning, 已完成=success
|
* 待测评=info, 测评中=primary, 生成中=warning, 已完成=success
|
||||||
*/
|
*/
|
||||||
function getStatusTagType(status: number): 'info' | 'primary' | 'warning' | 'success' {
|
function getStatusTagType(status: number): 'info' | 'primary' | 'warning' | 'success' | 'danger' {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 1: return 'info'
|
case 1: return 'info'
|
||||||
case 2: return 'primary'
|
case 2: return 'primary'
|
||||||
case 3: return 'warning'
|
case 3: return 'warning'
|
||||||
case 4: return 'success'
|
case 4: return 'success'
|
||||||
|
case 5: return 'danger'
|
||||||
default: return 'info'
|
default: return 'info'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -547,6 +570,65 @@ function handleViewReport(row: AssessmentRecordItem) {
|
||||||
loadRecordReport(row.id)
|
loadRecordReport(row.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 表格选择变化 */
|
||||||
|
function handleSelectionChange(rows: AssessmentRecordItem[]) {
|
||||||
|
state.selectedRows = rows
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 单条重新生成报告 */
|
||||||
|
async function handleRegenerate(row: AssessmentRecordItem) {
|
||||||
|
try {
|
||||||
|
await ElMessageBox.confirm(
|
||||||
|
`确定要重新生成记录 ID=${row.id} 的报告吗?`,
|
||||||
|
'重新生成报告',
|
||||||
|
{ confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }
|
||||||
|
)
|
||||||
|
const res = await regenerateReport(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 handleBatchRegenerate() {
|
||||||
|
const eligibleRows = state.selectedRows.filter(r => r.status === 3 || r.status === 5)
|
||||||
|
if (eligibleRows.length === 0) {
|
||||||
|
ElMessage.warning('请先勾选状态为"生成中"或"生成失败"的记录')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await ElMessageBox.confirm(
|
||||||
|
`已选中 ${eligibleRows.length} 条符合条件的记录,确定批量重新生成?`,
|
||||||
|
'批量重新生成报告',
|
||||||
|
{ confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }
|
||||||
|
)
|
||||||
|
state.batchRegenerateLoading = true
|
||||||
|
const ids = eligibleRows.map(r => r.id)
|
||||||
|
const res = await batchRegenerateReport(ids)
|
||||||
|
if (res.code === 0) {
|
||||||
|
const { successCount, skippedCount } = res.data!
|
||||||
|
ElMessage.success(`成功入队 ${successCount} 条,跳过 ${skippedCount} 条`)
|
||||||
|
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)
|
||||||
|
} finally {
|
||||||
|
state.batchRegenerateLoading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function handleExport() {
|
async function handleExport() {
|
||||||
state.exportLoading = true
|
state.exportLoading = true
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user