|
|
|
@ -12,7 +12,7 @@
|
|
|
|
<div class="online">
|
|
|
|
<div class="online">
|
|
|
|
<span>班级:</span>
|
|
|
|
<span>班级:</span>
|
|
|
|
<el-select v-model="paramsquery.schoolClassId" placeholder="" style="width: 14rem" clearable class="ml10">
|
|
|
|
<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>
|
|
|
|
</el-select>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="online">
|
|
|
|
<div class="online">
|
|
|
|
@ -70,6 +70,7 @@
|
|
|
|
<el-button type="info" text @click="editSchool(row)">编辑</el-button>
|
|
|
|
<el-button type="info" text @click="editSchool(row)">编辑</el-button>
|
|
|
|
<el-button type="danger" text @click="delSchool(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="success" text @click="initPassword(row, 0)">密码初始化</el-button>
|
|
|
|
|
|
|
|
<el-button type="warning" text @click="initPassword(row, 1)">数据初始化</el-button>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
<el-tag v-else type="info">仅查看</el-tag>
|
|
|
|
<el-tag v-else type="info">仅查看</el-tag>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
@ -186,7 +187,7 @@ const status = ref(false);
|
|
|
|
const tableData = ref([]);
|
|
|
|
const tableData = ref([]);
|
|
|
|
// 获取院校列表
|
|
|
|
// 获取院校列表
|
|
|
|
const getList = () => {
|
|
|
|
const getList = () => {
|
|
|
|
indexApi.getStudentList(paramsquery.value).then((res) => {
|
|
|
|
indexApi.getStudentList({ ...paramsquery.value, operatorId: currentUserId.value }).then((res) => {
|
|
|
|
tableData.value = res.data.list;
|
|
|
|
tableData.value = res.data.list;
|
|
|
|
schoolTotal.value = res.data.total;
|
|
|
|
schoolTotal.value = res.data.total;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
@ -303,6 +304,18 @@ const getMajorList = () => {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
};
|
|
|
|
const uploadStudents = (options) => {
|
|
|
|
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);
|
|
|
|
const formData = buildStudentImportFormData(options.file);
|
|
|
|
return indexApi.importTeacherStudents(formData).then((res) => {
|
|
|
|
return indexApi.importTeacherStudents(formData).then((res) => {
|
|
|
|
handleSuccess(res);
|
|
|
|
handleSuccess(res);
|
|
|
|
@ -318,7 +331,7 @@ const handleSuccess = (res, file) => {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// 导出教师账号
|
|
|
|
// 导出教师账号
|
|
|
|
const exportTeacher = () => {
|
|
|
|
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 blob = new Blob([res], { type: "application/vnd.ms-excel" });
|
|
|
|
const url = URL.createObjectURL(blob);
|
|
|
|
const url = URL.createObjectURL(blob);
|
|
|
|
const link = document.createElement("a");
|
|
|
|
const link = document.createElement("a");
|
|
|
|
@ -351,6 +364,17 @@ const buildOwnedAdminClassRows = async () => {
|
|
|
|
|
|
|
|
|
|
|
|
const downloadTemplate = async () => {
|
|
|
|
const downloadTemplate = async () => {
|
|
|
|
const XLSX = await import("xlsx");
|
|
|
|
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 adminClassRows = await buildOwnedAdminClassRows();
|
|
|
|
const firstAdminClass = adminClassRows[0] || ["电子商务学院", "电子商务", "行政一班"];
|
|
|
|
const firstAdminClass = adminClassRows[0] || ["电子商务学院", "电子商务", "行政一班"];
|
|
|
|
const templateSheet = XLSX.utils.aoa_to_sheet([
|
|
|
|
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 classMap = computed(() => new Map(classList.value.map((item) => [item.schoolClassId, item])));
|
|
|
|
const adminClassList = computed(() => classList.value.filter((item) => canUseAdminClassForStudent(item)));
|
|
|
|
const adminClassList = computed(() => classList.value.filter((item) => canUseAdminClassForStudent(item)));
|
|
|
|
|
|
|
|
const studentClassOptions = computed(() =>
|
|
|
|
|
|
|
|
isTeacherRosterMode.value ? teachingClassOptions.value : adminClassList.value
|
|
|
|
|
|
|
|
);
|
|
|
|
const teachingClassOptions = computed(() =>
|
|
|
|
const teachingClassOptions = computed(() =>
|
|
|
|
classList.value.filter(
|
|
|
|
classList.value.filter(
|
|
|
|
(schoolClass) =>
|
|
|
|
(schoolClass) =>
|
|
|
|
@ -399,6 +426,11 @@ const teachingClassOptions = computed(() =>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
const canOperateStudent = (row) => {
|
|
|
|
const canOperateStudent = (row) => {
|
|
|
|
const selectedClass = classMap.value.get(paramsquery.value.schoolClassId);
|
|
|
|
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") {
|
|
|
|
if (selectedClass && normalizeClassType(selectedClass) === "TEACHING") {
|
|
|
|
return sameValue(selectedClass.createdBy, currentUserId.value);
|
|
|
|
return sameValue(selectedClass.createdBy, currentUserId.value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|