feat: align teacher student roster page

dev-QQq
chenyuan 4 weeks ago
parent 769e32852b
commit 0a794c21e7

@ -12,7 +12,7 @@
<div class="online">
<span>班级:</span>
<el-select v-model="paramsquery.schoolClassId" placeholder="" style="width: 14rem" clearable class="ml10">
<el-option v-for="school in adminClassList" :key="school.schoolClassId" :label="school.className" :value="school.schoolClassId" />
<el-option v-for="school in studentClassOptions" :key="school.schoolClassId" :label="school.className" :value="school.schoolClassId" />
</el-select>
</div>
<div class="online">
@ -70,6 +70,7 @@
<el-button type="info" text @click="editSchool(row)"></el-button>
<el-button type="danger" text @click="delSchool(row)"></el-button>
<el-button type="success" text @click="initPassword(row, 0)">密码初始化</el-button>
<el-button type="warning" text @click="initPassword(row, 1)">数据初始化</el-button>
</template>
<el-tag v-else type="info">仅查看</el-tag>
</template>
@ -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);
}

@ -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");
Loading…
Cancel
Save