Recruitment_site/offer_frontend/src/views/admin/JobManageView.vue

170 lines
5.7 KiB
Vue

<template>
<div>
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px">
<h2>职位管理</h2>
<el-button type="primary" @click="openDialog()">发布职位</el-button>
</div>
<el-table :data="jobs" v-loading="loading" border>
<el-table-column prop="title" label="职位名称" />
<el-table-column prop="organization_name" label="所属公司" />
<el-table-column prop="location" label="地点" />
<el-table-column prop="salary" label="薪资" />
<el-table-column prop="status" label="状态">
<template #default="{ row }">
<el-tag :type="row.status === 'published' ? 'success' : row.status === 'draft' ? 'info' : 'danger'">
{{ { draft:'草稿', published:'已发布', closed:'已关闭' }[row.status] }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="180">
<template #default="{ row }">
<el-button size="small" @click="openDialog(row)">编辑</el-button>
<el-button size="small" type="danger" @click="handleDelete(row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div style="margin-top: 16px; text-align: right;">
<el-pagination
v-model:current-page="currentPage"
:page-size="pageSize"
:total="total"
@current-change="handlePageChange"
layout="total, prev, pager, next, jumper"
/>
</div>
<el-dialog v-model="dialogVisible" :title="editingJob ? '编辑职位' : '发布职位'" width="600px">
<el-form :model="form" label-width="90px">
<!-- 超管才需要选择公司 -->
<el-form-item v-if="auth.isSuperAdmin" label="所属公司">
<el-select v-model="form.organization_id" placeholder="请选择公司" style="width:100%" filterable>
<template v-for="org in allOrgs" :key="org.id">
<el-option :label="org.name" :value="org.id" />
<el-option
v-for="child in org.children"
:key="child.id"
:label="'└ ' + child.name"
:value="child.id"
/>
</template>
</el-select>
</el-form-item>
<el-form-item label="职位名称"><el-input v-model="form.title" /></el-form-item>
<el-form-item label="职位类别"><el-input v-model="form.category" /></el-form-item>
<el-form-item label="工作地点"><el-input v-model="form.location" /></el-form-item>
<el-form-item label="薪资范围"><el-input v-model="form.salary" /></el-form-item>
<el-form-item label="职位描述"><el-input v-model="form.description" type="textarea" :rows="5" /></el-form-item>
<el-form-item label="状态">
<el-select v-model="form.status">
<el-option value="draft" label="草稿" />
<el-option value="published" label="立即发布" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSave" :loading="saving">保存</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { useAuthStore } from '@/stores/auth'
import { manageJobs, createJob, updateJob, deleteJob } from '@/api/jobs'
import { getOrganizations } from '@/api/organizations'
import { ElMessage, ElMessageBox } from 'element-plus'
const auth = useAuthStore()
const jobs = ref([])
const allOrgs = ref([])
const loading = ref(false)
const saving = ref(false)
const dialogVisible = ref(false)
const editingJob = ref(null)
const form = reactive({
title: '', category: '', location: '', salary: '',
description: '', status: 'draft', organization_id: null
})
const currentPage = ref(1)
const pageSize = ref(20)
const total = ref(0)
const fetchJobs = async (page = 1) => {
loading.value = true
try {
const { data } = await manageJobs(page)
jobs.value = data.results
total.value = data.count
currentPage.value = page
} catch (error) {
ElMessage.error('加载职位列表失败,请重试')
} finally {
loading.value = false
}
}
const fetchOrgs = async () => {
const { data } = await getOrganizations()
allOrgs.value = data.results
}
function openDialog(job = null) {
editingJob.value = job
if (job) {
Object.assign(form, {
title: job.title,
category: job.category,
location: job.location,
salary: job.salary,
description: job.description,
status: job.status,
organization_id: job.organization?.id ?? job.organization ?? null,
})
} else {
Object.assign(form, {
title: '', category: '', location: '', salary: '',
description: '', status: 'draft', organization_id: null
})
}
dialogVisible.value = true
}
function handlePageChange(newPage) {
fetchJobs(newPage)
}
async function handleSave() {
if (auth.isSuperAdmin && !form.organization_id) {
return ElMessage.warning('请选择所属公司')
}
saving.value = true
try {
const payload = { ...form }
if (!auth.isSuperAdmin) delete payload.organization_id
if (editingJob.value) await updateJob(editingJob.value.id, payload)
else await createJob(payload)
ElMessage.success('保存成功')
dialogVisible.value = false
fetchJobs(1)
} catch (e) {
ElMessage.error(e.response?.data?.detail || '保存失败')
} finally {
saving.value = false
}
}
async function handleDelete(id) {
await ElMessageBox.confirm('确认删除该职位?', '提示', { type: 'warning' })
await deleteJob(id)
ElMessage.success('已删除')
fetchJobs(1)
}
onMounted(() => {
fetchJobs()
if (auth.isSuperAdmin) fetchOrgs()
})
</script>