Browse Source

feat: 表格表头设置

zhangjie 3 tuần trước cách đây
mục cha
commit
152241b001

+ 2 - 0
components.d.ts

@@ -14,6 +14,7 @@ declare module '@vue/runtime-core' {
     ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem'];
     ElButton: typeof import('element-plus/es')['ElButton'];
     ElCheckbox: typeof import('element-plus/es')['ElCheckbox'];
+    ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup'];
     ElCol: typeof import('element-plus/es')['ElCol'];
     ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider'];
     ElDatePicker: typeof import('element-plus/es')['ElDatePicker'];
@@ -63,6 +64,7 @@ declare module '@vue/runtime-core' {
     SelectSubject: typeof import('./src/components/select-subject/index.vue')['default'];
     SelectTeaching: typeof import('./src/components/select-teaching/index.vue')['default'];
     SvgIcon: typeof import('./src/components/svg-icon/index.vue')['default'];
+    TableField: typeof import('./src/components/table-field/index.vue')['default'];
     UploadButton: typeof import('./src/components/upload-button/index.vue')['default'];
   }
   export interface ComponentCustomProperties {

+ 2 - 0
src/components/index.ts

@@ -10,6 +10,7 @@ import UploadButton from './upload-button/index.vue';
 import SelectExam from './select-exam/index.vue';
 import SelectSubject from './select-subject/index.vue';
 import ImportDialog from './import-dialog/index.vue';
+import TableField from './table-field/index.vue';
 
 export default {
   install(Vue: App) {
@@ -22,5 +23,6 @@ export default {
     Vue.component('SelectExam', SelectExam);
     Vue.component('SelectSubject', SelectSubject);
     Vue.component('ImportDialog', ImportDialog);
+    Vue.component('TableField', TableField);
   },
 };

+ 96 - 0
src/components/table-field/index.vue

@@ -0,0 +1,96 @@
+<template>
+  <el-button type="primary" @click="showDialog = true">
+    <el-icon><Setting /></el-icon>
+    表头配置
+  </el-button>
+
+  <el-dialog
+    v-model="showDialog"
+    title="表头配置"
+    width="662px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    top="10vh"
+    append-to-body
+    align-center
+    :close-close="handleClose"
+    @open="initFields"
+  >
+    <el-checkbox-group v-model="selectedFields">
+      <el-checkbox
+        v-for="field in props.fields"
+        :key="field.field"
+        :label="field.field"
+        :value="field.field"
+      >
+        {{ field.name }}
+      </el-checkbox>
+    </el-checkbox-group>
+
+    <template #footer>
+      <el-button @click="showDialog = false">取消</el-button>
+      <el-button type="primary" @click="handleConfirm">确定</el-button>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup lang="ts">
+  import { ref } from 'vue';
+  import { ElMessage } from 'element-plus';
+  import { Setting } from '@element-plus/icons-vue';
+
+  defineOptions({
+    name: 'TableFieldConfig',
+  });
+
+  interface Field {
+    name: string;
+    field: string;
+  }
+
+  const props = withDefaults(
+    defineProps<{
+      fields: Field[];
+      modelValue?: string[];
+    }>(),
+    {
+      fields: () => [],
+      modelValue: () => [],
+    }
+  );
+
+  const emit = defineEmits(['update:modelValue', 'change']);
+
+  const showDialog = ref(false);
+  const originalFields = ref<string[]>([]);
+  const selectedFields = ref<string[]>([]);
+
+  // 初始化字段数据
+  const initFields = () => {
+    // 初始化选中的字段
+    selectedFields.value =
+      props.modelValue.length === 0
+        ? props.fields.map((field) => field.field)
+        : [...props.modelValue];
+    // 保存原始状态用于重置
+    originalFields.value = [...selectedFields.value];
+  };
+
+  // 确认配置
+  const handleConfirm = () => {
+    if (selectedFields.value.length === 0) {
+      ElMessage.warning('请至少选择一个字段');
+      return;
+    }
+    emit('update:modelValue', selectedFields.value);
+    emit('change', selectedFields.value);
+    showDialog.value = false;
+  };
+
+  // 关闭弹窗
+  const handleClose = (done: () => void) => {
+    // 恢复到打开弹窗前的状态
+    selectedFields.value = [...originalFields.value];
+    done();
+  };
+</script>

+ 142 - 23
src/views/student/StudentManage.vue

@@ -161,31 +161,73 @@
         </el-input-number>
       </el-form-item>
     </el-form>
-    <el-space wrap>
-      <el-button type="primary" @click="toPage(1)">查询</el-button>
-      <el-button @click="onAdd">添加</el-button>
-      <el-button type="success" @click="onImport">导入</el-button>
-      <el-button @click="exportData">导出</el-button>
-    </el-space>
+    <div class="box-justify">
+      <el-space wrap>
+        <el-button type="primary" @click="toPage(1)">查询</el-button>
+        <el-button @click="onAdd">添加</el-button>
+        <el-button type="success" @click="onImport">导入</el-button>
+        <el-button @click="exportData">导出</el-button>
+      </el-space>
+
+      <table-field v-model="headFields" :fields="tableFields"></table-field>
+    </div>
   </div>
   <div class="part-box">
     <el-table class="page-table" :data="dataList" :loading="loading">
       <el-table-column type="index" label="序号" width="60" />
-      <el-table-column property="examNo" label="准考证号" width="120" />
-      <el-table-column property="name" label="姓名" min-width="100" />
-      <el-table-column property="studentNo" label="学号" width="120" />
-      <el-table-column property="subject" label="科目" min-width="100" />
-      <el-table-column property="examType" label="试卷类型" width="100" />
-      <el-table-column property="level" label="层次" width="80" />
-      <el-table-column property="majorType" label="专业类型" width="100" />
-      <el-table-column property="college" label="学院" width="120" />
-      <el-table-column property="className" label="班级" width="100" />
-      <el-table-column property="teacher" label="任课老师" width="100" />
-      <el-table-column property="examSite" label="考点" width="100" />
-      <el-table-column property="examRoom" label="考场" width="80" />
-      <el-table-column property="signBookNo" label="签到表编号" width="120" />
-      <el-table-column property="batchNo" label="批次编号" width="100" />
-      <el-table-column label="扫描识别" width="80">
+      <el-table-column
+        v-if="checkFieldVisible('examNo')"
+        property="examNo"
+        label="准考证号"
+        width="120"
+      />
+      <el-table-column
+        v-if="checkFieldVisible('secretNo')"
+        property="secretNo"
+        label="密号"
+        min-width="100"
+      />
+      <el-table-column
+        v-if="checkFieldVisible('name')"
+        property="name"
+        label="姓名"
+        min-width="100"
+      />
+      <el-table-column
+        v-if="checkFieldVisible('studentNo')"
+        property="studentNo"
+        label="学号"
+        width="120"
+      />
+      <el-table-column
+        v-if="checkFieldVisible('subject')"
+        property="subject"
+        label="科目"
+        min-width="100"
+      />
+      <el-table-column
+        v-if="checkFieldVisible('examType')"
+        property="examType"
+        label="试卷类型"
+        width="100"
+      />
+      <el-table-column
+        v-if="checkFieldVisible('level')"
+        property="level"
+        label="层次"
+        width="80"
+      />
+      <el-table-column
+        v-if="checkFieldVisible('majorType')"
+        property="majorType"
+        label="专业类型"
+        width="100"
+      />
+      <el-table-column
+        v-if="checkFieldVisible('scanRecognition')"
+        label="扫描识别"
+        width="80"
+      >
         <template #default="scope">
           <el-tag :type="scope.row.scanRecognition ? 'success' : 'danger'">
             {{ scope.row.scanRecognition ? '是' : '否' }}
@@ -200,14 +242,65 @@
           </el-button>
         </template>
       </el-table-column>
-      <el-table-column property="scanPages" label="扫描张数" width="80" />
-      <el-table-column label="人工指定" width="80">
+      <el-table-column
+        v-if="checkFieldVisible('scanPages')"
+        property="scanPages"
+        label="扫描张数"
+        width="80"
+      />
+      <el-table-column
+        v-if="checkFieldVisible('manualAssign')"
+        label="人工指定"
+        width="80"
+      >
         <template #default="scope">
           <el-tag :type="scope.row.manualAssign ? 'success' : 'danger'">
             {{ scope.row.manualAssign ? '是' : '否' }}
           </el-tag>
         </template>
       </el-table-column>
+      <el-table-column
+        v-if="checkFieldVisible('batchNo')"
+        property="batchNo"
+        label="批次编号"
+        width="100"
+      />
+      <el-table-column
+        v-if="checkFieldVisible('signBookNo')"
+        property="signBookNo"
+        label="签到表编号"
+        width="120"
+      />
+      <el-table-column
+        v-if="checkFieldVisible('college')"
+        property="college"
+        label="学院"
+        width="120"
+      />
+      <el-table-column
+        v-if="checkFieldVisible('className')"
+        property="className"
+        label="班级"
+        width="100"
+      />
+      <el-table-column
+        v-if="checkFieldVisible('teacher')"
+        property="teacher"
+        label="任课老师"
+        width="100"
+      />
+      <el-table-column
+        v-if="checkFieldVisible('examSite')"
+        property="examSite"
+        label="考点"
+        width="100"
+      />
+      <el-table-column
+        v-if="checkFieldVisible('examRoom')"
+        property="examRoom"
+        label="考场"
+        width="80"
+      />
       <el-table-column label="操作" width="100" fixed="right">
         <template #default="scope">
           <el-button size="small" link @click="onEdit(scope.row)">
@@ -286,6 +379,32 @@
   const { dataList, pagination, loading, getList, toPage, pageSizeChange } =
     useTable<StudentItem>(getStudentList, searchModel, false);
 
+  // 表头配置
+  const tableFields = [
+    { name: '准考证号', field: 'examNo' },
+    { name: '密号', field: 'secretNo' },
+    { name: '姓名', field: 'name' },
+    { name: '学号', field: 'studentNo' },
+    { name: '科目', field: 'subject' },
+    { name: '试卷类型', field: 'examType' },
+    { name: '层次', field: 'level' },
+    { name: '专业类型', field: 'majorType' },
+    { name: '扫描识别', field: 'scanRecognition' },
+    { name: '扫描张数', field: 'scanPages' },
+    { name: '人工指定', field: 'manualAssign' },
+    { name: '批次编号', field: 'batchNo' },
+    { name: '签到表编号', field: 'signBookNo' },
+    { name: '学院', field: 'college' },
+    { name: '班级', field: 'className' },
+    { name: '任课老师', field: 'teacher' },
+    { name: '考点', field: 'examSite' },
+    { name: '考场', field: 'examRoom' },
+  ];
+  const headFields = ref(tableFields.map((item) => item.field));
+  const checkFieldVisible = (field: string) => {
+    return headFields.value.includes(field);
+  };
+
   // table action
   const curRow = ref({} as StudentItem);
   const modifyStudentRef = ref();