+
-
+
-
+
@@ -73,17 +73,17 @@
-
+
-
+
-
+
@@ -190,6 +190,11 @@ const selectedTeachingClass = ref(null);
const currentUserId = computed(() => userStore.userInfo.userId);
const currentSchoolId = computed(() => userStore.userInfo.schoolId);
+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({
@@ -204,11 +209,11 @@ const paramsquery = ref({
const formInline = ref(defaultForm());
const memberParams = ref(defaultMemberParams());
-const rules = {
- schoolFacultyId: [{ required: true, message: "请选择所属院系", trigger: "change" }],
- schoolMajorId: [{ required: true, message: "请选择所属专业", trigger: "change" }],
+const rules = computed(() => ({
+ ...(facultyManagementEnabled.value ? { schoolFacultyId: [{ required: true, message: "请选择所属院系", trigger: "change" }] } : {}),
+ ...(majorManagementEnabled.value ? { schoolMajorId: [{ required: true, message: "请选择所属专业", trigger: "change" }] } : {}),
className: [{ required: true, message: "请输入班级名称", trigger: "blur" }],
-};
+}));
const tableHeaderStyle = {
color: "#0f3052",
@@ -403,7 +408,7 @@ function updateClass() {
function submitForm() {
proxy.$refs.formInlineref.validate((valid) => {
if (!valid) return;
- if (isCreate.value && activeClassType.value === "TEACHING" && sourceAdminClassIds.value.length === 0) {
+ if (adminClassManagementEnabled.value && isCreate.value && activeClassType.value === "TEACHING" && sourceAdminClassIds.value.length === 0) {
proxy.$message.warning("请选择来源行政班");
return;
}
@@ -767,6 +772,9 @@ function refreshAllClassList() {
}
onMounted(() => {
+ if (!adminClassManagementEnabled.value) {
+ activeClassType.value = "TEACHING";
+ }
getList();
getAllClassList();
getFacultyList();
diff --git a/tests/school-product-config.static.test.cjs b/tests/school-product-config.static.test.cjs
index 1b10de6..b9719cf 100644
--- a/tests/school-product-config.static.test.cjs
+++ b/tests/school-product-config.static.test.cjs
@@ -7,11 +7,25 @@ const api = fs.readFileSync(path.join(root, "src/api/schoolProductConfig.js"), "
const router = fs.readFileSync(path.join(root, "src/router/index.js"), "utf8");
const sidebar = fs.readFileSync(path.join(root, "src/layout/components/Sidebar/index.vue"), "utf8");
const platformSchool = fs.readFileSync(path.join(root, "src/views/platformAdmin/school/index.vue"), "utf8");
+const teacherClass = fs.readFileSync(path.join(root, "src/views/teacherEnd/class/index.vue"), "utf8");
+const teacherRoutes = router.slice(router.indexOf("export const teacherRoutes"), router.indexOf("export const platformAdminRoutes"));
assert(/\/api\/school-product-config\/current/.test(api), "school users must load their product configuration");
assert(/\/product-config`/.test(api), "platform admins must update a school's product configuration");
assert(/requiresAdminClass:\s*true/.test(router), "administrative organization routes must be marked for configuration gating");
+assert(/path: "\/school"[\s\S]*?requiresAdminClass:\s*true/.test(teacherRoutes), "teacher faculty menu must be gated");
+assert(/path: "\/major"[\s\S]*?requiresAdminClass:\s*true/.test(teacherRoutes), "teacher major menu must be gated");
+assert(/path: "\/teacher"[\s\S]*?requiresAdminClass:\s*true/.test(teacherRoutes), "teacher account menu must be gated");
assert(/filterRoutesByOrganizationMode/.test(sidebar), "sidebar must remove unavailable administrative organization routes");
+assert(/filterRoutesByOrganizationMode\(teacherRoutes\)/.test(sidebar), "teacher menus must be filtered by organization mode");
+assert(/watch\(\s*\(\) => userStore\.schoolProductConfig\?\.organizationMode/.test(sidebar), "sidebar must refresh when the asynchronous school configuration arrives");
assert(/organizationMode/.test(platformSchool) && /updatePlatformSchoolProductConfig/.test(platformSchool), "platform school editor must manage organization mode");
+assert(/行政班管理/.test(platformSchool), "platform school editor must expose administrative-class management controls");
+assert(/v-model="productConfig\.facultyManagementEnabled"/.test(platformSchool), "platform school editor must configure faculty management with a switch");
+assert(/v-model="productConfig\.majorManagementEnabled"/.test(platformSchool), "platform school editor must configure major management with a switch");
+assert(/v-model="productConfig\.adminClassManagementEnabled"/.test(platformSchool), "platform school editor must configure administrative classes with a switch");
+assert(/requiresFacultyManagement/.test(router) && /requiresMajorManagement/.test(router), "teacher routes must declare their management capability");
+assert(/adminClassManagementEnabled/.test(teacherClass), "teacher class page must derive administrative-class controls from the switch");
+assert(/isTeacherRosterMode/.test(teacherClass), "teacher class page must recognize teacher-managed roster mode");
console.log("School product configuration is represented in the API, routes, sidebar, and platform editor.");