/* 就业管理:增删改查
学号必须从学生下拉框里选:表的 stu_no 是指向 wl_student 的外键,
手填一个不存在的学号会直接撞外键约束报 500 */
window.PAGES.push({
key: 'emps',
title: '就业管理',
sub: '学生就业去向与薪资,一个学生一条记录',
group: '数据管理',
icon: 'emp',
component: {
name: 'EmpsPage',
template: `
查询
重置
共 {{ filtered.length }} 条
{{ row.stu_name }}
学生已删除
{{ row.salary.toLocaleString() }}
—
{{ dash(fmtDateTime(row.emp_open_time)) }}
{{ dash(fmtDateTime(row.offer_time)) }}
编辑
删除
取消
保存
`,
setup() {
const loading = ref(false);
const saving = ref(false);
const rows = ref([]);
const students = ref([]);
const keyword = ref('');
const dialog = ref(false);
const editing = ref(null);
const formRef = ref(null);
const filter = ref({ company_name: '' });
const emptyForm = () => ({
stu_no: null, company_name: '', salary: null,
emp_open_time: null, offer_time: null,
});
const form = ref(emptyForm());
const rules = {
stu_no: [{ required: true, message: '请选择学生', trigger: 'change' }],
company_name: [{ required: true, message: '请填写公司名称', trigger: 'blur' }],
};
const filtered = computed(() => {
const k = keyword.value.trim().toLowerCase();
if (!k) return rows.value;
return rows.value.filter(r => String(r.stu_no || '').toLowerCase().includes(k));
});
const load = async () => {
loading.value = true;
try {
rows.value = await EmpApi.list({ company_name: filter.value.company_name, limit: 1000 });
} catch (e) { toastErr(e); }
finally { loading.value = false; }
};
const reset = () => {
filter.value = { company_name: '' };
keyword.value = '';
load();
};
const openCreate = () => {
editing.value = null;
form.value = emptyForm();
dialog.value = true;
};
const openEdit = (row) => {
// 学号是主键,EmpUpdate 里也没有这个字段,编辑时只允许改其余信息
editing.value = row.stu_no;
form.value = {
stu_no: row.stu_no, company_name: row.company_name, salary: row.salary,
emp_open_time: row.emp_open_time ? String(row.emp_open_time).slice(0, 19) : null,
offer_time: row.offer_time ? String(row.offer_time).slice(0, 19) : null,
};
dialog.value = true;
};
const submit = async () => {
if (!formRef.value) return;
try { await formRef.value.validate(); } catch (e) { return; }
saving.value = true;
try {
const payload = pruneEmpty(form.value);
if (editing.value) {
delete payload.stu_no; // 主键不参与修改
await EmpApi.update(editing.value, payload);
toastOk('保存成功');
} else {
await EmpApi.create(payload);
// 该学生的记录若曾被删除,后端会直接把旧记录复活,所以提示统一写"保存成功"
toastOk('保存成功');
}
dialog.value = false;
await load();
} catch (e) { toastErr(e); }
finally { saving.value = false; }
};
const remove = async (row) => {
try {
await ElementPlus.ElMessageBox.confirm(
`确定删除「${row.stu_name || row.stu_no}」的就业信息吗?`,
'删除确认', { type: 'warning', confirmButtonText: '确定删除', cancelButtonText: '取消' });
} catch (e) { return; }
try {
await EmpApi.remove(row.stu_no);
toastOk('删除成功');
await load();
} catch (e) { toastErr(e); }
};
onMounted(async () => {
try { students.value = await Cache.loadStudents(); }
catch (e) { toastErr(e); }
load();
});
return { loading, saving, rows, students, keyword, filtered, filter, dialog, editing,
formRef, form, rules, load, reset, openCreate, openEdit, submit, remove,
dash, fmtDateTime, studentLabel };
},
},
});