206 lines
8.6 KiB
JavaScript
206 lines
8.6 KiB
JavaScript
/* 就业管理:增删改查
|
||||
|
|
学号必须从学生下拉框里选:表的 stu_no 是指向 wl_student 的外键,
|
|||
|
|
手填一个不存在的学号会直接撞外键约束报 500 */
|
|||
|
|
|
|||
|
|
window.PAGES.push({
|
|||
|
|
key: 'emps',
|
|||
|
|
title: '就业管理',
|
|||
|
|
sub: '学生就业去向与薪资,一个学生一条记录',
|
|||
|
|
group: '数据管理',
|
|||
|
|
icon: 'emp',
|
|||
|
|
|
|||
|
|
component: {
|
|||
|
|
name: 'EmpsPage',
|
|||
|
|
template: `
|
|||
|
|
<div>
|
|||
|
|
<div class="card">
|
|||
|
|
<div class="filters">
|
|||
|
|
<el-input v-model="filter.company_name" placeholder="公司名称(模糊)" clearable style="width:200px" @keyup.enter="load" />
|
|||
|
|
<el-input v-model="keyword" placeholder="按学号筛选" clearable style="width:160px" />
|
|||
|
|
<el-button type="primary" @click="load">查询</el-button>
|
|||
|
|
<el-button @click="reset">重置</el-button>
|
|||
|
|
<span class="muted">共 {{ filtered.length }} 条</span>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="card-head">
|
|||
|
|
<div class="card-title">就业列表</div>
|
|||
|
|
<div class="card-tools">
|
|||
|
|
<el-button type="primary" @click="openCreate">+ 新增就业</el-button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<el-table :data="filtered" v-loading="loading" border stripe row-key="stu_no">
|
|||
|
|
<el-table-column prop="stu_no" label="学号" width="130" />
|
|||
|
|
<el-table-column label="学生姓名" width="120">
|
|||
|
|
<template #default="{ row }">
|
|||
|
|
<span v-if="row.stu_name">{{ row.stu_name }}</span>
|
|||
|
|
<el-tag v-else size="small" type="info" effect="plain">学生已删除</el-tag>
|
|||
|
|
</template>
|
|||
|
|
</el-table-column>
|
|||
|
|
<el-table-column prop="company_name" label="公司名称" min-width="170" show-overflow-tooltip />
|
|||
|
|
<el-table-column label="薪资" width="110">
|
|||
|
|
<template #default="{ row }">
|
|||
|
|
<span v-if="row.salary">{{ row.salary.toLocaleString() }}</span>
|
|||
|
|
<span v-else class="muted">—</span>
|
|||
|
|
</template>
|
|||
|
|
</el-table-column>
|
|||
|
|
<el-table-column label="就业开放时间" width="150">
|
|||
|
|
<template #default="{ row }">{{ dash(fmtDateTime(row.emp_open_time)) }}</template>
|
|||
|
|
</el-table-column>
|
|||
|
|
<el-table-column label="offer 下发时间" width="150">
|
|||
|
|
<template #default="{ row }">{{ dash(fmtDateTime(row.offer_time)) }}</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="薪资、两个时间留空时会走数据库默认值(薪资默认 15000,offer 时间取当前时间)" />
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<el-dialog v-model="dialog" :title="editing ? '编辑就业信息' : '新增就业信息'" width="620px" destroy-on-close>
|
|||
|
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="104px">
|
|||
|
|
<div class="form-grid">
|
|||
|
|
<el-form-item label="学生" prop="stu_no" class="span2">
|
|||
|
|
<el-select v-model="form.stu_no" placeholder="按学号或姓名搜索" filterable
|
|||
|
|
:disabled="!!editing" style="width:100%">
|
|||
|
|
<el-option v-for="s in students" :key="s.stu_no" :label="studentLabel(s)" :value="s.stu_no" />
|
|||
|
|
</el-select>
|
|||
|
|
</el-form-item>
|
|||
|
|
<el-form-item label="公司名称" prop="company_name" class="span2">
|
|||
|
|
<el-input v-model="form.company_name" placeholder="就业公司" maxlength="100" />
|
|||
|
|
</el-form-item>
|
|||
|
|
<el-form-item label="薪资">
|
|||
|
|
<el-input-number v-model="form.salary" :min="0" :step="1000"
|
|||
|
|
controls-position="right" style="width:100%" placeholder="默认 15000" />
|
|||
|
|
</el-form-item>
|
|||
|
|
<el-form-item label="就业开放时间">
|
|||
|
|
<el-date-picker v-model="form.emp_open_time" type="datetime"
|
|||
|
|
value-format="YYYY-MM-DDTHH:mm:ss" placeholder="可不填"
|
|||
|
|
style="width:100%" />
|
|||
|
|
</el-form-item>
|
|||
|
|
<el-form-item label="offer 下发时间" class="span2">
|
|||
|
|
<el-date-picker v-model="form.offer_time" type="datetime"
|
|||
|
|
value-format="YYYY-MM-DDTHH:mm:ss" placeholder="可不填,默认当前时间"
|
|||
|
|
style="width:100%" />
|
|||
|
|
</el-form-item>
|
|||
|
|
</div>
|
|||
|
|
</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 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 };
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
});
|