学生原来只能拿两张表逐格对,看不出要改的是哪几行。现在改过的格子、新插的行标黄, 删掉的行在表下面写「删掉了 2 行(id 是 2、3)」。按第一列配对,对不上就不标。 数据表和期望结果抽成一个组件,后台出题页的预览也用它。 题型判断统一走契约的 isSqlProblem()。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
99 lines
2.4 KiB
Vue
99 lines
2.4 KiB
Vue
<script setup lang="ts">
|
||
import type { SqlDisplayColumn } from "utils/types"
|
||
import type { TableChanges } from "../utils/sqlChanges"
|
||
|
||
const props = defineProps<{
|
||
columns: SqlDisplayColumn[]
|
||
rows: (string | number | null)[][]
|
||
totalRows?: number
|
||
truncated?: boolean
|
||
/** 增删改题执行后的表:变了的格子、新插的行标出来 */
|
||
changes?: TableChanges | null
|
||
}>()
|
||
|
||
const changed = (i: number, j: number) =>
|
||
!!props.changes && (props.changes.newRows.has(i) || props.changes.cells.has(`${i}:${j}`))
|
||
</script>
|
||
|
||
<template>
|
||
<!--
|
||
列多的表横向滚动(设计文档第 8 节)。原来 n-table 固定占满宽度,列一多就把每一列
|
||
挤成一两个字宽,列名和值都折成好几行,对不上哪个值是哪一列的
|
||
-->
|
||
<div class="sqlScroll">
|
||
<n-table class="sqlTable" size="small" :single-line="false">
|
||
<thead>
|
||
<tr>
|
||
<th v-for="(col, i) in columns" :key="i">
|
||
{{ col.name }}
|
||
<span v-if="col.type" class="colType">{{ col.type }}</span>
|
||
</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-if="rows.length === 0">
|
||
<td :colspan="columns.length" class="nullCell">(空表)</td>
|
||
</tr>
|
||
<tr v-for="(row, i) in rows" :key="i">
|
||
<td
|
||
v-for="(v, j) in row"
|
||
:key="j"
|
||
:class="{ nullCell: v === null, changed: changed(i, j) }"
|
||
>
|
||
{{ v === null ? "NULL" : v }}
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</n-table>
|
||
</div>
|
||
<p v-if="truncated" class="truncNote">共 {{ totalRows }} 行,仅展示前 {{ rows.length }} 行</p>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.sqlScroll {
|
||
overflow-x: auto;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
/* 按内容撑开、至少占满一行:列名和值都不折行,放不下就横向滚 */
|
||
.sqlTable {
|
||
width: max-content;
|
||
min-width: 100%;
|
||
}
|
||
|
||
.sqlTable :deep(th),
|
||
.sqlTable :deep(td) {
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.colType {
|
||
font-size: 12px;
|
||
opacity: 0.55;
|
||
margin-left: 4px;
|
||
font-weight: normal;
|
||
}
|
||
|
||
/* 和图例同一个黄:浅底深字,暗色下压暗底、提亮字 */
|
||
.sqlTable :deep(td.changed) {
|
||
background-color: #fff4d6;
|
||
color: #7a4b00;
|
||
font-weight: 600;
|
||
}
|
||
|
||
html.dark .sqlTable :deep(td.changed) {
|
||
background-color: rgba(240, 180, 40, 0.18);
|
||
color: #f5d38a;
|
||
}
|
||
|
||
.nullCell {
|
||
opacity: 0.45;
|
||
font-style: italic;
|
||
}
|
||
|
||
.truncNote {
|
||
font-size: 13px;
|
||
opacity: 0.65;
|
||
margin: 0 0 8px;
|
||
}
|
||
</style>
|