فهرست منبع

feat(zpgl): 实现招聘管理功能

- 新增职位发布、编辑、删除功能
- 支持批量删除职位
- 实现职位详情查看功能
- 添加分页查询和表单验证- 集成Element Plus组件库和Lucide图标- 实现招聘信息的增删改查操作
- 添加职位列表展示和筛选功能
nahida 8 ماه پیش
والد
کامیت
ba57c45cb5
1فایلهای تغییر یافته به همراه371 افزوده شده و 0 حذف شده
  1. 371 0
      src/views/gwnrgl/zpgl/index.vue

+ 371 - 0
src/views/gwnrgl/zpgl/index.vue

@@ -0,0 +1,371 @@
+<script setup>
+import {onMounted, reactive, ref} from 'vue'
+import {ElMessage, ElMessageBox} from 'element-plus'
+import {Edit, Plus, Trash2} from 'lucide-vue-next'
+import request from '@/utils/request.js'
+
+// 响应式数据
+const jobs = ref([])
+const total = ref(0)
+const dialogVisible = ref(false)
+const detailVisible = ref(false)
+const isEdit = ref(false)
+const loading = ref(false)
+const selectedJob = ref(null)
+const formRef = ref()
+const currentPage = ref(1)
+const pageSize = ref(10)
+
+// 批量选择
+const selectedJobIds = ref([])
+
+// 表单数据
+const formData = reactive({
+  id: '',
+  jobOpenings: '',
+  keyTerms: '',
+  jobRequirements: '',
+  numberRecruits: '',
+  salary: '',
+  workLocation: '',
+  contact: '',
+  contactInformation: '',
+  remarks: ''
+})
+
+// 表单验证规则
+const rules = {
+  jobOpenings: [{ required: true, message: '请输入招聘岗位', trigger: 'blur' }],
+  keyTerms: [{ required: true, message: '请输入关键词条', trigger: 'blur' }],
+  jobRequirements: [{ required: true, message: '请输入招聘详情', trigger: 'blur' }],
+  numberRecruits: [{ required: true, message: '请输入招聘人数', trigger: 'blur' }],
+  salary: [{ required: true, message: '请输入薪资', trigger: 'blur' }],
+  workLocation: [{ required: true, message: '请输入工作地点', trigger: 'blur' }],
+  contact: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
+  contactInformation: [{ required: true, message: '请输入联系方式', trigger: 'blur' }]
+}
+
+// 获取数据
+const getList = async () => {
+  try {
+    const res = await request.get('/smartEmployment/findByPage', {
+      params: {
+        pageNum: currentPage.value,
+        pageSize: pageSize.value
+      }
+    })
+    if (res.code !== 200) {
+      ElMessage.error(res.msg)
+      return
+    }
+    jobs.value = res.data.records || []
+    total.value = res.data.total || 0
+  } catch (error) {
+    ElMessage.error('获取数据失败')
+  }
+}
+
+// 打开新增对话框
+const openAddDialog = () => {
+  isEdit.value = false
+  resetForm()
+  dialogVisible.value = true
+}
+
+// 编辑职位
+const editJob = async (job) => {
+  isEdit.value = true
+  try {
+    const res = await request.get(`/smartEmployment/getById/${job.id}`)
+    if (res.code !== 200) {
+      ElMessage.error(res.msg)
+      return
+    }
+    Object.assign(formData, res.data)
+    dialogVisible.value = true
+  } catch (error) {
+    ElMessage.error('获取职位详情失败')
+  }
+}
+
+// 删除职位
+const deleteJob = async (id) => {
+  try {
+    await ElMessageBox.confirm('确定要删除这个职位吗?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    })
+    const res = await request.post('/smartEmployment/deleteBatch', [id])
+    if (res.code !== 200) {
+      ElMessage.error(res.msg)
+      return
+    }
+    ElMessage.success('删除成功')
+    getList()
+  } catch (error) {
+    if (error !== 'cancel') {
+      ElMessage.error('删除失败')
+    }
+  }
+}
+
+// 批量删除
+const deleteSelectedJobs = async () => {
+  if (selectedJobIds.value.length === 0) {
+    ElMessage.warning('请先选择要删除的职位')
+    return
+  }
+  try {
+    await ElMessageBox.confirm(`确定要删除选中的 ${selectedJobIds.value.length} 个职位吗?`, '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    })
+    const res = await request.post('/smartEmployment/deleteBatch', selectedJobIds.value)
+    if (res.code !== 200) {
+      ElMessage.error(res.msg)
+      return
+    }
+    ElMessage.success('批量删除成功')
+    selectedJobIds.value = []
+    getList()
+  } catch (error) {
+    if (error !== 'cancel') {
+      ElMessage.error('批量删除失败')
+    }
+  }
+}
+
+// 提交表单
+const handleSubmit = async () => {
+  if (!formRef.value) return
+  try {
+    await formRef.value.validate()
+    loading.value = true
+    let success = false
+    if (isEdit.value) {
+      success = await update(formData)
+    } else {
+      success = await add(formData)
+    }
+    if (success) {
+      dialogVisible.value = false
+      getList()
+    }
+  } catch (error) {
+    console.error('表单验证失败', error)
+  } finally {
+    loading.value = false
+  }
+}
+
+const add = async (data) => {
+  try {
+    const res = await request.post('/smartEmployment/save', data)
+    if (res.code !== 200) {
+      ElMessage.error(res.msg)
+      return false
+    }
+    ElMessage.success(res.msg)
+    return true
+  } catch (error) {
+    ElMessage.error('添加失败')
+    return false
+  }
+}
+
+const update = async (data) => {
+  try {
+    const res = await request.post('/smartEmployment/update', data)
+    if (res.code !== 200) {
+      ElMessage.error(res.msg)
+      return false
+    }
+    ElMessage.success(res.msg)
+    return true
+  } catch (error) {
+    ElMessage.error('更新失败')
+    return false
+  }
+}
+
+// 查看详情
+const viewJobDetail = (job) => {
+  selectedJob.value = job
+  detailVisible.value = true
+}
+
+const handleClose = () => {
+  dialogVisible.value = false
+  resetForm()
+}
+
+const resetForm = () => {
+  Object.keys(formData).forEach(key => {
+    formData[key] = ''
+  })
+  if (formRef.value) {
+    formRef.value.resetFields()
+  }
+}
+
+const handleSizeChange = (val) => {
+  pageSize.value = val
+  currentPage.value = 1
+  getList()
+}
+
+const handleCurrentChange = (val) => {
+  currentPage.value = val
+  getList()
+}
+
+onMounted(() => {
+  getList()
+})
+</script>
+
+<template>
+  <div class="min-h-screen bg-gray-50 p-6">
+    <div class="w-full mx-auto mb-6 bg-white p-4 rounded-lg shadow">
+      <el-button type="primary" @click="openAddDialog">
+        <Plus class="w-4 h-4 mr-1" /> 发布职位
+      </el-button>
+      <el-button type="danger" @click="deleteSelectedJobs">
+        <Trash2 class="w-4 h-4 mr-1" /> 批量删除
+      </el-button>
+    </div>
+
+    <!-- 表格 -->
+    <div class="w-full mx-auto bg-white p-4 rounded-lg shadow">
+      <el-table
+          :data="jobs"
+          style="width: 100%"
+          @selection-change="(rows)=>selectedJobIds = rows.map(r=>r.id)"
+      >
+        <el-table-column type="selection" width="55" />
+        <el-table-column prop="jobOpenings" label="岗位名称" width="150" />
+        <el-table-column prop="workLocation" label="工作地点" width="120" />
+        <el-table-column prop="salary" label="薪资" width="120" />
+        <el-table-column prop="numberRecruits" label="招聘人数" width="100" />
+        <el-table-column prop="contact" label="联系人" width="100" />
+        <el-table-column prop="contactInformation" label="联系方式" width="150" />
+        <el-table-column prop="keyTerms" label="关键词" />
+        <el-table-column label="操作" width="180">
+          <template #default="scope">
+            <el-button size="small" type="primary" text @click="editJob(scope.row)">
+              <Edit class="w-4 h-4" /> 编辑
+            </el-button>
+            <el-button size="small" type="danger" text @click="deleteJob(scope.row.id)">
+              <Trash2 class="w-4 h-4" /> 删除
+            </el-button>
+            <el-button size="small" type="info" text @click="viewJobDetail(scope.row)">
+              详情
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 分页 -->
+      <div class="flex justify-center mt-6">
+        <el-pagination
+            v-model:current-page="currentPage"
+            v-model:page-size="pageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            :total="total"
+            layout="total, sizes, prev, pager, next, jumper"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+        />
+      </div>
+    </div>
+
+    <!-- 添加/编辑对话框 -->
+    <el-dialog
+        v-model="dialogVisible"
+        :title="isEdit ? '编辑职位' : '发布职位'"
+        width="600px"
+        :before-close="handleClose"
+    >
+      <el-form :model="formData" :rules="rules" ref="formRef" label-width="100px">
+        <el-form-item label="招聘岗位" prop="jobOpenings">
+          <el-input v-model="formData.jobOpenings" placeholder="请输入招聘岗位" />
+        </el-form-item>
+        <el-form-item label="关键词条" prop="keyTerms">
+          <el-input v-model="formData.keyTerms" placeholder="请输入关键词,用逗号分隔" />
+        </el-form-item>
+        <el-form-item label="招聘详情" prop="jobRequirements">
+          <el-input
+              v-model="formData.jobRequirements"
+              type="textarea"
+              :rows="4"
+              placeholder="请输入招聘详情"
+          />
+        </el-form-item>
+        <el-form-item label="招聘人数" prop="numberRecruits">
+          <el-input v-model="formData.numberRecruits" placeholder="请输入招聘人数" />
+        </el-form-item>
+        <el-form-item label="薪资" prop="salary">
+          <el-input v-model="formData.salary" placeholder="请输入薪资" />
+        </el-form-item>
+        <el-form-item label="工作地点" prop="workLocation">
+          <el-input v-model="formData.workLocation" placeholder="请输入工作地点" />
+        </el-form-item>
+        <el-form-item label="联系人" prop="contact">
+          <el-input v-model="formData.contact" placeholder="请输入联系人" />
+        </el-form-item>
+        <el-form-item label="联系方式" prop="contactInformation">
+          <el-input v-model="formData.contactInformation" placeholder="请输入联系方式" />
+        </el-form-item>
+        <el-form-item label="备注">
+          <el-input
+              v-model="formData.remarks"
+              type="textarea"
+              :rows="3"
+              placeholder="请输入备注信息"
+          />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false">取消</el-button>
+          <el-button type="primary" @click="handleSubmit" :loading="loading">
+            {{ isEdit ? '更新' : '发布' }}
+          </el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 职位详情对话框 -->
+    <el-dialog v-model="detailVisible" title="职位详情" width="700px">
+      <div v-if="selectedJob" class="space-y-4">
+        <div class="bg-gray-50 rounded-lg p-4">
+          <h3 class="text-xl font-bold text-gray-800 mb-2">{{ selectedJob.jobOpenings }}</h3>
+          <div class="grid grid-cols-2 gap-4 text-sm">
+            <div><strong>工作地点:</strong>{{ selectedJob.workLocation }}</div>
+            <div><strong>薪资:</strong>{{ selectedJob.salary }}</div>
+            <div><strong>招聘人数:</strong>{{ selectedJob.numberRecruits }}</div>
+            <div><strong>联系人:</strong>{{ selectedJob.contact }}</div>
+          </div>
+        </div>
+        <div>
+          <h4 class="font-semibold mb-2">职位要求:</h4>
+          <p class="text-gray-700 leading-relaxed">{{ selectedJob.jobRequirements }}</p>
+        </div>
+        <div v-if="selectedJob.remarks">
+          <h4 class="font-semibold mb-2">备注:</h4>
+          <p class="text-gray-700">{{ selectedJob.remarks }}</p>
+        </div>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<style scoped>
+.dialog-footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: 12px;
+}
+</style>