Xiao_123 7 ヶ月 前
コミット
33ad86ff67

+ 8 - 0
src/api/menduner/common/useDictionaries.ts

@@ -10,4 +10,12 @@ export const dictApi = {
   getPositionData: async (params: any) => {
     return await request.get({ url: `/menduner/system/position/list`, params })
   },
+  // 职位类型树结构
+  getPositionTreeData: async (params: any) => {
+    return await request.get({ url: `/menduner/system/position/get/tree`, params })
+  },
+  // 地区树结构
+  getAreaTreeData: async (params: any) => {
+    return await request.get({ url: `/menduner/system/area/get/tree`, params })
+  },
 }

+ 19 - 5
src/api/menduner/system/job/index.ts

@@ -3,23 +3,22 @@ import request from '@/config/axios'
 // 门墩儿-招聘职位 VO
 export interface JobAdvertisedVO {
   id: number // id
-  enterpriseId: number // 企业id
-  userId: number // 发布用户id
   areaId: number // 工作地区
   name: string // 职位名称
   positionId: number // 职位类型id
   type: number // 招聘类型
   expType: number // 工作经验
   eduType: number // 学历要求
+  payUnit: number // 计薪时段
   payFrom: number // 薪酬from
   payTo: number // 薪酬to
-  tagList: string // 职位标签
+  tagList: Array<[]> // 职位标签
   content: string // 职位内容
   requirement: string // 职位要求
   address: string // 工作地址
   longitude: string // 经度
   latitude: string // 维度
-  status: number // 职位状态
+  expireTime: string // 过期时间
 }
 
 // 门墩儿-招聘职位 API
@@ -39,6 +38,16 @@ export const JobAdvertisedApi = {
     return await request.post({ url: `/menduner/system/job-advertised/create`, data })
   },
 
+  // 关闭门墩儿-招聘职位
+  closeJobAdvertised: async (ids) => {
+    return await request.post({ url: `/menduner/system/job-advertised/disable?ids=` + ids })
+  },
+
+  // 激活门墩儿-招聘职位
+  enAbleJobAdvertised: async (ids) => {
+    return await request.post({ url: `/menduner/system/job-advertised/enable?ids=` + ids })
+  },
+
   // 修改门墩儿-招聘职位
   updateJobAdvertised: async (data: JobAdvertisedVO) => {
     return await request.put({ url: `/menduner/system/job-advertised/update`, data })
@@ -52,5 +61,10 @@ export const JobAdvertisedApi = {
   // 导出门墩儿-招聘职位 Excel
   exportJobAdvertised: async (params) => {
     return await request.download({ url: `/menduner/system/job-advertised/export-excel`, params })
-  }
+  },
+
+  // 查询职位模板
+  getRecruitPositionDetails: async (id) => {
+    return await request.get({ url: `/menduner/system/position/get?id=` + id })
+  },
 }

+ 11 - 2
src/hooks/web/useDictionaries.js

