diff --git a/src/views/teacherEnd/student/index.vue b/src/views/teacherEnd/student/index.vue
index 81cd6cb..d2d7b21 100644
--- a/src/views/teacherEnd/student/index.vue
+++ b/src/views/teacherEnd/student/index.vue
@@ -12,7 +12,7 @@
班级:
-
+
@@ -70,6 +70,7 @@
编辑
删除
密码初始化
+ 数据初始化
仅查看
@@ -186,7 +187,7 @@ const status = ref(false);
const tableData = ref([]);
// 获取院校列表
const getList = () => {
- indexApi.getStudentList(paramsquery.value).then((res) => {
+ indexApi.getStudentList({ ...paramsquery.value, operatorId: currentUserId.value }).then((res) => {
tableData.value = res.data.list;
schoolTotal.value = res.data.total;
});
@@ -303,6 +304,18 @@ const getMajorList = () => {
});
};
const uploadStudents = (options) => {
+ if (isTeacherRosterMode.value) {
+ const teachingClassId = currentTeachingClassId();
+ if (!teachingClassId) {
+ proxy.$message.warning("请选择自己的教学班后再导入学生");
+ return Promise.reject(new Error("teaching class is required"));
+ }
+ const formData = new FormData();
+ formData.append("file", options.file);
+ return indexApi.importTeacherRosterMembers(teachingClassId, formData).then((res) => {
+ handleSuccess(res);
+ });
+ }
const formData = buildStudentImportFormData(options.file);
return indexApi.importTeacherStudents(formData).then((res) => {
handleSuccess(res);
@@ -318,7 +331,7 @@ const handleSuccess = (res, file) => {
};
// 导出教师账号
const exportTeacher = () => {
- indexApi.exportStudentList({ schoolId: userStore.userInfo.schoolId }).then((res) => {
+ indexApi.exportStudentList({ schoolId: userStore.userInfo.schoolId, operatorId: currentUserId.value, schoolClassId: currentTeachingClassId() }).then((res) => {
const blob = new Blob([res], { type: "application/vnd.ms-excel" });
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
@@ -351,6 +364,17 @@ const buildOwnedAdminClassRows = async () => {
const downloadTemplate = async () => {
const XLSX = await import("xlsx");
+ if (isTeacherRosterMode.value) {
+ const templateSheet = XLSX.utils.aoa_to_sheet([
+ ["学生姓名", "学号"],
+ ["张三", "20260001"],
+ ]);
+ templateSheet["!cols"] = [{ wch: 16 }, { wch: 18 }];
+ const workbook = XLSX.utils.book_new();
+ XLSX.utils.book_append_sheet(workbook, templateSheet, "学生导入模板");
+ XLSX.writeFile(workbook, "学生账号导入模板.xlsx");
+ return;
+ }
const adminClassRows = await buildOwnedAdminClassRows();
const firstAdminClass = adminClassRows[0] || ["电子商务学院", "电子商务", "行政一班"];
const templateSheet = XLSX.utils.aoa_to_sheet([
@@ -389,6 +413,9 @@ const canUseAdminClassForStudent = (schoolClass) => {
};
const classMap = computed(() => new Map(classList.value.map((item) => [item.schoolClassId, item])));
const adminClassList = computed(() => classList.value.filter((item) => canUseAdminClassForStudent(item)));
+const studentClassOptions = computed(() =>
+ isTeacherRosterMode.value ? teachingClassOptions.value : adminClassList.value
+);
const teachingClassOptions = computed(() =>
classList.value.filter(
(schoolClass) =>
@@ -399,6 +426,11 @@ const teachingClassOptions = computed(() =>
);
const canOperateStudent = (row) => {
const selectedClass = classMap.value.get(paramsquery.value.schoolClassId);
+ if (isTeacherRosterMode.value) {
+ return Boolean(selectedClass)
+ && normalizeClassType(selectedClass) === "TEACHING"
+ && sameValue(selectedClass.createdBy, currentUserId.value);
+ }
if (selectedClass && normalizeClassType(selectedClass) === "TEACHING") {
return sameValue(selectedClass.createdBy, currentUserId.value);
}
diff --git a/tests/teacher-owned-student-management.static.test.cjs b/tests/teacher-owned-student-management.static.test.cjs
new file mode 100644
index 0000000..a74ffbf
--- /dev/null
+++ b/tests/teacher-owned-student-management.static.test.cjs
@@ -0,0 +1,13 @@
+const assert = require("assert");
+const fs = require("fs");
+const path = require("path");
+const root = path.join(__dirname, "..");
+const page = fs.readFileSync(path.join(root, "src", "views", "teacherEnd", "student", "index.vue"), "utf8");
+
+assert(page.includes("operatorId: currentUserId.value"), "学生列表必须携带当前教师");
+assert(page.includes("isTeacherRosterMode.value ? teachingClassOptions.value : adminClassList.value"), "教学班模式必须只显示教师自有教学班");
+assert(page.includes("请选择自己的教学班后再导入学生"), "导入必须要求选中教学班");
+assert(page.includes('["学生姓名", "学号"]'), "教学班导入模板必须只有学生姓名和学号");
+assert(page.includes("initPassword(row, 1)"), "学生列表必须提供数据初始化操作");
+
+console.log("teacher owned student management static checks passed");