Browse Source

feat: 科目查询

zhangjie 1 week ago
parent
commit
6bc9d2ccd1

+ 1 - 0
components.d.ts

@@ -52,6 +52,7 @@ declare module '@vue/runtime-core' {
     SelectExam: typeof import('./src/components/select-exam/index.vue')['default'];
     SelectRangeDatetime: typeof import('./src/components/select-range-datetime/index.vue')['default'];
     SelectRangeTime: typeof import('./src/components/select-range-time/index.vue')['default'];
+    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'];
     UploadButton: typeof import('./src/components/upload-button/index.vue')['default'];

+ 2 - 0
src/components/index.ts

@@ -6,6 +6,7 @@ import SelectRangeDatetime from './select-range-datetime/index.vue';
 import SelectRangeTime from './select-range-time/index.vue';
 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';
 
 export default {
@@ -15,6 +16,7 @@ export default {
     Vue.component('SelectRangeTime', SelectRangeTime);
     Vue.component('UploadButton', UploadButton);
     Vue.component('SelectExam', SelectExam);
+    Vue.component('SelectSubject', SelectSubject);
     Vue.component('ImportDialog', ImportDialog);
   },
 };

+ 1 - 0
src/components/select-exam/index.vue

@@ -5,6 +5,7 @@
     :clearable="clearable"
     :disabled="disabled"
     filterable
+    default-first-option
     v-bind="attrs"
     @change="onChange"
   >

+ 87 - 0
src/components/select-subject/index.vue

@@ -0,0 +1,87 @@
+<template>
+  <el-select
+    v-model="selected"
+    :placeholder="placeholder"
+    :clearable="clearable"
+    :disabled="disabled"
+    filterable
+    default-first-option
+    v-bind="attrs"
+    @change="onChange"
+  >
+    <el-option
+      v-for="item in optionList"
+      :key="item.value"
+      :label="item.label"
+      :value="item.value"
+    />
+  </el-select>
+</template>
+
+<script setup lang="ts">
+  import { ref, useAttrs, watch } from 'vue';
+  import { subjectQuery } from '@/api/base';
+  import { useAppStore } from '@/store';
+
+  const appStore = useAppStore();
+
+  defineOptions({
+    name: 'SelectSubject',
+  });
+  type ValueType = number | Array<number> | null;
+
+  const props = withDefaults(
+    defineProps<{
+      modelValue: ValueType;
+      clearable?: boolean;
+      disabled?: boolean;
+      placeholder?: string;
+      multiple?: boolean;
+    }>(),
+    {
+      clearable: true,
+      disabled: false,
+      placeholder: '请选择科目',
+      multiple: false,
+    }
+  );
+  const emit = defineEmits(['update:modelValue', 'change']);
+  const attrs = useAttrs();
+
+  interface OptionListItem {
+    value: number;
+    label: string;
+  }
+
+  const selected = ref<number | Array<number> | undefined>();
+  const optionList = ref<OptionListItem[]>([]);
+  const search = async () => {
+    if (!appStore.curExam?.id) return;
+    const res = await subjectQuery(appStore.curExam?.id);
+    optionList.value = res.map((item) => {
+      return { ...item, value: item.id, label: item.name };
+    });
+  };
+  search(); // Initial load
+
+  const onChange = () => {
+    const selectedData = props.multiple
+      ? optionList.value.filter(
+          (item) =>
+            selected.value && (selected.value as number[]).includes(item.value)
+        )
+      : optionList.value.filter((item) => selected.value === item.value);
+    emit('update:modelValue', selected.value || null);
+    emit('change', props.multiple ? selectedData : selectedData[0]);
+  };
+
+  watch(
+    () => props.modelValue,
+    (val) => {
+      selected.value = val || undefined;
+    },
+    {
+      immediate: true,
+    }
+  );
+</script>

+ 1 - 8
src/views/scan/ScanCourseStats.vue

@@ -2,14 +2,7 @@
   <div class="part-box is-filter">
     <el-form inline>
       <el-form-item label="科目">
-        <el-select
-          v-model="searchModel.subject"
-          placeholder="请选择"
-          clearable
-          style="width: 120px"
-        >
-          <el-option label="请选择" value="" />
-        </el-select>
+        <select-subject v-model="searchModel.subject"></select-subject>
       </el-form-item>
       <el-form-item label="层次">
         <el-select

+ 1 - 9
src/views/student/ModifyStudent.vue

@@ -17,15 +17,7 @@
       label-width="100px"
     >
       <el-form-item label="科目" prop="subject">
-        <el-select
-          v-model="formModel.subject"
-          placeholder="请选择科目"
-          style="width: 100%"
-        >
-          <el-option label="201904516-工程图学2" value="201904516-工程图学2" />
-          <el-option label="201904517-高等数学" value="201904517-高等数学" />
-          <el-option label="201904518-大学英语" value="201904518-大学英语" />
-        </el-select>
+        <select-subject v-model="formModel.subject"></select-subject>
       </el-form-item>
       <el-form-item label="姓名" prop="name">
         <el-input v-model="formModel.name" placeholder="请输入姓名" />

+ 1 - 8
src/views/student/StudentManage.vue

@@ -38,14 +38,7 @@
         </el-input>
       </el-form-item>
       <el-form-item label="科目">
-        <el-select
-          v-model="searchModel.subject"
-          placeholder="请选择"
-          clearable
-          style="width: 120px"
-        >
-          <el-option label="请选择" value="" />
-        </el-select>
+        <select-subject v-model="searchModel.subject"></select-subject>
       </el-form-item>
       <el-form-item label="层次">
         <el-select