| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- <template>
- <div class="store-page">
- <Breadcrumb />
- <a-card title="抢课回报记录">
- <AppQueryFilter>
- <a-row class="query-row">
- <a-col :flex="'1000px'" class="query-main">
- <a-form class="queryForm app-query-form" :model="query" :label-col-props="{ span: 6 }" :wrapper-col-props="{ span: 18 }" label-align="left">
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item field="name" label="姓名">
- <a-input v-model="query.name" placeholder="任务备注姓名" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item field="student_num" label="学号">
- <a-input v-model="query.student_num" placeholder="学号" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item field="username" label="用户名">
- <a-input v-model="query.username" placeholder="平台用户名" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item field="client_label" label="客户端名称">
- <a-input v-model="query.client_label" placeholder="客户端备注名" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item field="task_id" label="任务 ID">
- <a-input v-model="query.task_id" placeholder="任务 ID" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item field="client_id" label="客户端 ID">
- <a-input v-model="query.client_id" placeholder="client_id" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item field="event" label="回报类型">
- <a-select v-model="query.event" placeholder="全部" allow-clear>
- <a-option value="request_result">单次请求</a-option>
- <a-option value="progress_snapshot">定时进度</a-option>
- <a-option value="grab_success">抢课成功</a-option>
- <a-option value="grab_fail">抢课失败</a-option>
- </a-select>
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item field="queryTime" label="回报时间">
- <a-range-picker v-model="query.queryTime" show-time format="YYYY-MM-DD HH:mm" value-format="x" />
- </a-form-item>
- </a-col>
- </a-row>
- </a-form>
- </a-col>
- <a-divider class="query-divider" style="height: 120px" direction="vertical" />
- <a-col :flex="1" class="app-query-actions">
- <a-space class="query-actions-space" direction="vertical" :size="18">
- <a-button type="primary" @click="search">
- <template #icon><icon-search /></template>
- 搜索
- </a-button>
- <a-button @click="reset">
- <template #icon><icon-refresh /></template>
- 重置
- </a-button>
- </a-space>
- </a-col>
- </a-row>
- </AppQueryFilter>
- <a-table
- row-key="id"
- :data="data"
- :bordered="false"
- hoverable
- class="table"
- :loading="loading"
- :scroll="{ x: 1500 }"
- :pagination="{
- showPageSize: true,
- showJumper: true,
- showTotal: true,
- pageSize: pagination.pagesize,
- current: pagination.current,
- total: pagination.total
- }"
- @page-change="onPageChange"
- @page-size-change="onPageSizeChange"
- >
- <template #columns>
- <a-table-column title="ID" data-index="id" :width="80" />
- <a-table-column title="任务" :width="240">
- <template #cell="{ record }">
- <div>#{{ record.task_id }} {{ record.task_name || '' }}</div>
- <div class="sub-text">学号:{{ record.student_num || '-' }}</div>
- <div v-if="record.username" class="sub-text">用户:{{ record.username }}</div>
- </template>
- </a-table-column>
- <a-table-column title="客户端" :width="220">
- <template #cell="{ record }">
- <div>{{ record.client_label || record.client_id || '-' }}</div>
- <div class="sub-text">{{ record.client_id || '-' }}</div>
- </template>
- </a-table-column>
- <a-table-column title="类型" data-index="event" :width="120">
- <template #cell="{ record }">
- <a-tag :color="eventColor(record.event)">{{ eventLabel(record.event) }}</a-tag>
- </template>
- </a-table-column>
- <a-table-column title="课程" :width="180">
- <template #cell="{ record }">
- <AppTableEllipsis :row-key="`${record.id}-course`" :content="record.course_name || '-'" />
- </template>
- </a-table-column>
- <a-table-column title="回报信息" :width="320">
- <template #cell="{ record }">
- <AppTableEllipsis
- :row-key="`${record.id}-message`"
- :content="record.display_message || record.message || '-'"
- />
- </template>
- </a-table-column>
- <a-table-column title="任务状态" data-index="task_status" :width="100">
- <template #cell="{ record }">
- {{ taskStatusLabel(record.task_status) }}
- </template>
- </a-table-column>
- <a-table-column title="回报时间" :width="180">
- <template #cell="{ record }">
- {{ formatTime(record.create_time) }}
- </template>
- </a-table-column>
- <a-table-column title="详情" :width="90" fixed="right">
- <template #cell="{ record }">
- <a-button type="text" size="small" @click="openDetail(record)">查看</a-button>
- </template>
- </a-table-column>
- </template>
- <template #empty>
- <a-empty description="暂无回报记录" />
- </template>
- </a-table>
- </a-card>
- <a-modal v-model:visible="detailVisible" title="回报详情" :footer="false" width="720px">
- <a-descriptions :column="1" bordered size="small">
- <a-descriptions-item label="任务 ID">{{ detail.task_id }}</a-descriptions-item>
- <a-descriptions-item label="客户端">{{ detail.client_id }}</a-descriptions-item>
- <a-descriptions-item label="类型">{{ eventLabel(detail.event) }}</a-descriptions-item>
- <a-descriptions-item label="课程">{{ detail.course_name || '-' }}</a-descriptions-item>
- <a-descriptions-item label="信息">{{ detail.display_message || detail.message || '-' }}</a-descriptions-item>
- <a-descriptions-item label="时间">{{ formatTime(detail.create_time) }}</a-descriptions-item>
- <a-descriptions-item label="原始数据">
- <pre class="payload-pre">{{ formatPayload(detail.payload_json) }}</pre>
- </a-descriptions-item>
- </a-descriptions>
- </a-modal>
- </div>
- </template>
- <script setup>
- import { onMounted, reactive, ref } from 'vue'
- import { Notification } from '@arco-design/web-vue'
- import { IconRefresh, IconSearch } from '@arco-design/web-vue/es/icon'
- import Breadcrumb from '@/components/Breadcrumb/index.vue'
- import { adminQkReportList } from '@/api/qk'
- const loading = ref(false)
- const data = ref([])
- const detailVisible = ref(false)
- const detail = ref({})
- const pagination = reactive({
- current: 1,
- pagesize: 20,
- total: 0
- })
- const query = reactive({
- name: '',
- student_num: '',
- username: '',
- client_label: '',
- task_id: '',
- client_id: '',
- event: '',
- queryTime: []
- })
- const eventMap = {
- request_result: '单次请求',
- progress_snapshot: '定时进度',
- grab_success: '抢课成功',
- grab_fail: '抢课失败'
- }
- const taskStatusMap = {
- paused: '未开始',
- pending: '待分配',
- assigned: '已分配',
- running: '抢课中',
- success: '成功',
- failed: '失败',
- cancelled: '已取消'
- }
- function eventLabel(event) {
- return eventMap[event] || event || '-'
- }
- function eventColor(event) {
- if (event === 'grab_success') return 'green'
- if (event === 'grab_fail') return 'red'
- if (event === 'progress_snapshot') return 'orange'
- return 'blue'
- }
- function taskStatusLabel(status) {
- return taskStatusMap[status] || status || '-'
- }
- function formatTime(value) {
- if (!value) return '-'
- return new Date(Number(value)).toLocaleString()
- }
- function formatPayload(payload) {
- if (!payload) return '-'
- try {
- return JSON.stringify(payload, null, 2)
- } catch (_) {
- return String(payload)
- }
- }
- function buildParams() {
- const params = {
- current: pagination.current,
- pagesize: pagination.pagesize
- }
- if (query.name) params.name = query.name
- if (query.student_num) params.student_num = query.student_num
- if (query.username) params.username = query.username
- if (query.client_label) params.client_label = query.client_label
- if (query.task_id) params.task_id = query.task_id
- if (query.client_id) params.client_id = query.client_id
- if (query.event) params.event = query.event
- if (Array.isArray(query.queryTime) && query.queryTime.length === 2) {
- params.start_time = query.queryTime[0]
- params.end_time = query.queryTime[1]
- }
- return params
- }
- function fetchList() {
- loading.value = true
- adminQkReportList(buildParams())
- .then((res) => {
- if (res?.code === 0) {
- data.value = res.data?.list || []
- pagination.total = res.data?.total || 0
- pagination.current = res.data?.current || pagination.current
- pagination.pagesize = res.data?.pagesize || pagination.pagesize
- } else {
- Notification.error({ title: '获取回报记录失败', content: res?.msg || '请稍后再试' })
- }
- })
- .catch((error) => {
- Notification.error({ title: '获取回报记录失败', content: error.message || '请稍后再试' })
- })
- .finally(() => {
- loading.value = false
- })
- }
- function search() {
- pagination.current = 1
- fetchList()
- }
- function reset() {
- query.name = ''
- query.student_num = ''
- query.username = ''
- query.client_label = ''
- query.task_id = ''
- query.client_id = ''
- query.event = ''
- query.queryTime = []
- search()
- }
- function onPageChange(page) {
- pagination.current = page
- fetchList()
- }
- function onPageSizeChange(size) {
- pagination.pagesize = size
- pagination.current = 1
- fetchList()
- }
- function openDetail(record) {
- detail.value = record
- detailVisible.value = true
- }
- onMounted(() => {
- fetchList()
- })
- </script>
- <style scoped>
- .sub-text {
- color: var(--color-text-3);
- font-size: 12px;
- }
- .payload-pre {
- margin: 0;
- white-space: pre-wrap;
- word-break: break-all;
- max-height: 320px;
- overflow: auto;
- }
- </style>
|