|
@@ -190,6 +190,7 @@
|
|
|
:loading="loading"
|
|
|
border
|
|
|
stripe
|
|
|
+ @sort-change="handleSortChange"
|
|
|
>
|
|
|
<el-table-column type="index" label="序号" width="60" />
|
|
|
<el-table-column
|
|
@@ -197,30 +198,35 @@
|
|
|
prop="examNumber"
|
|
|
label="准考证号"
|
|
|
width="120"
|
|
|
+ sortable
|
|
|
/>
|
|
|
<el-table-column
|
|
|
v-if="checkFieldVisible('secretNumber')"
|
|
|
prop="secretNumber"
|
|
|
label="密号"
|
|
|
- min-width="100"
|
|
|
+ width="120"
|
|
|
+ sortable
|
|
|
/>
|
|
|
<el-table-column
|
|
|
v-if="checkFieldVisible('name')"
|
|
|
prop="name"
|
|
|
label="姓名"
|
|
|
min-width="100"
|
|
|
+ sortable
|
|
|
/>
|
|
|
<el-table-column
|
|
|
v-if="checkFieldVisible('studentCode')"
|
|
|
prop="studentCode"
|
|
|
label="学号"
|
|
|
width="120"
|
|
|
+ sortable
|
|
|
/>
|
|
|
<el-table-column
|
|
|
- v-if="checkFieldVisible('subjectName')"
|
|
|
- prop="subjectName"
|
|
|
+ v-if="checkFieldVisible('subjectCode')"
|
|
|
+ prop="subjectCode"
|
|
|
label="科目"
|
|
|
- min-width="100"
|
|
|
+ min-width="120"
|
|
|
+ sortable
|
|
|
/>
|
|
|
<el-table-column
|
|
|
v-if="checkFieldVisible('paperType')"
|
|
@@ -245,93 +251,115 @@
|
|
|
label="扫描识别"
|
|
|
width="100"
|
|
|
>
|
|
|
- <!-- TODO: -->
|
|
|
- <template #default="scope">
|
|
|
- <el-tag :type="scope.row.upload ? 'success' : 'danger'">
|
|
|
- {{ scope.row.upload ? '是' : '否' }}
|
|
|
- </el-tag>
|
|
|
- <el-button
|
|
|
- v-if="scope.row.sheetUrls.length > 0"
|
|
|
- size="small"
|
|
|
- type="primary"
|
|
|
- link
|
|
|
- style="margin-left: 5px"
|
|
|
- @click="onPreviewImg(scope.row)"
|
|
|
- >
|
|
|
- 原图
|
|
|
- </el-button>
|
|
|
+ <template #default="{ row }">
|
|
|
+ <span v-if="!row.upload">未上传</span>
|
|
|
+ <template v-else>
|
|
|
+ <!-- 上传 -->
|
|
|
+ <span v-if="appStore.isMultiExam">已上传</span>
|
|
|
+ <el-button v-else type="primary" link @click="onPreviewImg(row)"
|
|
|
+ >已上传</el-button
|
|
|
+ >
|
|
|
+ <!-- 缺考 -->
|
|
|
+ <span class="ml-10">{{ row.absent ? '缺考' : '正常' }}</span>
|
|
|
+ </template>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column
|
|
|
v-if="checkFieldVisible('sheetCount')"
|
|
|
prop="sheetCount"
|
|
|
label="扫描张数"
|
|
|
- width="100"
|
|
|
+ width="120"
|
|
|
+ sortable
|
|
|
/>
|
|
|
<el-table-column
|
|
|
v-if="checkFieldVisible('manualAbsent')"
|
|
|
label="人工指定"
|
|
|
width="100"
|
|
|
>
|
|
|
- <template #default="scope">
|
|
|
- <el-tag :type="scope.row.manualAbsent ? 'success' : 'danger'">
|
|
|
- {{ scope.row.manualAbsent ? '是' : '否' }}
|
|
|
- </el-tag>
|
|
|
+ <template #default="{ row }">
|
|
|
+ <!-- 违纪 -->
|
|
|
+ <template v-if="row.breach">
|
|
|
+ <el-button
|
|
|
+ v-if="userStore.isSchoolAdmin"
|
|
|
+ type="danger"
|
|
|
+ link
|
|
|
+ @click="onChangeBreach(row)"
|
|
|
+ >违纪</el-button
|
|
|
+ >
|
|
|
+ <span v-else>违纪</span>
|
|
|
+ </template>
|
|
|
+ <span v-else>正常</span>
|
|
|
+ <!-- 人工指定缺考 -->
|
|
|
+ <span class="ml-10">{{
|
|
|
+ row.manualAbsent ? '人工指定' : '正常'
|
|
|
+ }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column
|
|
|
v-if="checkFieldVisible('batchCode')"
|
|
|
prop="batchCode"
|
|
|
label="批次编号"
|
|
|
- width="100"
|
|
|
+ width="120"
|
|
|
+ sortable
|
|
|
/>
|
|
|
<el-table-column
|
|
|
v-if="checkFieldVisible('packageCode')"
|
|
|
prop="packageCode"
|
|
|
label="签到表编号"
|
|
|
width="120"
|
|
|
+ sortable
|
|
|
/>
|
|
|
<el-table-column
|
|
|
v-if="checkFieldVisible('college')"
|
|
|
prop="college"
|
|
|
label="学院"
|
|
|
width="120"
|
|
|
+ sortable
|
|
|
/>
|
|
|
<el-table-column
|
|
|
v-if="checkFieldVisible('className')"
|
|
|
prop="className"
|
|
|
label="班级"
|
|
|
width="100"
|
|
|
+ sortable
|
|
|
/>
|
|
|
<el-table-column
|
|
|
v-if="checkFieldVisible('teacher')"
|
|
|
prop="teacher"
|
|
|
label="任课老师"
|
|
|
- width="100"
|
|
|
+ width="120"
|
|
|
+ sortable
|
|
|
/>
|
|
|
<el-table-column
|
|
|
v-if="checkFieldVisible('examSite')"
|
|
|
prop="examSite"
|
|
|
label="考点"
|
|
|
width="100"
|
|
|
+ sortable
|
|
|
/>
|
|
|
<el-table-column
|
|
|
v-if="checkFieldVisible('examRoom')"
|
|
|
prop="examRoom"
|
|
|
label="考场"
|
|
|
width="80"
|
|
|
+ sortable
|
|
|
/>
|
|
|
<el-table-column label="操作" width="120" fixed="right">
|
|
|
- <template #default="scope">
|
|
|
+ <template v-if="userStore.isSchoolAdmin" #default="scope">
|
|
|
<el-button
|
|
|
size="small"
|
|
|
type="primary"
|
|
|
link
|
|
|
@click="onEdit(scope.row)"
|
|
|
>
|
|
|
- 编辑
|
|
|
+ 修改
|
|
|
</el-button>
|
|
|
- <el-button size="small" type="danger" link @click="onDelete(row)"
|
|
|
+ <el-button
|
|
|
+ v-if="!appStore.isMultiExam"
|
|
|
+ size="small"
|
|
|
+ type="danger"
|
|
|
+ link
|
|
|
+ @click="onDelete(row)"
|
|
|
>删除</el-button
|
|
|
>
|
|
|
</template>
|
|
@@ -387,13 +415,13 @@
|
|
|
import { reactive, ref, computed } from 'vue';
|
|
|
import { CaretBottom } from '@element-plus/icons-vue';
|
|
|
import { ElMessage } from 'element-plus';
|
|
|
- import { getStudentList, deleteStudent } from '@/api/student';
|
|
|
+ import { getStudentList, deleteStudent, resetBreach } from '@/api/student';
|
|
|
import { StudentItem, StudentListFilter } from '@/api/types/student';
|
|
|
import useTable from '@/hooks/table';
|
|
|
import useLoading from '@/hooks/loading';
|
|
|
import { modalConfirm } from '@/utils/ui';
|
|
|
import { downloadExport } from '@/utils/download-export';
|
|
|
- import { useAppStore } from '@/store';
|
|
|
+ import { useAppStore, useUserStore } from '@/store';
|
|
|
|
|
|
import ModifyStudent from './ModifyStudent.vue';
|
|
|
|
|
@@ -402,6 +430,7 @@
|
|
|
});
|
|
|
|
|
|
const appStore = useAppStore();
|
|
|
+ const userStore = useUserStore();
|
|
|
|
|
|
const searchModel = reactive<StudentListFilter>({
|
|
|
name: '',
|
|
@@ -425,8 +454,15 @@
|
|
|
sheetCount: undefined,
|
|
|
});
|
|
|
|
|
|
- const { dataList, pagination, loading, getList, toPage, pageSizeChange } =
|
|
|
- useTable<StudentItem>(getStudentList, searchModel, false);
|
|
|
+ const {
|
|
|
+ dataList,
|
|
|
+ pagination,
|
|
|
+ loading,
|
|
|
+ getList,
|
|
|
+ toPage,
|
|
|
+ pageSizeChange,
|
|
|
+ handleSortChange,
|
|
|
+ } = useTable<StudentItem>(getStudentList, searchModel, false);
|
|
|
|
|
|
// 表头配置
|
|
|
const tableFields = [
|
|
@@ -434,7 +470,7 @@
|
|
|
{ name: '密号', field: 'secretNumber' },
|
|
|
{ name: '姓名', field: 'name' },
|
|
|
{ name: '学号', field: 'studentCode' },
|
|
|
- { name: '科目', field: 'subjectName' },
|
|
|
+ { name: '科目', field: 'subjectCode' },
|
|
|
{ name: '试卷类型', field: 'paperType' },
|
|
|
{ name: '层次', field: 'subjectLevel' },
|
|
|
{ name: '专业类型', field: 'subjectCategory' },
|
|
@@ -468,12 +504,33 @@
|
|
|
modifyStudentRef.value?.open();
|
|
|
}
|
|
|
|
|
|
+ const { loading: breachLoading, setLoading: setBreachLoading } = useLoading();
|
|
|
+ async function onChangeBreach(row: StudentItem) {
|
|
|
+ if (breachLoading.value) return;
|
|
|
+ const confirm = await modalConfirm(
|
|
|
+ `确认要将该考生违纪重置为正常?`,
|
|
|
+ '删除确认'
|
|
|
+ ).catch(() => false);
|
|
|
+ if (!confirm) return;
|
|
|
+
|
|
|
+ try {
|
|
|
+ setBreachLoading(true);
|
|
|
+ await resetBreach(row.id);
|
|
|
+ ElMessage.success('重置成功');
|
|
|
+ getList();
|
|
|
+ } catch (error) {
|
|
|
+ console.log('重置失败:', error);
|
|
|
+ } finally {
|
|
|
+ setBreachLoading(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// 删除
|
|
|
const { loading: deleteLoading, setLoading: setDeleteLoading } = useLoading();
|
|
|
async function onDelete(row: StudentItem) {
|
|
|
if (deleteLoading.value) return;
|
|
|
const confirm = await modalConfirm(
|
|
|
- `确定要删除分类"${row.name}"吗?`,
|
|
|
+ `确定要删除考生"${row.name}"吗?`,
|
|
|
'删除确认'
|
|
|
).catch(() => false);
|
|
|
if (!confirm) return;
|