feat: disable locked teacher actions

dev-QQq
chenyuan 4 weeks ago
parent 87abf8981a
commit 769e32852b

@ -55,8 +55,9 @@
<el-table-column label="操作" align="center"> <el-table-column label="操作" align="center">
<template #default="{ row }"> <template #default="{ row }">
<template v-if="isManagerTeacher"> <template v-if="isManagerTeacher">
<el-button type="primary" text @click="editSchool(row)"></el-button> <el-button type="primary" text :disabled="row.hasCreatedClass" @click="editSchool(row)"></el-button>
<el-button type="danger" text @click="delSchool(row)"></el-button> <el-button type="danger" text :disabled="row.hasCreatedClass" @click="delSchool(row)"></el-button>
<el-tag v-if="row.hasCreatedClass" type="warning" size="small"></el-tag>
</template> </template>
<el-tag v-else type="info">仅查看</el-tag> <el-tag v-else type="info">仅查看</el-tag>
</template> </template>
@ -65,13 +66,13 @@
<pagination v-show="schoolTotal > 0" :total="schoolTotal" v-model:page="paramsquery.index" v-model:limit="paramsquery.size" @pagination="getList" /> <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="560px" :title="status ? '新增教师' : '编辑教师'" class="teacher-dialog" @close="onClose"> <el-dialog v-model="dialogVisible" width="560px" :title="status ? '新增教师' : '编辑教师'" class="teacher-dialog" @close="onClose">
<el-form :model="formInline" class="demo-form-inline" ref="formInlineref" label-width="100px" style="width: 80%" :rules="rules"> <el-form :model="formInline" class="demo-form-inline" ref="formInlineref" label-width="100px" style="width: 80%" :rules="rules">
<el-form-item label="所属院系:" prop="schoolFacultyId"> <el-form-item v-if="status || isOrganizationManagementEnabled" label="所属院系:" prop="schoolFacultyId">
<el-select v-model="formInline.schoolFacultyId" placeholder="" clearable @change="getMajorList" style="width: 20rem" v-if="status"> <el-select v-model="formInline.schoolFacultyId" placeholder="" clearable @change="getMajorList" style="width: 20rem" v-if="status">
<el-option v-for="school in facultyList" :key="school.schoolId" :label="school.schoolFacultyName" :value="school.schoolFacultyId" /> <el-option v-for="school in facultyList" :key="school.schoolId" :label="school.schoolFacultyName" :value="school.schoolFacultyId" />
</el-select> </el-select>
<el-input v-else v-model="classInfo.name" style="width: 20rem" disabled></el-input> <el-input v-else v-model="classInfo.name" style="width: 20rem" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="所属专业:" prop="schoolMajorId"> <el-form-item v-if="status || isOrganizationManagementEnabled" label="所属专业:" prop="schoolMajorId">
<el-select v-model="formInline.schoolMajorId" placeholder="" clearable style="width: 20rem" v-if="status"> <el-select v-model="formInline.schoolMajorId" placeholder="" clearable style="width: 20rem" v-if="status">
<el-option v-for="major in majorList" :key="major.schoolMajorId" :label="major.schoolMajorName" :value="major.schoolMajorId" /> <el-option v-for="major in majorList" :key="major.schoolMajorId" :label="major.schoolMajorName" :value="major.schoolMajorId" />
</el-select> </el-select>
@ -108,6 +109,11 @@ const dialogVisible = ref(false);
const loading = ref(false); const loading = ref(false);
const currentUserId = computed(() => userStore.userInfo.userId); const currentUserId = computed(() => userStore.userInfo.userId);
const isManagerTeacher = computed(() => userStore.userInfo.teacherAdmin === true || String(userStore.userInfo.roleId || userStore.userInfo.role) === "1"); const isManagerTeacher = computed(() => userStore.userInfo.teacherAdmin === true || String(userStore.userInfo.roleId || userStore.userInfo.role) === "1");
const legacyOrganizationManagementEnabled = computed(() => userStore.schoolProductConfig?.organizationMode !== "TEACHING_CLASS_ONLY");
const facultyManagementEnabled = computed(() => userStore.schoolProductConfig?.facultyManagementEnabled ?? legacyOrganizationManagementEnabled.value);
const majorManagementEnabled = computed(() => userStore.schoolProductConfig?.majorManagementEnabled ?? legacyOrganizationManagementEnabled.value);
const adminClassManagementEnabled = computed(() => userStore.schoolProductConfig?.adminClassManagementEnabled ?? legacyOrganizationManagementEnabled.value);
const isOrganizationManagementEnabled = computed(() => facultyManagementEnabled.value || majorManagementEnabled.value || adminClassManagementEnabled.value);
const formatDate = (cellValue) => { const formatDate = (cellValue) => {
const numeric = Number(cellValue); const numeric = Number(cellValue);
if (!cellValue || !Number.isFinite(numeric)) { if (!cellValue || !Number.isFinite(numeric)) {
@ -130,12 +136,15 @@ const formInline = ref({
email: "", email: "",
phone: "", phone: "",
}); });
const rules = ref({ const organizationRules = {
schoolFacultyId: [{ required: true, message: "请选择院系", trigger: "change" }], schoolFacultyId: [{ required: true, message: "请选择院系", trigger: "change" }],
schoolMajorId: [{ required: true, message: "请选择专业", trigger: "change" }], schoolMajorId: [{ required: true, message: "请选择专业", trigger: "change" }],
};
const rules = computed(() => ({
...((status.value || isOrganizationManagementEnabled.value) ? organizationRules : {}),
name: [{ required: true, message: "请输入教师姓名", trigger: "blur" }], name: [{ required: true, message: "请输入教师姓名", trigger: "blur" }],
userName: [{ required: true, message: "请输入教师工号", trigger: "blur" }], userName: [{ required: true, message: "请输入教师工号", trigger: "blur" }],
}); }));
const paramsquery = ref({ const paramsquery = ref({
index: 1, index: 1,
size: 10, size: 10,
@ -149,7 +158,7 @@ const status = ref(false);
const tableData = ref([]); const tableData = ref([]);
// //
const getList = () => { const getList = () => {
indexApi.getTeacherList(paramsquery.value).then((res) => { indexApi.getTeacherList({ ...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;
}); });
@ -172,6 +181,9 @@ const editSchool = (row) => {
formInline.value.userName = row.username; formInline.value.userName = row.username;
dialogVisible.value = true; dialogVisible.value = true;
status.value = false; status.value = false;
if (!isOrganizationManagementEnabled.value) {
return;
}
indexApi.getFacultyAndMajorName({ schoolMajorId: row.schoolMajorId }).then((res) => { indexApi.getFacultyAndMajorName({ schoolMajorId: row.schoolMajorId }).then((res) => {
classInfo.value.name = Object.keys(res.data)[0]; classInfo.value.name = Object.keys(res.data)[0];
classInfo.value.value = Object.values(res.data)[0]; classInfo.value.value = Object.values(res.data)[0];
@ -260,7 +272,9 @@ const downloadTemplate = () => {
onMounted(() => { onMounted(() => {
getList(); getList();
if (isOrganizationManagementEnabled.value) {
getFacultyList(); getFacultyList();
}
}); });
</script> </script>
<style lang='scss' scoped> <style lang='scss' scoped>

@ -0,0 +1,16 @@
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", "teacher", "index.vue"), "utf8");
const api = fs.readFileSync(path.join(root, "src", "api", "teacher.js"), "utf8");
assert(page.includes("operatorId: currentUserId.value"), "教师列表请求必须携带当前操作人");
assert(/:disabled="row\.hasCreatedClass"/.test(page), "已建班教师的操作按钮必须禁用");
assert(page.includes("该教师已创建班级,不允许编辑或删除"), "锁定原因必须向用户说明");
assert(/if \(!isOrganizationManagementEnabled\.value\) \{\s*return;\s*\}/.test(page), "无组织结构模式编辑时不得查询院系专业");
assert(/const rules = computed\(\(\) => \(\{[\s\S]*?isOrganizationManagementEnabled/.test(page), "无组织结构模式编辑时不得保留院系专业必填校验");
assert(api.includes('url: "/api/user/selectTeacher"'), "教师列表 API 声明必须保留");
console.log("teacher management class lock static checks passed");
Loading…
Cancel
Save