Browse Source

feat: 更新系统名称为飞行学院并添加多项功能改进

refactor(env): 将VITE_TITLE从smilingFace改为飞行学院
feat(user): 添加学号字段及搜索功能
feat(course): 增加课程数量统计和日期选择功能
feat(exam): 添加考试类型筛选和关联试卷类型逻辑
feat(org): 扩展组织表单添加英文名称和图片上传功能
style(watermark): 更新水印文本为飞行学院
docs: 更新代码注释和文档中的系统名称
tanshanming 6 tháng trước cách đây
mục cha
commit
ebbfbbc1d8

+ 1 - 1
.env.development

@@ -2,7 +2,7 @@
 NODE_ENV = development
 
 # 标题
-VITE_TITLE = smilingFace
+VITE_TITLE = 飞行学院
 
 # 接口地址
 VITE_API_BASEURL = http://192.168.1.245:9003

+ 1 - 1
.env.production

@@ -2,7 +2,7 @@
 NODE_ENV = production
 
 # 标题
-VITE_TITLE = smilingFace
+VITE_TITLE = 飞行学院
 
 # 接口地址
 VITE_API_BASEURL = http://192.168.1.245:19003

+ 2 - 2
index.html

@@ -7,7 +7,7 @@
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
     <link rel="icon" href="/favicon.ico">
