183 lines
4.5 KiB
Vue
183 lines
4.5 KiB
Vue
<!-- app/components/dashboard/QaRecordsTable.vue - 最近问答记录表格,基于已准备好的 TableCom -->
|
||
<script lang="ts" setup>
|
||
import { Eye } from "lucide-vue-next";
|
||
import { storeToRefs } from "pinia";
|
||
|
||
import TableCom from "@/components/Table/TableCom.vue";
|
||
import type { TableColumn } from "@/components/Table/type";
|
||
import { Badge } from "@/components/ui/badge";
|
||
import { Button } from "@/components/ui/button";
|
||
import {
|
||
Card,
|
||
CardContent,
|
||
CardDescription,
|
||
CardHeader,
|
||
CardTitle
|
||
} from "@/components/ui/card";
|
||
import {
|
||
Select,
|
||
SelectContent,
|
||
SelectItem,
|
||
SelectTrigger,
|
||
SelectValue
|
||
} from "@/components/ui/select";
|
||
import type { IQaRecord } from "@/interfaces";
|
||
import {
|
||
DASHBOARD_PAGE_SIZE_OPTIONS,
|
||
QUESTION_TYPE_LABELS,
|
||
useAnswerStore
|
||
} from "@/stores/answer";
|
||
|
||
const answerStore = useAnswerStore();
|
||
const {
|
||
pagedRecords,
|
||
recordCount,
|
||
recordsLoading,
|
||
recordsPage,
|
||
recordsPageSize
|
||
} = storeToRefs(answerStore);
|
||
|
||
/** TableCom 列配置集中在组件顶部,便于和其他项目的表格风格保持一致 */
|
||
const columns = computed<TableColumn[]>(() => [
|
||
{
|
||
label: "时间",
|
||
slot: "time",
|
||
width: 170
|
||
},
|
||
{
|
||
label: "题型",
|
||
slot: "type",
|
||
width: 100,
|
||
cellAlign: "center",
|
||
headerAlign: "center"
|
||
},
|
||
{
|
||
label: "题目",
|
||
slot: "question",
|
||
minWidth: 280
|
||
},
|
||
{
|
||
label: "选项",
|
||
slot: "options",
|
||
minWidth: 220
|
||
},
|
||
{
|
||
label: "答案",
|
||
slot: "answer",
|
||
minWidth: 160
|
||
},
|
||
{
|
||
label: "操作",
|
||
slot: "action",
|
||
width: 90,
|
||
cellAlign: "center",
|
||
headerAlign: "center"
|
||
}
|
||
]);
|
||
|
||
/** 题型英文值兜底展示原值,避免未来 OCS 扩展题型时表格为空 */
|
||
const getQuestionTypeLabel = (type: string) => {
|
||
return QUESTION_TYPE_LABELS[type] || type || "自动判断";
|
||
};
|
||
|
||
/** 空选项统一展示占位,不在表格中撑开大段空白 */
|
||
const displayOptions = (record: IQaRecord) => {
|
||
return record.options || "-";
|
||
};
|
||
</script>
|
||
|
||
<template>
|
||
<Card>
|
||
<CardHeader>
|
||
<div class="flex items-center justify-between gap-4">
|
||
<div>
|
||
<CardTitle>最近问答记录</CardTitle>
|
||
<CardDescription>分页展示,按创建时间倒序</CardDescription>
|
||
</div>
|
||
<Select
|
||
:model-value="String(recordsPageSize)"
|
||
@update:model-value="(v) => answerStore.setRecordsPageSize(Number(v))"
|
||
>
|
||
<SelectTrigger class="w-28">
|
||
<SelectValue />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
<SelectItem
|
||
v-for="size in DASHBOARD_PAGE_SIZE_OPTIONS"
|
||
:key="size"
|
||
:value="String(size)"
|
||
>
|
||
{{ size }} 条/页
|
||
</SelectItem>
|
||
</SelectContent>
|
||
</Select>
|
||
</div>
|
||
</CardHeader>
|
||
|
||
<CardContent>
|
||
<TableCom
|
||
:data="pagedRecords"
|
||
:columns="columns"
|
||
:load="recordsLoading"
|
||
:buffer="true"
|
||
:pagination="{
|
||
currentPage: recordsPage,
|
||
total: recordCount,
|
||
pageSize: recordsPageSize,
|
||
align: 'end'
|
||
}"
|
||
cell-align="left"
|
||
header-align="start"
|
||
cell-class-name="align-top"
|
||
@page:change="answerStore.setRecordsPage"
|
||
>
|
||
<template #time="{ value }">
|
||
<span class="whitespace-nowrap text-foreground">{{ value }}</span>
|
||
</template>
|
||
|
||
<template #type="{ value }">
|
||
<Badge variant="secondary" class="text-center">
|
||
{{ getQuestionTypeLabel(value) }}
|
||
</Badge>
|
||
</template>
|
||
|
||
<template #question="{ value }">
|
||
<div class="max-w-136 truncate text-foreground" :title="value">
|
||
{{ value }}
|
||
</div>
|
||
</template>
|
||
|
||
<template #options="{ row }">
|
||
<div
|
||
class="max-w-md truncate text-muted-foreground"
|
||
:title="displayOptions(row)"
|
||
>
|
||
{{ displayOptions(row) }}
|
||
</div>
|
||
</template>
|
||
|
||
<template #answer="{ value }">
|
||
<div
|
||
class="max-w-[20rem] truncate font-medium text-foreground"
|
||
:title="value"
|
||
>
|
||
{{ value }}
|
||
</div>
|
||
</template>
|
||
|
||
<template #action="{ row }">
|
||
<Button
|
||
type="button"
|
||
variant="outline"
|
||
size="icon-sm"
|
||
title="查看详情"
|
||
@click.stop="answerStore.selectRecord(row)"
|
||
>
|
||
<Eye class="size-4" />
|
||
</Button>
|
||
</template>
|
||
</TableCom>
|
||
</CardContent>
|
||
</Card>
|
||
</template>
|