You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dianshang-qianduan/src/views/teacherEnd/class/index.vue

781 lines
27 KiB
Vue

4 months ago
<template>
<div class="class-page app-container">
<el-tabs v-if="adminClassManagementEnabled" v-model="activeClassType" class="class-tabs" @tab-change="handleTabChange">
<el-tab-pane label="行政班" name="ADMIN" />
<el-tab-pane label="教学班" name="TEACHING" />
</el-tabs>
<div class="query-bar">
<el-select v-if="facultyManagementEnabled" v-model="paramsquery.schoolFacultyId" placeholder="所属院系" clearable class="query-control" @change="getMajorList">
<el-option v-for="faculty in facultyList" :key="faculty.schoolFacultyId" :label="faculty.schoolFacultyName" :value="faculty.schoolFacultyId" />
</el-select>
<el-select v-if="majorManagementEnabled" v-model="paramsquery.schoolMajorId" placeholder="所属专业" clearable class="query-control">
<el-option v-for="major in majorList" :key="major.schoolMajorId" :label="major.schoolMajorName" :value="major.schoolMajorId" />
</el-select>
<el-input v-model="paramsquery.className" placeholder="班级名称" clearable class="query-control" />
<el-button type="primary" :icon="Search" @click="getList">查询</el-button>
<el-button :icon="Refresh" @click="refresh">刷新</el-button>
</div>
<div v-if="canCreateCurrentClass" class="table-actions">
<el-button type="primary" :icon="Plus" @click="openCreateDialog">新增{{ activeClassType === 'ADMIN' ? '行政班' : '教学班' }}</el-button>
4 months ago
</div>
<el-table :data="filteredTableData" border v-loading="loading" class="class-table" :header-cell-style="tableHeaderStyle">
<el-table-column label="班级名称" prop="schoolClass.className" align="center" />
<el-table-column v-if="facultyManagementEnabled" label="所属院系" align="center">
<template #default="{ row }">
<span>{{ row.schoolFacultyName || "-" }}</span>
</template>
</el-table-column>
<el-table-column v-if="majorManagementEnabled" label="所属专业" align="center">
<template #default="{ row }">
<span>{{ row.schoolMajorName || "-" }}</span>
</template>
</el-table-column>
<el-table-column label="创建人" align="center">
<template #default="{ row }">
<span>{{ row.createdByName || "-" }}</span>
</template>
</el-table-column>
<el-table-column label="数据来源" align="center" width="120">
<template #default="{ row }">
<el-tag :type="row.schoolClass.dataSource === 'ZHIYUN' ? 'warning' : 'success'">
{{ row.schoolClass.dataSource === "ZHIYUN" ? "智云" : "本系统" }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="schoolClass.createTime" align="center" width="180">
4 months ago
<template #default="{ row }">
<span>{{ formatDate(row.schoolClass.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" min-width="320">
4 months ago
<template #default="{ row }">
<div class="action-buttons">
<el-button v-if="activeClassType === 'TEACHING'" type="primary" text @click="openMemberDialog(row.schoolClass)">
成员管理
</el-button>
<template v-if="canOperateClass(row.schoolClass)">
<el-button type="primary" text @click="editClass(row)">编辑</el-button>
<el-button type="danger" text @click="deleteClass(row.schoolClass.schoolClassId)">删除</el-button>
<el-button v-if="activeClassType === 'TEACHING'" type="warning" text @click="initializeClass(row.schoolClass)">
数据初始化
</el-button>
</template>
<el-tag v-else type="info">仅查看</el-tag>
</div>
4 months ago
</template>
</el-table-column>
</el-table>
4 months ago
<pagination v-show="schoolTotal > 0" :total="schoolTotal" v-model:page="paramsquery.index" v-model:limit="paramsquery.size" @pagination="getList" />
<el-dialog v-model="dialogVisible" width="520px" :title="dialogTitle" class="teacher-dialog" @close="onClose">
<el-form ref="formInlineref" :model="formInline" label-width="96px" :rules="rules">
<el-form-item v-if="facultyManagementEnabled" label="所属院系" prop="schoolFacultyId">
<el-select v-model="formInline.schoolFacultyId" placeholder="请选择院系" clearable class="form-control" @change="getMajorListForForm">
<el-option v-for="faculty in facultyList" :key="faculty.schoolFacultyId" :label="faculty.schoolFacultyName" :value="faculty.schoolFacultyId" />
4 months ago
</el-select>
</el-form-item>
<el-form-item v-if="majorManagementEnabled" label="所属专业" prop="schoolMajorId">
<el-select v-model="formInline.schoolMajorId" placeholder="请选择专业" clearable class="form-control" @change="handleFormMajorChange">
<el-option v-for="major in majorListForForm" :key="major.schoolMajorId" :label="major.schoolMajorName" :value="major.schoolMajorId" />
4 months ago
</el-select>
</el-form-item>
<el-form-item v-if="activeClassType === 'TEACHING' && isCreate && adminClassManagementEnabled" label="来源行政班" prop="sourceClassIds">
<el-select v-model="sourceAdminClassIds" placeholder="请选择来源行政班" clearable multiple collapse-tags collapse-tags-tooltip class="form-control">
<el-option v-for="schoolClass in adminClassOptions" :key="schoolClass.schoolClassId" :label="schoolClass.className" :value="schoolClass.schoolClassId" />
</el-select>
</el-form-item>
<el-form-item label="班级名称" prop="className">
<el-input v-model="formInline.className" placeholder="请输入班级名称" class="form-control" />
4 months ago
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footers">
4 months ago
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm">确定</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="memberDialogVisible" width="900px" :title="memberDialogTitle" class="teacher-dialog" @close="closeMemberDialog">
<div class="member-toolbar">
<el-input v-model="memberParams.name" placeholder="学生姓名" clearable class="member-query" />
<el-input v-model="memberParams.userName" placeholder="学号" clearable class="member-query" />
<el-button type="primary" :icon="Search" @click="getMemberList">查询</el-button>
<el-button :icon="Refresh" @click="refreshMemberList">刷新</el-button>
<template v-if="selectedTeachingClassCanOperate">
<el-upload
action="/api/user/uploadTeachingClassStudentMembers"
:data="memberUploadData"
:show-file-list="false"
:before-upload="beforeImportMembers"
:http-request="uploadMemberImport"
>
<el-button type="primary">导入成员</el-button>
</el-upload>
<el-button @click="downloadMemberImportTemplate">模板下载</el-button>
</template>
</div>
<el-table :data="memberList" border v-loading="memberLoading" class="member-table" :header-cell-style="tableHeaderStyle">
<el-table-column label="学生姓名" prop="name" align="center" />
<el-table-column label="学号" prop="username" align="center" />
<el-table-column label="所属班级" prop="className" align="center" />
<el-table-column label="电话" prop="phone" align="center" />
<el-table-column label="邮箱" prop="email" align="center" />
<el-table-column label="账号来源" prop="codeFrom" align="center" />
<el-table-column label="操作" align="center" width="210">
<template #default="{ row }">
<template v-if="selectedTeachingClassCanOperate">
<el-button type="danger" text @click="removeMember(row)">移除</el-button>
<el-button type="primary" text @click="initializeMember(row)">数据初始化</el-button>
</template>
<el-tag v-else type="info">仅查看</el-tag>
</template>
</el-table-column>
</el-table>
<pagination
v-show="memberTotal > 0"
:total="memberTotal"
v-model:page="memberParams.index"
v-model:limit="memberParams.size"
@pagination="getMemberList"
/>
</el-dialog>
4 months ago
</div>
</template>
4 months ago
<script setup>
import { Plus, Refresh, Search } from "@element-plus/icons-vue";
import { ElMessageBox } from "element-plus";
4 months ago
import { formatDate } from "@/utils/index";
import useUserStore from "@/store/modules/user";
import * as indexApi from "@/api/teacher";
4 months ago
const { proxy } = getCurrentInstance();
4 months ago
const userStore = useUserStore();
const activeClassType = ref("ADMIN");
4 months ago
const dialogVisible = ref(false);
const memberDialogVisible = ref(false);
4 months ago
const loading = ref(false);
const memberLoading = ref(false);
const isCreate = ref(true);
const tableData = ref([]);
const memberList = ref([]);
const schoolTotal = ref(0);
const memberTotal = ref(0);
const facultyList = ref([]);
const majorList = ref([]);
const majorListForForm = ref([]);
const allClassList = ref([]);
const sourceAdminClassIds = ref([]);
const selectedTeachingClass = ref(null);
const currentUserId = computed(() => userStore.userInfo.userId);
const currentSchoolId = computed(() => userStore.userInfo.schoolId);
const isManagerTeacher = computed(() => userStore.userInfo.teacherAdmin === true);
const legacyAdminEnabled = computed(() => userStore.schoolProductConfig?.organizationMode !== "TEACHING_CLASS_ONLY");
const facultyManagementEnabled = computed(() => userStore.schoolProductConfig?.facultyManagementEnabled ?? legacyAdminEnabled.value);
const majorManagementEnabled = computed(() => userStore.schoolProductConfig?.majorManagementEnabled ?? legacyAdminEnabled.value);
const adminClassManagementEnabled = computed(() => userStore.schoolProductConfig?.adminClassManagementEnabled ?? legacyAdminEnabled.value);
const isTeacherRosterMode = computed(() => !facultyManagementEnabled.value && !majorManagementEnabled.value && !adminClassManagementEnabled.value);
const canCreateCurrentClass = computed(() => activeClassType.value === "ADMIN" || activeClassType.value === "TEACHING");
const paramsquery = ref({
index: 1,
size: 10,
schoolId: currentSchoolId.value,
4 months ago
schoolFacultyId: "",
schoolMajorId: "",
className: "",
});
const formInline = ref(defaultForm());
const memberParams = ref(defaultMemberParams());
const rules = computed(() => ({
...(facultyManagementEnabled.value ? { schoolFacultyId: [{ required: true, message: "请选择所属院系", trigger: "change" }] } : {}),
...(majorManagementEnabled.value ? { schoolMajorId: [{ required: true, message: "请选择所属专业", trigger: "change" }] } : {}),
4 months ago
className: [{ required: true, message: "请输入班级名称", trigger: "blur" }],
}));
const tableHeaderStyle = {
color: "#0f3052",
fontSize: "14px",
backgroundColor: "#eaf4ff",
4 months ago
};
const dialogTitle = computed(() => `${isCreate.value ? "新增" : "编辑"}${activeClassType.value === "ADMIN" ? "行政班" : "教学班"}`);
const memberDialogTitle = computed(() => `${selectedTeachingClass.value?.className || ""} 成员管理`);
const selectedTeachingClassCanOperate = computed(() => canOperateClass(selectedTeachingClass.value));
const filteredTableData = computed(() => {
return tableData.value.filter((row) => normalizeClassType(row.schoolClass) === activeClassType.value);
});
const adminClassOptions = computed(() => {
return allClassList.value.filter((schoolClass) => {
return normalizeClassType(schoolClass) === "ADMIN"
&& (!formInline.value.schoolMajorId || schoolClass.schoolMajorId === formInline.value.schoolMajorId);
});
});
const memberUploadData = computed(() => ({
teachingClassId: selectedTeachingClass.value?.schoolClassId || "",
operatorId: currentUserId.value,
}));
function isMultiTeachingClassConflict(error) {
return error?.response?.data?.code === 409;
}
function multiTeachingClassMessage(error) {
const body = error?.response?.data || {};
const students = Array.isArray(body.data) ? body.data : [];
const details = students.length ? `\n${students.slice(0, 12).join("、")}${students.length > 12 ? " 等" : ""}` : "";
return `${body.msg || "部分学生已在其他教学班,是否继续操作?"}${details}`;
}
function buildUploadFormData(file, data, confirmMultiTeachingClass = false) {
const formData = new FormData();
formData.append("file", file);
Object.keys(data).forEach((key) => {
formData.append(key, data[key] ?? "");
});
formData.append("confirmMultiTeachingClass", confirmMultiTeachingClass);
return formData;
}
function defaultForm() {
return {
schoolFacultyId: "",
schoolId: currentSchoolId.value,
schoolMajorId: "",
className: "",
classType: activeClassType.value,
sourceClassIds: "",
};
}
function defaultMemberParams() {
return {
index: 1,
size: 10,
schoolId: currentSchoolId.value,
schoolClassId: "",
name: "",
userName: "",
operatorId: currentUserId.value,
};
}
function normalizeClassType(schoolClass) {
if (schoolClass?.classType) {
return schoolClass.classType;
}
return schoolClass?.createdBy ? "TEACHING" : "ADMIN";
}
function canOperateClass(schoolClass) {
if (schoolClass?.dataSource === "ZHIYUN") {
return false;
}
if (isManagerTeacher.value) {
return !schoolClass?.schoolId || String(schoolClass.schoolId) === String(currentSchoolId.value);
}
if (normalizeClassType(schoolClass) === "ADMIN") {
return !schoolClass?.schoolId || schoolClass.schoolId === currentSchoolId.value;
}
return schoolClass?.createdBy === currentUserId.value;
}
function getList(options = {}) {
const { showLoading = true } = options;
if (showLoading) {
loading.value = true;
}
indexApi
.getClassesList({
...paramsquery.value,
operatorId: currentUserId.value,
})
.then((res) => {
tableData.value = res.data?.list || [];
schoolTotal.value = res.data?.total || 0;
})
.finally(() => {
if (showLoading) {
loading.value = false;
}
});
}
function handleTabChange() {
paramsquery.value.index = 1;
getList();
}
function openCreateDialog() {
if (!canCreateCurrentClass.value) {
proxy.$message.warning("普通教师不能新增行政班");
return;
}
isCreate.value = true;
formInline.value = defaultForm();
sourceAdminClassIds.value = [];
4 months ago
dialogVisible.value = true;
}
function editClass(row) {
const schoolClass = row?.schoolClass || row;
const schoolFacultyId = schoolClass?.schoolFacultyId || row?.schoolFacultyId || "";
const schoolMajorId = schoolClass?.schoolMajorId || row?.schoolMajorId || "";
isCreate.value = false;
formInline.value = {
...schoolClass,
schoolFacultyId,
schoolMajorId,
classType: normalizeClassType(schoolClass),
userId: currentUserId.value,
};
sourceAdminClassIds.value = [];
majorListForForm.value = [];
4 months ago
dialogVisible.value = true;
hydrateClassFormOptions(formInline.value);
}
function addClass(confirmMultiTeachingClass = false) {
const payload = {
...formInline.value,
schoolId: currentSchoolId.value,
classType: activeClassType.value,
sourceClassIds: activeClassType.value === "TEACHING" ? sourceAdminClassIds.value.join(",") : "",
userId: currentUserId.value,
confirmMultiTeachingClass,
};
indexApi
.addClass(payload)
.then(() => {
proxy.$message.success("添加成功");
dialogVisible.value = false;
getList({ showLoading: false });
refreshAllClassList();
})
.catch((error) => {
if (!isMultiTeachingClassConflict(error)) return;
ElMessageBox.confirm(multiTeachingClassMessage(error), "学生已在其他教学班", {
confirmButtonText: "继续创建",
cancelButtonText: "取消",
type: "warning",
}).then(() => addClass(true));
});
}
function updateClass() {
const payload = {
...formInline.value,
schoolId: currentSchoolId.value,
classType: activeClassType.value,
userId: currentUserId.value,
status: true,
};
indexApi.updateClass(payload).then(() => {
4 months ago
proxy.$message.success("编辑成功");
dialogVisible.value = false;
getList({ showLoading: false });
refreshAllClassList();
4 months ago
});
}
function submitForm() {
proxy.$refs.formInlineref.validate((valid) => {
if (!valid) return;
if (adminClassManagementEnabled.value && isCreate.value && activeClassType.value === "TEACHING" && sourceAdminClassIds.value.length === 0) {
proxy.$message.warning("请选择来源行政班");
return;
}
isCreate.value ? addClass() : updateClass();
4 months ago
});
}
function openMemberDialog(schoolClass) {
selectedTeachingClass.value = schoolClass;
memberParams.value = {
...defaultMemberParams(),
schoolClassId: schoolClass.schoolClassId,
};
memberDialogVisible.value = true;
getMemberList();
}
function closeMemberDialog() {
selectedTeachingClass.value = null;
memberList.value = [];
memberTotal.value = 0;
memberParams.value = defaultMemberParams();
}
function getMemberList() {
if (!memberParams.value.schoolClassId) {
return;
}
memberLoading.value = true;
indexApi
.getStudentList(memberParams.value)
.then((res) => {
memberList.value = res.data?.list || [];
memberTotal.value = res.data?.total || 0;
})
.finally(() => {
memberLoading.value = false;
});
}
function refreshMemberList() {
memberParams.value.name = "";
memberParams.value.userName = "";
memberParams.value.index = 1;
getMemberList();
}
function beforeImportMembers(file) {
if (!selectedTeachingClass.value?.schoolClassId) {
proxy.$message.warning("请先选择教学班");
return false;
}
if (!selectedTeachingClassCanOperate.value) {
proxy.$message.warning("只能维护自己创建的教学班成员");
return false;
}
if (!/\.(xls|xlsx)$/i.test(file.name)) {
proxy.$message.warning("请选择xls或xlsx格式文件");
return false;
}
return true;
}
function uploadMemberImport(options, confirmMultiTeachingClass = false) {
if (isTeacherRosterMode.value) {
const formData = new FormData();
formData.append("file", options.file);
return indexApi
.importTeacherRosterMembers(selectedTeachingClass.value.schoolClassId, formData)
.then((res) => {
handleMemberImportSuccess(res);
});
}
const formData = buildUploadFormData(options.file, memberUploadData.value, confirmMultiTeachingClass);
return indexApi
.uploadTeachingClassStudentMembers(formData)
.then((res) => {
handleMemberImportSuccess(res);
})
.catch((error) => {
if (!isMultiTeachingClassConflict(error)) return;
return ElMessageBox.confirm(multiTeachingClassMessage(error), "学生已在其他教学班", {
confirmButtonText: "继续导入",
cancelButtonText: "取消",
type: "warning",
}).then(() => uploadMemberImport(options, true));
});
}
function handleMemberImportSuccess(res) {
if (res?.statusCode && res.statusCode !== "OK" && res.statusCode !== 200) {
proxy.$message.error(res?.message || "导入失败");
return;
}
proxy.$message.success("导入成功");
getMemberList();
}
function removeMember(row) {
ElMessageBox.confirm("确定将该学生从当前教学班移除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
indexApi
.deleteStudent({
userId: row.userId,
operatorId: currentUserId.value,
teachingClassId: selectedTeachingClass.value.schoolClassId,
})
.then(() => {
proxy.$message.success("移除成功");
getMemberList();
});
});
}
function initializeMember(row) {
ElMessageBox.confirm("确定初始化该学生在当前教学班的实训数据吗?该操作不可恢复。", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
indexApi
.initializeTeachingClassStudentTrainingData({
teachingClassId: selectedTeachingClass.value.schoolClassId,
studentUserId: row.userId,
operatorId: currentUserId.value,
})
.then(() => {
proxy.$message.success("初始化成功");
});
});
}
async function downloadMemberImportTemplate() {
const XLSX = await import("xlsx");
if (isTeacherRosterMode.value) {
const templateSheet = XLSX.utils.aoa_to_sheet([
["学生姓名", "学号"],
["张三", "20260001"],
]);
templateSheet["!cols"] = [{ wch: 16 }, { wch: 18 }];
const guideSheet = XLSX.utils.aoa_to_sheet([
["填写说明"],
["1. 本模板用于向当前教学班添加成员。"],
["2. 仅填写学生姓名和学号,不需要填写班级或其他个人信息。"],
["3. 学号已存在时,系统会复用该学生并加入当前教学班。"],
["4. 任意一行校验失败时,整批导入失败并返回失败原因。"],
]);
guideSheet["!cols"] = [{ wch: 72 }];
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, templateSheet, "教学班成员导入模板");
XLSX.utils.book_append_sheet(workbook, guideSheet, "填写说明");
XLSX.writeFile(workbook, "教学班成员导入模板.xlsx");
return;
}
const templateSheet = XLSX.utils.aoa_to_sheet([
["所属院系", "所属专业", "行政班", "学号", "学生姓名", "性别", "手机号", "邮箱"],
["商学院", "电子商务", "2026电子商务1班-行政班", "20260001", "张三", "男", "13800000000", "zhangsan@example.com"],
]);
templateSheet["!cols"] = [{ wch: 18 }, { wch: 18 }, { wch: 28 }, { wch: 18 }, { wch: 16 }, { wch: 10 }, { wch: 18 }, { wch: 26 }];
const guideSheet = XLSX.utils.aoa_to_sheet([
["填写说明"],
["1. 本模板用于向当前教学班追加成员。"],
["2. 不要填写任何数据ID,院系、专业、行政班请填写页面中的名称。"],
["3. 系统优先按当前教学班来源行政班匹配;未配置来源行政班时,按院系、专业、行政班、学号、姓名匹配已有学生。"],
["4. 任意一行校验失败时,整批导入失败并返回失败原因。"],
]);
guideSheet["!cols"] = [{ wch: 72 }];
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, templateSheet, "教学班成员导入模板");
XLSX.utils.book_append_sheet(workbook, guideSheet, "填写说明");
XLSX.writeFile(workbook, "教学班成员导入模板.xlsx");
}
function deleteClass(id) {
ElMessageBox.confirm("确定删除该班级吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
indexApi.deleteClass({ schoolClassId: id, userId: currentUserId.value }).then(() => {
proxy.$message.success("删除成功");
getList();
refreshAllClassList();
});
4 months ago
});
}
function initializeClass(schoolClass) {
ElMessageBox.confirm("确定初始化该教学班全班实训数据吗?该操作不可恢复。", "提示", {
4 months ago
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
indexApi
.initializeTeachingClassTrainingData({
teachingClassId: schoolClass.schoolClassId,
operatorId: currentUserId.value,
})
.then(() => {
4 months ago
proxy.$message.success("初始化成功");
});
});
}
function refresh() {
getList();
}
function onClose() {
formInline.value = defaultForm();
sourceAdminClassIds.value = [];
}
function getFacultyList() {
return indexApi.seleteSchoolFacultyList({ schoolId: currentSchoolId.value }).then((res) => {
facultyList.value = res.data || [];
return facultyList.value;
});
}
function getMajorList() {
paramsquery.value.schoolMajorId = "";
if (!paramsquery.value.schoolFacultyId) {
majorList.value = [];
return;
}
indexApi.getMajorListBySchoolId({ schoolFacultyId: paramsquery.value.schoolFacultyId }).then((res) => {
majorList.value = res.data || [];
});
}
function loadMajorListForForm(schoolFacultyId) {
if (!schoolFacultyId) {
majorListForForm.value = [];
return Promise.resolve([]);
}
return indexApi.getMajorListBySchoolId({ schoolFacultyId }).then((res) => {
majorListForForm.value = res.data || [];
return majorListForForm.value;
});
}
function getMajorListForForm() {
sourceAdminClassIds.value = [];
formInline.value.schoolMajorId = "";
loadMajorListForForm(formInline.value.schoolFacultyId);
}
async function hydrateClassFormOptions(row) {
const schoolMajorId = row?.schoolMajorId;
if (!schoolMajorId) {
return;
}
if (row.schoolFacultyId) {
await loadMajorListForForm(row.schoolFacultyId);
return;
}
const faculties = facultyList.value.length ? facultyList.value : await getFacultyList();
const results = await Promise.all(
faculties.map((faculty) =>
indexApi
.getMajorListBySchoolId({ schoolFacultyId: faculty.schoolFacultyId })
.then((res) => ({
facultyId: faculty.schoolFacultyId,
majors: res.data || [],
}))
.catch(() => ({
facultyId: faculty.schoolFacultyId,
majors: [],
}))
)
);
const matched = results.find((item) => item.majors.some((major) => major.schoolMajorId === schoolMajorId));
if (!matched) {
return;
}
majorListForForm.value = matched.majors;
formInline.value = {
...formInline.value,
schoolFacultyId: matched.facultyId,
schoolMajorId,
};
}
function handleFormMajorChange() {
sourceAdminClassIds.value = [];
}
function getAllClassList() {
indexApi.getClassListBySchoolId({ schoolId: currentSchoolId.value }).then((res) => {
allClassList.value = res.data || [];
});
}
function refreshAllClassList() {
indexApi.clearClassListBySchoolIdCache(currentSchoolId.value);
indexApi.getClassListBySchoolId({ schoolId: currentSchoolId.value }, { force: true }).then((res) => {
allClassList.value = res.data || [];
});
}
4 months ago
onMounted(() => {
if (!adminClassManagementEnabled.value) {
activeClassType.value = "TEACHING";
}
4 months ago
getList();
getAllClassList();
4 months ago
getFacultyList();
});
</script>
<style lang="scss" scoped>
.class-page {
min-height: calc(100vh - 70px);
background: #f7fbff;
.class-tabs {
margin-bottom: 12px;
}
.query-bar {
4 months ago
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 12px;
padding: 14px;
border: 1px solid #d8e8f7;
border-radius: 6px;
background: #ffffff;
}
.query-control {
width: 220px;
}
.table-actions {
display: flex;
justify-content: flex-start;
margin: 14px 0;
}
.class-table {
width: 100%;
}
.action-buttons {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
flex-wrap: wrap;
:deep(.el-button) {
margin-left: 0;
min-width: 56px;
padding: 6px 10px;
line-height: 1;
}
}
.form-control {
width: 100%;
4 months ago
}
.member-toolbar {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 10px;
margin-bottom: 12px;
}
.member-query {
width: 180px;
}
.member-table {
width: 100%;
}
4 months ago
}
</style>