@@ -5,6 +5,15 @@ import { dictApi } from '@/api/menduner/common/useDictionaries'
 // }
 
 const setDict = (type, val, cacheTime = 7200) => {
+  if (type === 'areaTreeData') {
+    const obj = val.find(e => e.name === '中国')
+    val = obj?.children ? obj.children.map(e =>{
+      // 市辖区直接显示区
+      const municipality = e.children && e.children.length && e.children[0].name === '市辖区'
+      if (municipality && e.children[0].children?.length) e.children = e.children[0].children
+      return e
+    }) : []
+  }
   localStorage.setItem(type, JSON.stringify({
     data: val,
     expire: Date.now() + cacheTime * 1000
@@ -26,8 +35,8 @@ export const getDict = (type, params, apiType = 'dict') => {
     const query = params ? params : { type }
     const apiFn = {
       // dict: getDictData,
-      // positionTreeData: getPositionTreeData, // 职位tree
-      // areaTreeData: getAreaTreeData, // 区域tree
+      positionTreeData: dictApi.getPositionTreeData, // 职位tree
+      areaTreeData: dictApi.getAreaTreeData, // 区域tree
       // industryTreeData: getIndustryTreeData, // 行业tree
       // industryList: getIndustryListData,
       // skillList: getSkillList,

+ 100 - 0
src/utils/transform/position.js

@@ -0,0 +1,100 @@
+import { reactive, ref } from 'vue'
+import { getDict } from '@/hooks/web/useDictionaries'
+import * as CommissionRatioApi from '@/api/menduner/system/hire/commissionRatio/index'
+
+const dictObj = reactive({
+  // payUnit: [], // 薪资单位
+  // scale: [], // 规模
+  industry: [], // 行业
+  // edu: [], // 学历
+  // exp: [], // 工作经验
+  area: [], // 地区
+  position: [], // 职位类型
+  // jobStatus: [], // 求职状态
+  // marital: [], // 婚姻状态
+  // financing: [] // 融资阶段
+})
+const dictList = ref([
+  // { type: 'menduner_pay_unit', value: 'payUnit', key: 'payUnit', label: 'payName' },
+  // { type: 'menduner_financing_status', value: 'financing', key: 'financingStatus', label: 'financingName' },
+  // { type: 'menduner_scale', value: 'scale', key: 'scale', label: 'scaleName' },
+  // { type: 'menduner_job_seek_status', value: 'jobStatus', key: 'jobStatus', label: 'jobStatusName' },
+  // { type: 'menduner_marital_status', value: 'marital', key: 'maritalStatus', label: 'maritalStatusName' },
+  // { type: 'menduner_industry_type', value: 'industry', key: 'industryId', label: 'industryName', params: {}, apiType: 'industryList', nameKey: 'nameCn', valueKey: 'id' },
+  // { type: 'menduner_education_type', value: 'edu', key: 'eduType', label: 'eduName' },
+  // { type: 'menduner_exp_type', value: 'exp', key: 'expType', label: 'expName' },
+  { type: 'menduner_area_type', value: 'area', key: 'areaId', label: 'areaName', params: {}, apiType: 'areaList', nameKey: 'name', valueKey: 'id' },
+  // { type: 'menduner_area_type', value: 'reg', key: 'regId', label: 'regName', params: {}, apiType: 'areaList', nameKey: 'name', valueKey: 'id' },
+  { type: 'positionData', value: 'position', key: 'positionId', label: 'positionName', params: {}, apiType: 'positionData', nameKey: 'nameCn', valueKey: 'id' }
+])
+
+// 字典
+const getDictList = async () => {
+  dictList.value.forEach(async (val) => {
+    const { data } = await getDict(val.type, val.params, val.apiType)
+    dictObj[val.value] = data
+  })
+}
+export const getDictListData = async () => {
+  await getDictList()
+}
+getDictListData()
+
+export const dealDictArrayData = (res, list) => {
+  res = list.map(item => {
+    Object.keys(item).map(e => {
+      const data = dictList.value.find(k => k.key === e)
+      if (!data) return
+      const valueKey = data.nameKey ? data.nameKey : 'label'
+      const idKey = data.valueKey ? data.valueKey : 'value'
+      if (!dictObj[data.value] || !Object.keys(dictObj[data.value]).length) return
+      const result = dictObj[data.value].find(val => Number(val[idKey]) === Number(item[e]))
+      if (!result) return
+      item[data.label] = result[valueKey] || ''
+    })
+    return { ...item }
+  })
+  return res
+}
+
+export const dealDictObjData = (res, obj) => {
+  res = obj
+  Object.keys(obj).map(e => {
+    const data = dictList.value.find(k => k.key === e)
+    if (!data) return
+    const valueKey = data.nameKey ? data.nameKey : 'label'
+    const idKey = data.valueKey ? data.valueKey : 'value'
+    const result = dictObj[data.value]?.find(val => val[idKey] === obj[e])
+    if (!result) return
+    res[data.label] = result[valueKey]
+    res = { ...obj, ...res }
+  })
+  return res
+}
+
+// 计算众聘佣金
+let data
+const list = ['headhuntRate', 'recommendRate', 'cvRate'] // 平台、推荐人、投递人
+const getRation = async () => {
+  data = await CommissionRatioApi.getCommissionRatio()
+}
+getRation()
+
+export const rechargeRatio = () => { return 10 }
+
+export const commissionCalculation = (count, type) => {
+  if (!data || !Object.keys(data).length) return
+  // 所占的百分比
+  const ratio = parseFloat(data[list[type]]) / 100 // 所占的百分比-> 50%变为0.5 (不能改)
+  // 积分变成金额
+  const value = count * ratio / rechargeRatio()
+  return value % 1 === 0 ? Math.floor(value) : value.toFixed(2)
+}
+
+// "分"和"元" 转化。 type-> toCent:提交给后端需要乘以100; toYuan:回显需要除以100)
+export const FenYuanTransform = (count, type='toYuan') => {
+  if ((count - 0) === 0) return 0
+  if (!count) return ''
+  const Magnification = type === 'toCent' ? 100 : 1/100 
+  return type === 'toCent' ? (count - 0)*Magnification : ((count - 0)*Magnification).toFixed(2)
+}

+ 147 - 76
src/views/menduner/system/job/JobAdvertisedForm.vue

@@ -6,80 +6,69 @@
       :rules="formRules"
       label-width="100px"
       v-loading="formLoading"
+      :validate-on-rule-change="false"
     >
-      <el-form-item label="企业id" prop="enterpriseId">
-        <el-input v-model="formData.enterpriseId" placeholder="请输入企业id" />
+      <el-form-item label="奖励点数" prop="hirePrice">
+        <el-input-number v-model="formData.hirePrice" :min="1" :step="5" />
+        <div style="color: var(--el-color-danger)">
+          <div>众聘岗位分配比例:推荐人占比{{ ratio.recommendRate }}%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 平台占比{{ ratio.headhuntRate }}%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 投递人占比{{ ratio.cvRate }}%</div>
+          <div style="display: flex;">
+            按众聘岗位分配比例计算后的赏金: 
+            <span style="display: block; width: 120px;">推荐人{{ commissionCalculation(formData.hirePrice, 1, true) }}元</span>
+            <span style="display: block; width: 120px;">平台{{ commissionCalculation(formData.hirePrice, 0, true) }}元</span>
+            <span style="display: block; width: 120px;">投递人{{ commissionCalculation(formData.hirePrice, 2, true) }}元</span>
+          </div>
+        </div>
       </el-form-item>
-      <el-form-item label="发布用户id" prop="userId">
-        <el-input v-model="formData.userId" placeholder="请输入发布用户id" />
-      </el-form-item>
-      <el-form-item label="工作地区" prop="areaId">
-        <el-select v-model="formData.areaId" placeholder="请选择工作地区">
-          <el-option label="请选择字典生成" value="" />
-        </el-select>
+      <el-form-item label="职位类型" prop="positionId">
+        <el-cascader v-model="formData.positionId" :options="position" :props="{ label: 'nameCn', value: 'id', emitPath: false }"  class="!w-240px" />
+        <el-button v-if="showTemplateBtn" @click="handleSearchTemplate" type="primary" style="margin-left: 20px">职位模板</el-button>
       </el-form-item>
       <el-form-item label="职位名称" prop="name">
-        <el-input v-model="formData.name" placeholder="请输入职位名称" />
+        <el-input v-model="formData.name" placeholder="请输入职位名称" class="!w-240px"/>
       </el-form-item>
-      <el-form-item label="职位类型id" prop="positionId">
-        <el-select v-model="formData.positionId" placeholder="请选择职位类型id">
-          <el-option label="请选择字典生成" value="" />
-        </el-select>
+      <el-form-item label="到期时间" prop="expireTime">
+        <el-date-picker v-model="formData.expireTime" :disabled="disabled" :disabledDate="disabledDates" value-format="x" type="date" placeholder="请选择职位到期时间"  class="!w-240px" />
+        <el-checkbox v-model="loadingTerm" label="长期有效" size="large" style="margin-left: 20px;" @change="handleLongTerm"/>
+      </el-form-item>
+      <el-form-item label="职位内容" prop="content">
+        <Editor v-model="formData.content" height="150px" />
+      </el-form-item>
+      <el-form-item label="职位要求" prop="requirement">
+        <Editor v-model="formData.requirement" height="150px" />
       </el-form-item>
       <el-form-item label="招聘类型" prop="type">
-        <el-select v-model="formData.type" placeholder="请选择招聘类型">
-          <el-option
-            v-for="dict in getIntDictOptions(DICT_TYPE.MENDUNER_JOB_TYPE)"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
+        <el-select v-model="formData.type" placeholder="请选择招聘类型" class="!w-240px">
+          <el-option v-for="dict in getIntDictOptions(DICT_TYPE.MENDUNER_JOB_TYPE)" :key="dict.value" :label="dict.label" :value="dict.value"/>
         </el-select>
       </el-form-item>
       <el-form-item label="工作经验" prop="expType">
-        <el-select v-model="formData.expType" placeholder="请选择工作经验">
-          <el-option label="请选择字典生成" value="" />
+        <el-select v-model="formData.expType" placeholder="请选择工作经验" class="!w-240px">
+          <el-option v-for="dict in getIntDictOptions(DICT_TYPE.MENDUNER_EXP_TYPE)" :key="dict.value" :label="dict.label" :value="dict.value"/>
         </el-select>
       </el-form-item>
       <el-form-item label="学历要求" prop="eduType">
-        <el-select v-model="formData.eduType" placeholder="请选择学历要求">
-          <el-option label="请选择字典生成" value="" />
+        <el-select v-model="formData.eduType" placeholder="请选择学历要求" class="!w-240px">
+          <el-option v-for="dict in getIntDictOptions(DICT_TYPE.MENDUNER_EDUCATION_TYPE)" :key="dict.value" :label="dict.label" :value="dict.value"/>
         </el-select>
       </el-form-item>
-      <el-form-item label="薪酬from" prop="payFrom">
-        <el-input v-model="formData.payFrom" placeholder="请输入薪酬from" />
+      <el-form-item label="最低薪资" prop="payFrom">
+        <el-input-number v-model="formData.payFrom" :min="1" :step="1000" class="!w-240px" />
       </el-form-item>
-      <el-form-item label="薪酬to" prop="payTo">
-        <el-input v-model="formData.payTo" placeholder="请输入薪酬to" />
+      <el-form-item label="最高薪资" prop="payTo">
+        <el-input-number v-model="formData.payTo" :min="1" :step="1000" class="!w-240px" />
       </el-form-item>
-      <el-form-item label="职位标签" prop="tagList">
-        <el-input v-model="formData.tagList" placeholder="请输入职位标签" />
-      </el-form-item>
-      <el-form-item label="职位内容" prop="content">
-        <Editor v-model="formData.content" height="150px" />
+      <el-form-item label="计薪时段" prop="payUnit">
+        <el-select v-model="formData.payUnit" placeholder="请选择计薪时段" class="!w-240px">
+          <el-option v-for="dict in getIntDictOptions(DICT_TYPE.MENDUNER_PAY_UNIT)" :key="dict.value" :label="dict.label" :value="dict.value"/>
+        </el-select>
       </el-form-item>
-      <el-form-item label="职位要求" prop="requirement">
-        <el-input v-model="formData.requirement" placeholder="请输入职位要求" />
+      <el-form-item label="工作地区" prop="areaId">
+        <el-cascader v-model="formData.areaId" :options="area" :props="{ label: 'name', value: 'id', emitPath: false }"  class="!w-240px" />
       </el-form-item>
-      <el-form-item label="工作地址" prop="address">
+      <el-form-item label="详情地址" prop="address">
         <el-input v-model="formData.address" placeholder="请输入工作地址" />
       </el-form-item>
-      <el-form-item label="经度" prop="longitude">
-        <el-input v-model="formData.longitude" placeholder="请输入经度" />
-      </el-form-item>
-      <el-form-item label="维度" prop="latitude">
-        <el-input v-model="formData.latitude" placeholder="请输入维度" />
-      </el-form-item>
-      <el-form-item label="职位状态" prop="status">
-        <el-select v-model="formData.status" placeholder="请选择职位状态">
-          <el-option
-            v-for="dict in getIntDictOptions(DICT_TYPE.MENDUNER_STATUS)"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
     </el-form>
     <template #footer>
       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
@@ -87,51 +76,130 @@
     </template>
   </Dialog>
 </template>
+
 <script setup lang="ts">
 import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
 import { JobAdvertisedApi, JobAdvertisedVO } from '@/api/menduner/system/job'
+import { commissionCalculation } from '@/utils/transform/position'
+import * as CommissionRatioApi from '@/api/menduner/system/hire/commissionRatio/index'
 
 /** 门墩儿-招聘职位 表单 */
 defineOptions({ name: 'JobAdvertisedForm' })
-
+defineProps({
+  area: Array,
+  position: Array
+})
 const { t } = useI18n() // 国际化
 const message = useMessage() // 消息弹窗
 
+const loadingTerm = ref(false) // 长期有效
+const showTemplateBtn = ref(true) // 职位模板按钮
 const dialogVisible = ref(false) // 弹窗的是否展示
 const dialogTitle = ref('') // 弹窗的标题
 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
 const formType = ref('') // 表单的类型:create - 新增;update - 修改
 const formData = ref({
   id: undefined,
-  enterpriseId: undefined,
-  userId: undefined,
   areaId: undefined,
   name: undefined,
   positionId: undefined,
   type: undefined,
   expType: undefined,
+  expireTime: undefined,
   eduType: undefined,
-  payFrom: undefined,
-  payTo: undefined,
-  tagList: undefined,
+  payFrom: 6000,
+  payTo: 8000,
+  hirePrice: 10,
+  payUnit: undefined,
+  // tagList: undefined,
   content: undefined,
   requirement: undefined,
-  address: undefined,
-  longitude: undefined,
-  latitude: undefined,
-  status: undefined
+  address: undefined
 })
+
+const checkPayFrom = (rule: any, value: any, callback: any) => {
+  if (value === '') {
+    callback(new Error('最低薪资不能为空'))
+  } else {
+    if (value >= formData.value.payTo) {
+      callback(new Error('应低于最高薪资'))
+    }
+    callback()
+  }
+}
+const checkPayTo = (rule: any, value: any, callback: any) => {
+  if (value === '') {
+    callback(new Error('最高薪资不能为空'))
+  } else {
+    if (value <= formData.value.payFrom) {
+      callback(new Error('应高于最低薪资'))
+    }
+    callback()
+  }
+}
 const formRules = reactive({
-  enterpriseId: [{ required: true, message: '企业id不能为空', trigger: 'blur' }],
-  userId: [{ required: true, message: '发布用户id不能为空', trigger: 'blur' }],
+  hirePrice: [{ required: true, message: '请填写点数', trigger: 'change' }],
   areaId: [{ required: true, message: '工作地区不能为空', trigger: 'change' }],
   name: [{ required: true, message: '职位名称不能为空', trigger: 'blur' }],
-  positionId: [{ required: true, message: '职位类型id不能为空', trigger: 'change' }],
+  positionId: [{ required: true, message: '职位类型不能为空', trigger: 'change' }],
   type: [{ required: true, message: '招聘类型不能为空', trigger: 'change' }],
   expType: [{ required: true, message: '工作经验不能为空', trigger: 'change' }],
-  eduType: [{ required: true, message: '学历要求不能为空', trigger: 'change' }]
+  eduType: [{ required: true, message: '学历要求不能为空', trigger: 'change' }],
+  payUnit: [{ required: true, message: '计薪时段不能为空', trigger: 'change' }],
+  payFrom: [{ required: true, validator: checkPayFrom, trigger: 'change' }],
+  payTo: [{ required: true, validator: checkPayTo, trigger: 'change' }],
+  content: [{ required: true, message: '职位内容不能为空', trigger: 'change' }],
+  requirement: [{ required: true, message: '职位要求不能为空', trigger: 'change' }],
+  address: [{ required: true, message: '工作详情地址不能为空', trigger: 'change' }],
 })
 const formRef = ref() // 表单 Ref
+const disabled = ref(false) // 是否禁用日期选择器
+
+// 过去的日期不可选
+const disabledDates = (date) => {
+  const currentDate = new Date()
+  currentDate.setDate(currentDate.getDate() - 1)
+  return date.getTime() < currentDate.getTime()
+}
+
+// 职位过期时间长期有效
+const handleLongTerm = (e) => {
+  if (e) formData.value.expireTime = null
+  disabled.value = e ? true : false
+}
+
+// 获取众聘分配比例
+const ratio = ref({})
+const getRatio = async () => {
+  const data = await CommissionRatioApi.getCommissionRatio()
+  ratio.value = data
+}
+getRatio()
+
+
+
+// 职位模板填充
+const handleSearchTemplate = async () => {
+  if (!formData.value.positionId) return message.warning('请先选择职位类型')
+  const res = await JobAdvertisedApi.getRecruitPositionDetails(formData.value.positionId)
+
+  if (!res || !res.content || !res.requirement) {
+    message.warning('此职位类型没有可使用的模板!')
+    showTemplateBtn.value = false
+    return
+  }
+  if (formData.value.content || formData.value.requirement) {
+    await message.confirm('您确定要放弃目前岗位描述的内容吗?')
+    formData.value.content = res.content
+    formData.value.requirement = res.requirement
+    message.success('模板填充完成!')
+  } else {
+    // 无内容点击默认填充
+    formData.value.content = res.content
+    formData.value.requirement = res.requirement
+    message.success('模板填充完成!')
+  }
+}
 
 /** 打开弹窗 */
 const open = async (type: string, id?: number) => {
@@ -144,6 +212,10 @@ const open = async (type: string, id?: number) => {
     formLoading.value = true
     try {
       formData.value = await JobAdvertisedApi.getJobAdvertised(id)
+      formData.value.expType = Number(formData.value.expType)
+      formData.value.eduType = Number(formData.value.eduType)
+      formData.value.payUnit = Number(formData.value.payUnit)
+      formData.value.type = Number(formData.value.type)
     } finally {
       formLoading.value = false
     }
@@ -156,6 +228,7 @@ const emit = defineEmits(['success']) // 定义 success 事件,用于操作成
 const submitForm = async () => {
   // 校验表单
   await formRef.value.validate()
+  if (!loadingTerm.value && !formData.value.expireTime) return message.warning('请选择过期时间')
   // 提交请求
   formLoading.value = true
   try {
@@ -179,23 +252,21 @@ const submitForm = async () => {
 const resetForm = () => {
   formData.value = {
     id: undefined,
-    enterpriseId: undefined,
-    userId: undefined,
     areaId: undefined,
     name: undefined,
     positionId: undefined,
     type: undefined,
     expType: undefined,
+    payUnit: undefined,
+    expireTime: undefined,
     eduType: undefined,
-    payFrom: undefined,
-    payTo: undefined,
-    tagList: undefined,
+    payFrom: 6000,
+    hirePrice: 10,
+    payTo: 8000,
+    // tagList: undefined,
     content: undefined,
     requirement: undefined,
-    address: undefined,
-    longitude: undefined,
-    latitude: undefined,
-    status: undefined
+    address: undefined
   }
   formRef.value?.resetFields()
 }

+ 74 - 97
src/views/menduner/system/job/index.vue

@@ -8,16 +8,6 @@
       :inline="true"
       label-width="68px"
     >
-      <el-form-item label="工作地区" prop="areaId">
-        <el-select
-          v-model="queryParams.areaId"
-          placeholder="请选择工作地区"
-          clearable
-          class="!w-240px"
-        >
-          <el-option label="请选择字典生成" value="" />
-        </el-select>
-      </el-form-item>
       <el-form-item label="职位名称" prop="name">
         <el-input
           v-model="queryParams.name"
@@ -27,15 +17,11 @@
           class="!w-240px"
         />
       </el-form-item>
+      <el-form-item label="工作地区" prop="areaId">
+        <el-cascader v-model="queryParams.areaId" :options="areaTreeData" clearable :props="{ label: 'name', value: 'id', emitPath: false }"  class="!w-240px" />
+      </el-form-item>
       <el-form-item label="职位类型" prop="positionId">
-        <el-select
-          v-model="queryParams.positionId"
-          placeholder="请选择职位类型"
-          clearable
-          class="!w-240px"
-        >
-          <el-option label="请选择字典生成" value="" />
-        </el-select>
+        <el-cascader v-model="queryParams.positionId" :options="positionTreeData" clearable :props="{ label: 'nameCn', value: 'id', emitPath: false }"  class="!w-240px" />
       </el-form-item>
       <el-form-item label="招聘类型" prop="type">
         <el-select
@@ -59,7 +45,12 @@
           clearable
           class="!w-240px"
         >
-          <el-option label="请选择字典生成" value="" />
+          <el-option
+            v-for="dict in getIntDictOptions(DICT_TYPE.MENDUNER_EXP_TYPE)"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
         </el-select>
       </el-form-item>
       <el-form-item label="学历要求" prop="eduType">
@@ -69,18 +60,14 @@
           clearable
           class="!w-240px"
         >
-          <el-option label="请选择字典生成" value="" />
+          <el-option
+            v-for="dict in getIntDictOptions(DICT_TYPE.MENDUNER_EDUCATION_TYPE)"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
         </el-select>
       </el-form-item>
-      <el-form-item label="职位要求" prop="requirement">
-        <el-input
-          v-model="queryParams.requirement"
-          placeholder="请输入职位要求"
-          clearable
-          @keyup.enter="handleQuery"
-          class="!w-240px"
-        />
-      </el-form-item>
       <el-form-item label="职位状态" prop="status">
         <el-select
           v-model="queryParams.status"
@@ -89,7 +76,7 @@
           class="!w-240px"
         >
           <el-option
-            v-for="dict in getIntDictOptions(DICT_TYPE.MENDUNER_STATUS)"
+            v-for="dict in getIntDictOptions(DICT_TYPE.MENDUNER_JOB_STATUS)"
             :key="dict.value"
             :label="dict.label"
             :value="dict.value"
@@ -118,46 +105,42 @@
         >
           <Icon icon="ep:plus" class="mr-5px" /> 新增
         </el-button>
-        <el-button
-          type="success"
-          plain
-          @click="handleExport"
-          :loading="exportLoading"
-          v-hasPermi="['menduner:system:job-advertised:export']"
-        >
-          <Icon icon="ep:download" class="mr-5px" /> 导出
-        </el-button>
       </el-form-item>
     </el-form>
   </ContentWrap>
 
   <!-- 列表 -->
   <ContentWrap>
-    <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
-      <el-table-column label="id" align="left" prop="id" />
-      <!-- <el-table-column label="企业id" align="center" prop="enterpriseId" />
-      <el-table-column label="发布用户id" align="center" prop="userId" /> -->
-      <el-table-column label="工作地区" align="center" prop="areaId" />
+    <el-table v-loading="loading" :data="list" :stripe="true">
       <el-table-column label="职位名称" align="center" prop="name" />
-      <el-table-column label="职位类型" align="center" prop="positionId" />
+      <el-table-column label="职位类型" align="center" prop="positionName" />
+      <el-table-column label="工作地区" align="center" prop="areaName" />
       <el-table-column label="招聘类型" align="center" prop="type">
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.MENDUNER_JOB_TYPE" :value="scope.row.type" />
         </template>
       </el-table-column>
-      <el-table-column label="工作经验" align="center" prop="expType" />
-      <el-table-column label="学历要求" align="center" prop="eduType" />
-      <el-table-column label="薪酬from" align="center" prop="payFrom" />
-      <el-table-column label="薪酬to" align="center" prop="payTo" />
-      <el-table-column label="职位标签" align="center" prop="tagList" />
-      <el-table-column label="职位内容" align="center" prop="content" />
-      <el-table-column label="职位要求" align="center" prop="requirement" />
-      <el-table-column label="工作地址" align="center" prop="address" />
-      <el-table-column label="经度" align="center" prop="longitude" />
-      <el-table-column label="维度" align="center" prop="latitude" />
+      <el-table-column label="工作经验" align="center" prop="expType">
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.MENDUNER_EXP_TYPE" :value="scope.row.expType" />
+        </template>
+      </el-table-column>
+      <el-table-column label="学历要求" align="center" prop="eduType">
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.MENDUNER_EDUCATION_TYPE" :value="scope.row.eduType" />
+        </template>
+      </el-table-column>
+      <el-table-column label="最低薪资" align="center" prop="payFrom" />
+      <el-table-column label="最高薪资" align="center" prop="payTo" />
+      <el-table-column label="计薪时段" align="center" prop="payUnit">
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.MENDUNER_PAY_UNIT" :value="scope.row.payUnit" />
+        </template>
+      </el-table-column>
+      <el-table-column label="点数" align="center" prop="hirePrice" />
       <el-table-column label="职位状态" align="center" prop="status">
         <template #default="scope">
-          <dict-tag :type="DICT_TYPE.MENDUNER_STATUS" :value="scope.row.status" />
+          <dict-tag :type="DICT_TYPE.MENDUNER_JOB_STATUS" :value="scope.row.status" />
         </template>
       </el-table-column>
       <el-table-column
@@ -169,22 +152,9 @@
       />
       <el-table-column label="操作" align="center">
         <template #default="scope">
-          <el-button
-            link
-            type="primary"
-            @click="openForm('update', scope.row.id)"
-            v-hasPermi="['menduner:system:job-advertised:update']"
-          >
-            编辑
-          </el-button>
-          <el-button
-            link
-            type="danger"
-            @click="handleDelete(scope.row.id)"
-            v-hasPermi="['menduner:system:job-advertised:delete']"
-          >
-            删除
-          </el-button>
+          <el-button v-if="scope.row.status === '0'" link type="primary" @click="openForm('update', scope.row.id)">编辑</el-button>
+          <el-button v-if="scope.row.status === '0'" link type="primary" @click="handleAction(0, scope.row.id)">关闭</el-button>
+          <el-button v-if="scope.row.status === '1'" link type="primary" @click="handleAction(1, scope.row.id)">激活</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -198,7 +168,7 @@
   </ContentWrap>
 
   <!-- 表单弹窗:添加/修改 -->
-  <JobAdvertisedForm ref="formRef" @success="getList" />
+  <JobAdvertisedForm ref="formRef" :area="areaTreeData" :position="positionTreeData" @success="getList" />
 </template>
 
 <script setup lang="ts">
@@ -207,6 +177,8 @@ import { dateFormatter } from '@/utils/formatTime'
 import download from '@/utils/download'
 import { JobAdvertisedApi, JobAdvertisedVO } from '@/api/menduner/system/job'
 import JobAdvertisedForm from './JobAdvertisedForm.vue'
+import { dealDictArrayData } from '@/utils/transform/position'
+import { getDict } from '@/hooks/web/useDictionaries'
 
 /** 门墩儿-招聘职位 列表 */
 defineOptions({ name: 'JobAdvertised' })
@@ -229,17 +201,35 @@ const queryParams = reactive({
   content: undefined,
   requirement: undefined,
   status: undefined,
-  createTime: ''
+  createTime: '',
+  hire: true
 })
 const queryFormRef = ref() // 搜索的表单
 const exportLoading = ref(false) // 导出的加载中
 
+// 职位类型、地区树状列表
+const areaTreeData = ref([])
+const positionTreeData = ref([])
+const getDictData = async () => {
+  const { data } = await getDict('areaTreeData', {}, 'areaTreeData')
+  areaTreeData.value = data && data.length ? data : []
+
+  const { data: position } = await getDict('positionTreeData', {}, 'positionTreeData')
+  positionTreeData.value = position && position.length ? position : []
+}
+getDictData()
+
 /** 查询列表 */
 const getList = async () => {
   loading.value = true
   try {
     const data = await JobAdvertisedApi.getJobAdvertisedPage(queryParams)
-    list.value = data.list
+    if (!data.list || !data.list.length) {
+      list.value = []
+      total.value = 0
+      return
+    }
+    list.value = dealDictArrayData([], data.list)
     total.value = data.total
   } finally {
     loading.value = false
@@ -264,34 +254,21 @@ const openForm = (type: string, id?: number) => {
   formRef.value.open(type, id)
 }
 
-/** 删除按钮操作 */
-const handleDelete = async (id: number) => {
+/** 关闭、激活按钮操作 */
+const apiList = [
+  { label: '确定关闭该职位吗?', api: JobAdvertisedApi.closeJobAdvertised },
+  { label: '确定激活该职位吗?', api: JobAdvertisedApi.enAbleJobAdvertised }
+]
+const handleAction = async (index: number, id: number) => {
   try {
-    // 删除的二次确认
-    await message.delConfirm()
-    // 发起删除
-    await JobAdvertisedApi.deleteJobAdvertised(id)
-    message.success(t('common.delSuccess'))
+    await message.confirm(apiList[index].label)
+    await apiList[index].api(id)
+    message.success('操作成功')
     // 刷新列表
     await getList()
   } catch {}
 }
 
-/** 导出按钮操作 */
-const handleExport = async () => {
-  try {
-    // 导出的二次确认
-    await message.exportConfirm()
-    // 发起导出
-    exportLoading.value = true
-    const data = await JobAdvertisedApi.exportJobAdvertised(queryParams)
-    download.excel(data, '门墩儿-招聘职位.xls')
-  } catch {
-  } finally {
-    exportLoading.value = false
-  }
-}
-
 /** 初始化 **/
 onMounted(() => {
   getList()