Files
1/static/js/pages/classes.js
T
2026-09-14 10:23:36 +08:00

154 lines
6.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 班级管理:新增 / 修改 / 逻辑删除
班级表只有「编号 + 开课时间」两列,没有班级名,所以界面上一律显示成 "编号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 };
},
},
});