-    <title>smilingFace</title>
+    <title>飞行学院</title>
     <style>
         .dot {
             animation: antRotate 1.2s infinite linear;
@@ -137,7 +137,7 @@
                 <img src="/img/logo.png" />
             </div>
             <div><span class="dot dot-spin"><i></i><i></i><i></i><i></i></span></div>
-            <div class="app-loading__title">smilingFace</div>
+            <div class="app-loading__title">飞行学院</div>
         </div>
     </div>
     <script type="module" src="/src/main.js"></script>

+ 2 - 2
src/config/index.js

@@ -76,11 +76,11 @@ const DEFAULT_CONFIG = {
 		// 后端接口地址
 		SNOWY_SYS_API_URL: import.meta.env.VITE_API_BASEURL,
 		// 系统名称
-		SNOWY_SYS_NAME: 'smilingFace',
+		SNOWY_SYS_NAME: '飞行学院',
 		// 版本
 		SNOWY_SYS_VERSION: '2.0',
 		// 版权
-		SNOWY_SYS_COPYRIGHT: 'smilingFace',
+		SNOWY_SYS_COPYRIGHT: '飞行学院',
 		// 版权跳转URL
 		SNOWY_SYS_COPYRIGHT_URL: '',
 		// 默认文件存储

+ 4 - 3
src/locales/lang/zh-cn.js

@@ -1,4 +1,3 @@
- 
 import 'dayjs/locale/zh-cn'
 
 export default {
@@ -13,7 +12,8 @@ export default {
 		searchKey: '关键词',
 		imports: '导入',
 		more: '更多',
-		export: '导出'
+		export: '导出',
+		StudentID: '学号'
 	},
 	model: {
 		user: '用户',
@@ -60,6 +60,7 @@ export default {
 		placeholderNameAndSearchKey: '请输入姓名或关键词',
 		placeholderUserStatus: '请选择状态',
 		popconfirmDeleteUser: '确定要删除吗?',
-		popconfirmResatUserPwd: '确定要重置吗?'
+		popconfirmResatUserPwd: '确定要重置吗?',
+		placeholderStudentID: '请输入学号'
 	}
 }

+ 1 - 2
src/utils/watermark.js

@@ -1,4 +1,3 @@
- 
 import tool from '@/utils/tool'
 export const watermark = {
 	set: function (text1, text2) {
@@ -79,6 +78,6 @@ export const watermark = {
 // 使用方法
 // import { watermark } from '@/utils/watermark'
 // 添加水印
-// watermark.set('smilingFace','smilingFace')
+// watermark.set('飞行学院','飞行学院')
 // 移除水印,传 null 移除水印
 // watermark.close()

+ 32 - 2
src/views/courseManagement/components/ListView.vue

@@ -123,6 +123,18 @@
 			dataIndex: 'publishTime',
 			sorter: true
 		},
+		{
+			title: '开设课程数',
+			dataIndex: 'coursesNumber'
+		},
+		{
+			title: '开课数',
+			dataIndex: 'NumberCoursesOffered'
+		},
+		{
+			title: '选课信息',
+			dataIndex: 'CourseSelectionInformation'
+		},
 		{
 			title: '操作',
 			dataIndex: 'action',
@@ -199,11 +211,28 @@
 			getList()
 		})
 	}
+	// 提供假数据的方法,用于展示三个字段:开设课程数、开课数、选课信息
+	const provideMockData = (data) => {
+		if (!data || !data.length) return []
+
+		return data.map((item) => {
+			return {
+				...item,
+				coursesNumber: Math.floor(Math.random() * 10) + 1, // 1-10之间的随机数
+				NumberCoursesOffered: Math.floor(Math.random() * 5) + 1, // 1-5之间的随机数
+				CourseSelectionInformation: `已选${Math.floor(Math.random() * 100)}人/限选${
+					Math.floor(Math.random() * 100) + 50
+				}人`
+			}
+		})
+	}
+
 	const getList = () => {
 		list({ ...pagination.value }).then((data) => {
 			if (data.code == 200) {
 				dataSources.value = []
-				dataSources.value = data.data.records
+				// 使用假数据方法处理返回的数据
+				dataSources.value = provideMockData(data.data.records)
 				pagination.value.current = data.data.current
 				pagination.value.size = data.data.size
 				total.value = data.data.total
@@ -216,7 +245,8 @@
 		pagination.value.current = 1
 		list({ ...pagination.value, ...formState.value }).then((data) => {
 			if (data.code == 200) {
-				dataSources.value = data.data.records
+				// 使用假数据方法处理返回的数据
+				dataSources.value = provideMockData(data.data.records)
 				pagination.value.current = data.data.current
 				pagination.value.size = data.data.size
 				total.value = data.data.total

+ 1 - 1
src/views/courseManagement/index.vue

@@ -40,7 +40,7 @@
 	const courseModalTitle = ref('')
 	const courseInfoId = ref('')
 	const courseDetailModalVisible = ref(false)
-
+	const coursesNumber = ref(10)
 	// 搜索值
 	const searchValue = ref('')
 	const open = ref(false)

+ 59 - 1
src/views/courseOpen/components/DialogView.vue

@@ -91,6 +91,26 @@
 					@change="changeCollegeMajor"
 				/>
 			</a-form-item>
+			<a-form-item label="开始时间" name="startTime">
+				<a-date-picker
+					v-model:value="formState.startTime"
+					placeholder="请选择开始时间"
+					style="width: 100%"
+					format="YYYY-MM-DD"
+					value-format="YYYY-MM-DD"
+				/>
+			</a-form-item>
+
+			<a-form-item label="结束时间" name="endTime">
+				<a-date-picker
+					v-model:value="formState.endTime"
+					placeholder="请选择结束时间"
+					style="width: 100%"
+					format="YYYY-MM-DD"
+					value-format="YYYY-MM-DD"
+				/>
+			</a-form-item>
+
 			<a-form-item label="状态" name="status">
 				<a-select
 					v-model:value="formState.status"
@@ -107,6 +127,7 @@
 	import { reactive, ref } from 'vue'
 	import resourceAuditApi from '@/api/resourceAudit.js'
 	import { downList, userAllList, gradesQueryList, courseinfoAllList } from '@/api/semester/index.js'
+	import dayjs from 'dayjs'
 	const collegeMajorOptions = ref([]) //院系
 	const majorIdName = ref([]) //院系回显
 	const majorOptions = ref([]) //专业
@@ -124,7 +145,7 @@
 	const formRef = ref() //专业
 	const mode = ref('add') //专业
 	const title = ref('添加') //专业
-	import { addItem, detail, editItem } from '@/api/courseopen'
+	import { addItem, detail, editItem } from '@/api/courseOpen'
 	import tool from '@/utils/tool'
 	import { message } from 'ant-design-vue'
 	const visible = ref(false)
@@ -145,6 +166,8 @@
 		endPeriod: undefined,
 		scheduleTime: undefined,
 		weekType: undefined,
+		startTime: undefined,
+		endTime: undefined,
 		status: undefined
 	})
 	const rules = {
@@ -157,6 +180,8 @@
 		endPeriod: [{ required: true, message: '请输入结束节次', trigger: 'blur' }],
 		scheduleTime: [{ required: true, message: '请选择上课周期', trigger: 'change' }],
 		weekType: [{ required: true, message: '请选择单双周', trigger: 'change' }],
+		startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
+		endTime: [{ required: true, message: '请选择结束时间', trigger: 'change' }],
 		status: [{ required: true, message: '请选择状态', trigger: 'change' }]
 	}
 
@@ -198,6 +223,21 @@
 		{ deep: true, immediate: true }
 	)
 
+	// 监听开始时间和结束时间的变化
+	watch(
+		() => [formState.value.startTime, formState.value.endTime],
+		([startTime, endTime]) => {
+			if (startTime && endTime) {
+				const start = dayjs(startTime)
+				const end = dayjs(endTime)
+				if (end.isBefore(start)) {
+					message.error('结束时间不能早于开始时间')
+				}
+			}
+		},
+		{ deep: true }
+	)
+
 	const open = () => {
 		visible.value = true
 		mode.value = 'add'
@@ -220,12 +260,30 @@
 				formState.value.gradesId = Number(formState.value.gradesId)
 				// formState.value.semesterId = Number(formState.value.semesterId)
 
+				// 处理日期格式,确保日期选择器能正确显示
+				if (formState.value.startTime) {
+					formState.value.startTime = dayjs(formState.value.startTime).format('YYYY-MM-DD')
+				}
+				if (formState.value.endTime) {
+					formState.value.endTime = dayjs(formState.value.endTime).format('YYYY-MM-DD')
+				}
+
 				console.log('会先对象', formState.value)
 				// changeCollegeMajor(formState.collegeId)
 			}
 		})
 	}
 	const handleOk = (e) => {
+		// 验证时间逻辑
+		if (formState.value.startTime && formState.value.endTime) {
+			const start = dayjs(formState.value.startTime)
+			const end = dayjs(formState.value.endTime)
+			if (end.isBefore(start)) {
+				message.error('结束时间不能早于开始时间')
+				return
+			}
+		}
+
 		if (startPeriodTag.value == false && endPeriodTag.value == false) {
 			formRef.value.validate().then(() => {
 				let json = JSON.parse(JSON.stringify(formState.value))

+ 17 - 3
src/views/courseOpen/components/ListView.vue

@@ -9,9 +9,11 @@
 		:pagination="false"
 		size="small"
 	>
-		<template #bodyCell="{ column, record }">
-			<!--			<template v-if="column.dataIndex === 'publishTime'">{{ formatTimestamp(text) }}</template>-->
-			<template v-if="column.dataIndex === 'action'">
+		<template #bodyCell="{ column, record, text }">
+			<template v-if="column.dataIndex === 'startTime' || column.dataIndex === 'endTime'">
+				{{ text ? formatDate(text) : '-' }}
+			</template>
+			<template v-else-if="column.dataIndex === 'action'">
 				<!--				<a-button size="small" @click="handleDetail(record)" style="margin-right: 5px">详情</a-button>-->
 				<a-button size="small" @click="handleEdit(record)" style="margin-right: 5px">编辑</a-button>
 				<a-popover v-model:visible="popoverVisibles[record.id]" title="确定删除?" trigger="click">
@@ -48,6 +50,7 @@
 	import { ref, onMounted } from 'vue'
 	import { list, deletess } from '@/api/courseOpen/index.js'
 	import { useRouter } from 'vue-router'
+	import dayjs from 'dayjs'
 
 	const router = useRouter()
 
@@ -83,6 +86,14 @@
 			title: '结束节次',
 			dataIndex: 'endPeriod'
 		},
+		{
+			title: '开始时间',
+			dataIndex: 'startTime'
+		},
+		{
+			title: '结束时间',
+			dataIndex: 'endTime'
+		},
 		{
 			title: '上课周期',
 			dataIndex: 'scheduleTimeName'
@@ -117,6 +128,9 @@
 	const formatTimestamp = (time) => {
 		return tool.formatTimestamp(time)
 	}
+	const formatDate = (date) => {
+		return date ? dayjs(date).format('YYYY-MM-DD') : '-'
+	}
 	const total = ref(0)
 	const pagination = ref({
 		size: 10,

+ 6 - 2
src/views/dev/message/index.vue

@@ -31,7 +31,7 @@
 			:row-key="(record) => record.id"
 			:row-selection="options.rowSelection"
 		>
-			<template #operator class="table-operator">
+			<template #operator>
 				<a-space>
 					<a-button type="primary" @click="form.onOpen()"> 发送站内信 </a-button>
 					<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchEmail" />
@@ -56,6 +56,7 @@
 	import messageApi from '@/api/dev/messageApi'
 	import Form from './form.vue'
 	import Detail from './detail.vue'
+	import dayjs from 'dayjs'
 
 	const columns = [
 		{
@@ -73,7 +74,10 @@
 			dataIndex: 'createTime',
 			ellipsis: true,
 			sorter: true,
-			width: '150px'
+			width: '200px',
+			customRender: ({ text }) => {
+				return dayjs(text).format('YYYY-MM-DD HH:mm:ss')
+			}
 		},
 		{
 			title: '操作',

+ 27 - 9
src/views/exm/examinationManagement/form.vue

@@ -9,6 +9,13 @@
 			:loading="formLoading"
 			layout="horizontal"
 		>
+			<a-form-item label="试卷类型:">
+				<a-select v-model:value="form.examType" placeholder="请选择试卷类型" @change="examTypeChange" allow-clear>
+					<a-select-option v-for="item in examTypeEnum" :key="item.value" :value="item.value">
+						{{ item.label }}
+					</a-select-option>
+				</a-select>
+			</a-form-item>
 			<a-form-item label="考试标题" name="examName" :rules="rules.examName">
 				<a-input v-model:value="form.examName" placeholder="请输入考试标题" />
 			</a-form-item>
@@ -88,12 +95,7 @@
 		>
 			<a-form layout="inline">
 				<a-form-item label="试卷类型">
-					<a-select
-						v-model:value="paperPage.queryParam.paperType"
-						placeholder="请选择试卷类型"
-						@change="paperTypeChange"
-						disabled
-					>
+					<a-select v-model:value="paperPage.queryParam.paperType" placeholder="请选择试卷类型" disabled>
 						<a-select-option v-for="item in paperTypeEnum" :key="item.key" :value="item.key">
 							{{ item.value }}
 						</a-select-option>
@@ -140,7 +142,7 @@
 	import examManagerApi from '@/api/exam/paper/examManager.js'
 	import examPaperApi from '@/api/exam/paper/examPaperApi.js'
 	import resourceAuditApi from '@/api/resourceAudit.js'
-
+	import tool from '@/utils/tool'
 	import dayjs from 'dayjs'
 	const emit = defineEmits(['success'])
 	const props = defineProps({
@@ -151,8 +153,10 @@
 	})
 	const formRef = ref()
 	const examStore = useExamStore()
-	const { subjectEnumFormat } = examStore
-	const paperTypeEnum = computed(() => examStore.paperTypeEnum)
+	const paperTypeEnum = computed(() => examStore.paperTypeEnum.filter((item) => item.key !== '5'))
+	const examTypeEnum = tool.dictList('EXAM_TYPE').filter((item) => item.value !== '3')
+	console.log('examTypeEnum', examTypeEnum)
+	console.log('paperTypeEnum', paperTypeEnum.value)
 	const formLoading = ref(false)
 	const semesterList = ref([])
 	const majorList = ref([])
@@ -274,6 +278,20 @@
 		form.paperId = null
 		selectedPaperName.value = ''
 	}
+	// 考试类型变更
+	const examTypeChange = (type) => {
+		switch (type) {
+			case '1': // 普通考试
+				paperPage.queryParam.paperType = '6'
+				break
+			case '2': // 章节测验
+				paperPage.queryParam.paperType = '3'
+				break
+			case '4': // 课时作业
+				paperPage.queryParam.paperType = '2'
+				break
+		}
+	}
 
 	// 选择试卷
 	const addPaper = () => {

+ 11 - 1
src/views/exm/examinationManagement/index.vue

@@ -1,6 +1,13 @@
 <template>
 	<div class="task-container">
 		<a-form layout="inline" :model="queryParam">
+			<a-form-item label="考试类型:">
+				<a-select v-model:value="queryParam.examType" placeholder="请选择试卷类型" @change="examTypeChange">
+					<a-select-option v-for="item in examTypeEnum" :key="item.value" :value="item.value">
+						{{ item.label }}
+					</a-select-option>
+				</a-select>
+			</a-form-item>
 			<a-form-item label="考试标题:">
 				<a-input v-model:value="queryParam.examName" placeholder="请输入考试标题" style="min-width: 200px" allowClear />
 			</a-form-item>
@@ -98,6 +105,8 @@
 	import { useExamStore } from '@/store/exam.js'
 	import { storeToRefs } from 'pinia'
 	import { parseTime } from '@/utils/exam'
+	import tool from '@/utils/tool'
+
 	const examStore = useExamStore()
 	const { levelEnum, enumFormat } = storeToRefs(examStore)
 	const drawerVisible = ref(false)
@@ -108,13 +117,14 @@
 	const statisticVisible = ref(false)
 	const statisticTitle = ref('')
 	const statisticPaperId = ref(null)
+	const examTypeEnum = tool.dictList('EXAM_TYPE').filter((item) => item.value !== '3')
 
 	const queryParam = reactive({
 		examName: null,
 		examStatus: null,
 		pageIndex: 1,
 		pageSize: 10,
-		examType: 1
+		examType: '1'
 	})
 	const listLoading = ref(false)
 	const tableData = ref([])

+ 2 - 2
src/views/gen/basic.vue

@@ -144,7 +144,7 @@
 					<a-form-item name="moduleName">
 						<template #label>
 							<a-tooltip>
-								<template #title> 代码模块名就是包名后面的代码包,例如:smilingFace.*,*代表此模块名。 </template>
+								<template #title> 代码模块名就是包名后面的代码包,例如:飞行学院.*,*代表此模块名。 </template>
 								<question-circle-outlined />
 							</a-tooltip>
 							&nbsp 模块名:
@@ -359,7 +359,7 @@
 						dbsName: 'master',
 						subDatabase: 'N',
 						pluginName: 'snowy-plugin-biz',
-						packageName: 'smilingFace',
+						packageName: '飞行学院',
 						moduleName: 'biz',
 						tablePrefix: 'Y',
 						generateType: 'ZIP',

+ 18 - 6
src/views/statisticalAnalysis/overviewLearningProgress/index.vue

@@ -222,6 +222,12 @@
 			dataIndex: 'submissionCount',
 			key: 'submissionCount',
 			sorter: true
+		},
+		{
+			title: '退课人数',
+			dataIndex: 'numberStudentsDroppingCourses',
+			key: 'numberStudentsDroppingCourses',
+			sorter: true
 		}
 	]
 
@@ -234,7 +240,8 @@
 			visitCount: 1245,
 			videoDuration: '5h12m30s',
 			documentVisit: 453,
-			submissionCount: 94
+			submissionCount: 94,
+			numberStudentsDroppingCourses: 10
 		},
 		{
 			key: '2',
@@ -243,7 +250,8 @@
 			visitCount: 1087,
 			videoDuration: '5h12m30s',
 			documentVisit: 389,
-			submissionCount: 88
+			submissionCount: 88,
+			numberStudentsDroppingCourses: 12
 		},
 		{
 			key: '3',
@@ -252,7 +260,8 @@
 			visitCount: 987,
 			videoDuration: '5h12m30s',
 			documentVisit: 326,
-			submissionCount: 79
+			submissionCount: 79,
+			numberStudentsDroppingCourses: 15
 		},
 		{
 			key: '4',
@@ -261,7 +270,8 @@
 			visitCount: 856,
 			videoDuration: '5h12m30s',
 			documentVisit: 278,
-			submissionCount: 75
+			submissionCount: 75,
+			numberStudentsDroppingCourses: 18
 		},
 		{
 			key: '5',
@@ -270,7 +280,8 @@
 			visitCount: 723,
 			videoDuration: '5h12m30s',
 			documentVisit: 214,
-			submissionCount: 72
+			submissionCount: 72,
+			numberStudentsDroppingCourses: 20
 		},
 		{
 			key: '6',
@@ -279,7 +290,8 @@
 			visitCount: 634,
 			videoDuration: '5h12m30s',
 			documentVisit: 196,
-			submissionCount: 68
+			submissionCount: 68,
+			numberStudentsDroppingCourses: 22
 		}
 	])
 

+ 3 - 0
src/views/statisticalAnalysis/statisticsHistoryCourseOfferings/index.vue

@@ -0,0 +1,3 @@
+<template>
+	<div>统计历史课程 offerings</div>
+</template>

+ 55 - 0
src/views/sys/org/form.vue

@@ -28,6 +28,23 @@
 			<a-form-item label="组织名称:" name="name">
 				<a-input v-model:value="formData.name" placeholder="请输入组织名称" allow-clear />
 			</a-form-item>
+			<a-form-item label="英文名称:" name="englishName">
+				<a-input v-model:value="formData.englishName" placeholder="请输入英文名称" allow-clear />
+			</a-form-item>
+			<a-form-item label="所在二级单位徽章:" name="badge">
+				<xn-upload upload-mode="defaults" :upload-number="1" @upload-done="handleBadgeUpload" />
+				<div v-if="formData.badge" class="mt-2">
+					<img :src="formData.badge" alt="单位徽章" style="max-width: 100px; max-height: 100px" />
+					<a-button type="link" @click="removeBadge">删除</a-button>
+				</div>
+			</a-form-item>
+			<a-form-item label="单位宣传图:" name="propagandaImage">
+				<xn-upload upload-mode="defaults" :upload-number="1" @upload-done="handlePropagandaImageUpload" />
+				<div v-if="formData.propagandaImage" class="mt-2">
+					<img :src="formData.propagandaImage" alt="单位宣传图" style="max-width: 200px; max-height: 150px" />
+					<a-button type="link" @click="removePropagandaImage">删除</a-button>
+				</div>
+			</a-form-item>
 			<a-form-item label="组织分类:" name="category">
 				<a-select
 					v-model:value="formData.category"
@@ -46,6 +63,19 @@
 				}}</a-tag>
 				<a-input v-show="false" v-model:value="formData.directorId" />
 			</a-form-item>
+			<a-form-item label="二级管理员:" name="directorId">
+				<a-button type="link" style="padding-left: 0px" @click="openSelector(formData.secondaryAdministratorId)"
+					>选择</a-button
+				>
+				<a-tag
+					v-if="formData.secondaryAdministratorId && formData.secondaryAdministratorName"
+					color="orange"
+					closable
+					@close="closeUserTag"
+					>{{ formData.secondaryAdministratorName }}</a-tag
+				>
+				<a-input v-show="false" v-model:value="formData.secondaryAdministratorId" />
+			</a-form-item>
 		</a-form>
 		<template #footer>
 			<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
@@ -67,6 +97,7 @@
 	import orgApi from '@/api/sys/orgApi'
 	import userCenterApi from '@/api/sys/userCenterApi'
 	import UserSelectorPlus from '@/components/Selector/userSelectorPlus.vue'
+	import XnUpload from '@/components/XnUpload/index.vue'
 	import tool from '@/utils/tool'
 
 	// 定义emit事件
@@ -143,6 +174,30 @@
 		formData.value.directorId = ''
 		formData.value.directorName = ''
 	}
+
+	// 处理徽章上传
+	const handleBadgeUpload = (fileList) => {
+		if (fileList && fileList.length > 0) {
+			formData.value.badge = fileList[0].url
+		}
+	}
+
+	// 删除徽章
+	const removeBadge = () => {
+		formData.value.badge = ''
+	}
+
+	// 处理宣传图上传
+	const handlePropagandaImageUpload = (fileList) => {
+		if (fileList && fileList.length > 0) {
+			formData.value.propagandaImage = fileList[0].url
+		}
+	}
+
+	// 删除宣传图
+	const removePropagandaImage = () => {
+		formData.value.propagandaImage = ''
+	}
 	// 验证并提交数据
 	const onSubmit = () => {
 		formRef.value.validate().then(() => {

+ 7 - 2
src/views/sys/user/index.vue

@@ -17,7 +17,7 @@
 			<a-card :bordered="false" style="margin-bottom: 10px">
 				<a-form ref="searchFormRef" name="advanced_search" class="ant-advanced-search-form" :model="searchFormState">
 					<a-row :gutter="24">
-						<a-col :span="8">
+						<a-col :span="4">
 							<a-form-item name="searchKey" :label="$t('common.searchKey')">
 								<a-input
 									v-model:value="searchFormState.searchKey"
@@ -25,7 +25,12 @@
 								/>
 							</a-form-item>
 						</a-col>
-						<a-col :span="8">
+						<a-col :span="4">
+							<a-form-item name="searchKey" :label="$t('common.StudentID')">
+								<a-input v-model:value="searchFormState.studentNum" :placeholder="$t('user.placeholderStudentID')" />
+							</a-form-item>
+						</a-col>
+						<a-col :span="4">
 							<a-form-item name="userStatus" :label="$t('user.userStatus')">
 								<a-select v-model:value="searchFormState.userStatus" :placeholder="$t('user.placeholderUserStatus')">
 									<a-select-option v-for="item in statusData" :key="item.value" :value="item.value">{{