154 lines
6.0 KiB
JavaScript
154 lines
6.0 KiB
JavaScript
/* 班级管理:新增 / 修改 / 逻辑删除
|
||||
|
|
班级表只有「编号 + 开课时间」两列,没有班级名,所以界面上一律显示成 "编号1 · 2026-09-01 开班" */
|
|||
|
|
|
|||
|
|
window.PAGES.push({
|
|||
|
|
key: 'classes',
|
|||
|
|
title: '班级管理',
|
|||
|
|
sub: '班级开课时间,班主任与任课老师来自老师模块',
|
|||
|
|
group: '数据管理',
|
|||
|
|
icon: 'class',
|
|||
|
|
|
|||
|
|
component: {
|
|||
|
|
name: 'ClassesPage',
|
|||
|
|
template: `
|
|||
|
|
<div>
|
|||
|
|
<div class="card">
|
|||
|
|
<div class="card-head">
|
|||
|
|
<div>
|
|||
|
|
<div class="card-title">班级列表</div>
|
|||
|
|
<div class="card-hint">
|
|||
|
|
共 {{ rows.length }} 个班级;班主任和任课老师由老师模块反查得到
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="card-tools">
|
|||
|
|
<el-button @click="load">刷新</el-button>
|
|||
|
|
<el-button type="primary" @click="openCreate">+ 新增班级</el-button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<el-table :data="rows" v-loading="loading" border stripe row-key="class_id">
|
|||
|
|
<el-table-column prop="class_id" label="班级编号" width="100" />
|
|||
|
|
<el-table-column label="开课时间" width="140">
|
|||
|
|
<template #default="{ row }">{{ dash(fmtDate(row.start_time)) }}</template>
|
|||
|
|
</el-table-column>
|
|||
|
|
<el-table-column label="班主任" width="130">
|
|||
|
|
<template #default="{ row }">
|
|||
|
|
<span :class="{ muted: !row.head_teacher_name || row.head_teacher_name === '暂无' }">
|
|||
|
|
{{ row.head_teacher_name || '暂无' }}
|
|||
|
|
</span>
|
|||
|
|
</template>
|
|||
|
|
</el-table-column>
|
|||
|
|
<el-table-column label="任课老师">
|
|||
|
|
<template #default="{ row }">
|
|||
|
|
<span :class="{ muted: !row.course_teacher_names || row.course_teacher_names === '暂无' }">
|
|||
|
|
{{ row.course_teacher_names || '暂无' }}
|
|||
|
|
</span>
|
|||
|
|
</template>
|
|||
|
|
</el-table-column>
|
|||
|
|
<el-table-column label="操作" width="140" fixed="right">
|
|||
|
|
<template #default="{ row }">
|
|||
|
|
<el-button link type="primary" @click="openEdit(row)">编辑</el-button>
|
|||
|
|
<el-button link type="danger" @click="remove(row)">删除</el-button>
|
|||
|
|
</template>
|
|||
|
|
</el-table-column>
|
|||
|
|
</el-table>
|
|||
|
|
|
|||
|
|
<el-alert class="mt12" type="info" :closable="false" show-icon
|
|||
|
|
title="删除保护:班里还有学生或老师时不允许删除,后端会返回中文提示" />
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<el-dialog v-model="dialog" :title="editing ? '编辑班级' : '新增班级'" width="480px" destroy-on-close>
|
|||
|
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="88px">
|
|||
|
|
<el-form-item label="开课时间" prop="start_time">
|
|||
|
|
<el-date-picker v-model="form.start_time" type="date" value-format="YYYY-MM-DD"
|
|||
|
|
placeholder="选择开课日期" style="width:100%" />
|
|||
|
|
</el-form-item>
|
|||
|
|
<el-alert type="info" :closable="false" show-icon
|
|||
|
|
title="开课时间会用来生成学生学号的前八位,请认真填写" />
|
|||
|
|
</el-form>
|
|||
|
|
<template #footer>
|
|||
|
|
<el-button @click="dialog = false">取消</el-button>
|
|||
|
|
<el-button type="primary" :loading="saving" @click="submit">保存</el-button>
|
|||
|
|
</template>
|
|||
|
|
</el-dialog>
|
|||
|
|
</div>
|
|||
|
|
`,
|
|||
|
|
|
|||
|
|
setup() {
|
|||
|
|
const loading = ref(false);
|
|||
|
|
const saving = ref(false);
|
|||
|
|
const rows = ref([]);
|
|||
|
|
const dialog = ref(false);
|
|||
|
|
const editing = ref(null);
|
|||
|
|
const formRef = ref(null);
|
|||
|
|
const form = ref({ start_time: null });
|
|||
|
|
|
|||
|
|
const rules = {
|
|||
|
|
start_time: [{ required: true, message: '请选择开课时间', trigger: 'change' }],
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 一定要重新拉列表:新增/修改接口返回的班主任和任课老师永远是"暂无",
|
|||
|
|
// 那两个字段是 DAO 在列表查询里才挂上去的。
|
|||
|
|
// 顺便把结果写回共享缓存,别的页面的班级下拉/名称映射也就跟着更新了。
|
|||
|
|
const load = async () => {
|
|||
|
|
loading.value = true;
|
|||
|
|
try {
|
|||
|
|
rows.value = await ClassApi.list({ limit: 1000 });
|
|||
|
|
Cache.classes = rows.value;
|
|||
|
|
Cache.loaded.classes = true;
|
|||
|
|
} catch (e) { toastErr(e); }
|
|||
|
|
finally { loading.value = false; }
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const openCreate = () => {
|
|||
|
|
editing.value = null;
|
|||
|
|
form.value = { start_time: null };
|
|||
|
|
dialog.value = true;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const openEdit = (row) => {
|
|||
|
|
editing.value = row.class_id;
|
|||
|
|
// 回参是 "2026-09-01T00:00:00",日期选择器只认前半段
|
|||
|
|
form.value = { start_time: fmtDate(row.start_time) || null };
|
|||
|
|
dialog.value = true;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const submit = async () => {
|
|||
|
|
if (!formRef.value) return;
|
|||
|
|
try { await formRef.value.validate(); } catch (e) { return; }
|
|||
|
|
saving.value = true;
|
|||
|
|
try {
|
|||
|
|
if (editing.value) {
|
|||
|
|
await ClassApi.update(editing.value, form.value);
|
|||
|
|
toastOk('修改成功');
|
|||
|
|
} else {
|
|||
|
|
await ClassApi.create(form.value);
|
|||
|
|
toastOk('新增成功');
|
|||
|
|
}
|
|||
|
|
dialog.value = false;
|
|||
|
|
await load();
|
|||
|
|
} catch (e) { toastErr(e); }
|
|||
|
|
finally { saving.value = false; }
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const remove = async (row) => {
|
|||
|
|
try {
|
|||
|
|
await ElementPlus.ElMessageBox.confirm(
|
|||
|
|
`确定删除班级「编号${row.class_id}」吗?`,
|
|||
|
|
'删除确认', { type: 'warning', confirmButtonText: '确定删除', cancelButtonText: '取消' });
|
|||
|
|
} catch (e) { return; }
|
|||
|
|
try {
|
|||
|
|
await ClassApi.remove(row.class_id);
|
|||
|
|
toastOk('删除成功');
|
|||
|
|
await load();
|
|||
|
|
} catch (e) { toastErr(e); }
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
onMounted(load);
|
|||
|
|
|
|||
|
|
return { loading, saving, rows, dialog, editing, formRef, form, rules,
|
|||
|
|
load, openCreate, openEdit, submit, remove, dash, fmtDate };
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
});
|