170 lines
5.7 KiB
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>
|