lifanagju_citu 8 meses atrás
pai
commit
6a910fbb2c

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

@@ -0,0 +1,9 @@
+import request from '@/config/axios'
+
+// 字典
+export const dictApi = {
+  // 获取地区列表
+  getAreaListData: async (params: any) => {
+    return await request.get({ url: `/menduner/system/area/list`, params })
+  },
+}

+ 11 - 2
src/components/Echart/src/Echart.vue

@@ -11,6 +11,8 @@ import { useDesign } from '@/hooks/web/useDesign'
 
 defineOptions({ name: 'EChart' })
 
+const emit = defineEmits(['chartClick'])
+
 const { getPrefixCls, variables } = useDesign()
 
 const prefixCls = getPrefixCls('echart')
@@ -56,10 +58,17 @@ const styles = computed(() => {
   }
 })
 
-const initChart = () => {
+const EChartClickFun = (params) => {
+  emit('chartClick', params)
+}
+
+const initChart = async () => {
   if (unref(elRef) && props.options) {
-    echartRef = echarts.init(unref(elRef) as HTMLElement)
+    echartRef = await echarts.init(unref(elRef) as HTMLElement)
     echartRef?.setOption(unref(options))
+    echartRef.on('click', function(params) {
+      EChartClickFun(params)
+   })
   }
 }
 

+ 45 - 0
src/hooks/web/useDictionaries.js

@@ -0,0 +1,45 @@
+import { dictApi } from '@/api/menduner/common/useDictionaries'
+// 定义对应的api
+// const DICT_CITY_API = {
+//   menduner_exp_type: getDictData
+// }
+
+const setDict = (type, val, cacheTime = 7200) => {
+  localStorage.setItem(type, JSON.stringify({
+    data: val,
+    expire: Date.now() + cacheTime * 1000
+  }))
+}
+
+export const getDict = (type, params, apiType = 'dict') => {
+    if (!type) {
+      // console.error('type不存在', type, params, apiType)
+      return []
+    }
+    return new Promise((resolve) => {
+      const item = localStorage.getItem(type)
+      const catchData = item ? JSON.parse(item) : null
+      if (catchData && catchData.expire && (Date.now() <= catchData.expire)) {
+        return resolve({ data: catchData.data })
+      }
+      // 传参按照规范参数传
+      const query = params ? params : { type }
+      const apiFn = {
+        // dict: getDictData,
+        // positionTreeData: getPositionTreeData, // 职位tree
+        // areaTreeData: getAreaTreeData, // 区域tree
+        // industryTreeData: getIndustryTreeData, // 行业tree
+        // industryList: getIndustryListData,
+        // skillList: getSkillList,
+        areaList: dictApi.getAreaListData,
+        // areaMap: getAreaMapData,
+        // positionData: getPositionData
+      }
+      if (!apiFn[apiType]) return
+      
+      apiFn[apiType](query).then(data => {
+        setDict(type, data, Date.now())
+        resolve({ data })
+      })
+    })
+}

+ 1 - 0
src/utils/dict.ts

@@ -241,4 +241,5 @@ export enum DICT_TYPE {
   MENDUNER_EXP_TYPE = 'menduner_exp_type', // 工作经验
   MENDUNER_JOB_STATUS = 'menduner_job_status', // 求职状态
   MENDUNER_MARITAL_STATUS = 'menduner_marital_status', // 婚姻状况
+  MENDUNER_PAY_UNIT= 'menduner_pay_unit', // 薪资单位
 }

+ 79 - 0
src/utils/transform/date.js

@@ -0,0 +1,79 @@
+// 时间戳转换为年月日时分秒
+export const timesTampChange = (timestamp, format = 'Y-M-D h:m:s') => {
+  if (!timestamp) return ''
+  const date = new Date(timestamp)
+  const Y = date.getFullYear().toString()
+  const M = (date.getMonth() + 1).toString().padStart(2, '0')
+  const D = date.getDate().toString().padStart(2, '0')
+
+  const h = date.getHours().toString().padStart(2, '0')
+  const m = date.getMinutes().toString().padStart(2, '0')
+  const s = date.getSeconds().toString().padStart(2, '0')
+
+  const formatter = { 'Y': Y, 'M': M, 'D': D, 'h': h, 'm': m, 's': s } // 替换format中的占位符
+  let formattedDate = format.replace(/Y|M|D|h|m|s/g, matched => formatter[matched]) // 使用正则表达式匹配并替换占位符
+  
+  if (!formattedDate) formattedDate = Y + '-' + M + '-' + D + ' ' + h + ':' + m + ':' + s
+
+  return formattedDate
+}
+
+// 将 Wed May 01 2024 00:00:00 GMT+0800 (中国标准时间) 转换为时间戳
+export const getTimeStamp = (str) => {
+  if (!str) return ''
+  const date = new Date(str)
+  return date.getTime()
+}
+
+// 传入一个时间戳返回这个日期的最早时间点以及最晚时间点 输出:[1721232000000, 1721318399999]
+export const getDayBounds = (timestamp) => {
+  const date = new Date(timestamp)
+  date.setHours(0, 0, 0, 0)
+  const startOfDay = date.getTime()
+  const endOfDay = new Date(timestamp)
+  endOfDay.setHours(23, 59, 59, 999)
+  if (endOfDay.getDate() !== date.getDate()) {
+    endOfDay.setDate(endOfDay.getDate() - 1)
+    endOfDay.setHours(23, 59, 59, 999)
+  }
+  // 返回包含最早和最晚时间点的时间戳的数组
+  return [startOfDay, endOfDay.getTime()]
+}
+
+// 传入 Wed May 01 2024 00:00:00 GMT+0800 (中国标准时间) 输出 [2024-07-18 00:00:00, 2024-07-18 23:59:59]
+export const getStartAndEndOfDay = (dateTimeStr) => {
+  const date = new Date(dateTimeStr)
+
+  const year = date.getFullYear()
+  const month = String(date.getMonth() + 1).padStart(2, '0')
+  const day = String(date.getDate()).padStart(2, '0')
+
+  const startTime = `${year}-${month}-${day} 00:00:00`
+  const endTime = `${year}-${month}-${day} 23:59:59`
+  return [startTime, endTime]
+}
+
+// 传入一组时间戳,返回 [最早时间点,最晚时间点]
+export const  convertTimestampsToDayRange = (timestamps) => {
+  if (timestamps.length < 2) {
+    throw new Error('Timestamps array must contain at least two elements')
+  }
+  function formatDate(date) {
+    const year = date.getFullYear();
+    const month = String(date.getMonth() + 1).padStart(2, '0')
+    const day = String(date.getDate()).padStart(2, '0')
+    const hours = String(date.getHours()).padStart(2, '0')
+    const minutes = String(date.getMinutes()).padStart(2, '0')
+    const seconds = String(date.getSeconds()).padStart(2, '0')
+    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
+  }
+
+  const startDate = new Date(timestamps[0])
+  const endDate = new Date(timestamps[1])
+
+  const startOfDay = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate())
+
+  const endOfDay = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate() + 1, 0, 0, 0, -1)
+
+  return [formatDate(startOfDay), formatDate(endOfDay)]
+}

+ 34 - 0
src/utils/transform/getText.js

@@ -0,0 +1,34 @@
+import { getDict } from '@/hooks/web/useDictionaries'
+
+export const getText = (value, arr, itemText = 'label', itemValue = 'value') => { // 一维数组
+  if (!arr?.length || !(value && value !== 0)) return
+  const item = arr.find(formItem => formItem[itemValue] === value)
+  if (!item) return
+  return item[itemText]
+}
+export const getNameIdText = (value, arr) => {
+  getText(value, arr, 'name', 'id')
+}
+
+export const getDictText = async (value, type) => {
+  if (!type) return
+  const query = {
+    areaList: { dictName: 'menduner_area_type', params: {}, itemText: 'name', itemValue: 'id' },
+  }
+  if (!query[type]) return
+  const { data } = await getDict(query[type].dictName, query[type].params, type)
+  const itemText = query[type].itemText || 'label'
+  const itemValue = query[type].itemValue || 'value'
+  getText(value, data, itemText, itemValue)
+}
+
+export const getDictOptions = async (type) => {
+  if (!type) return
+  const query = {
+    areaList: { dictName: 'menduner_area_type', params: {}, itemText: 'name', itemValue: 'id' },
+  }
+  if (!query[type]) return
+  const { data } = await getDict(query[type].dictName, query[type].params, type)
+  return data || []
+}
+

+ 7 - 2
src/views/menduner/system/analysis/statisticAnalysis/components/AgeDistribution.vue

@@ -11,6 +11,7 @@
 </template>
 
 <script lang="ts" setup>
+// import Echart from '@/components/Echart'
 import { EChartsOption } from 'echarts'
 defineOptions({name: 'AgeDistribution'})
 const props = defineProps({
@@ -19,8 +20,8 @@ const props = defineProps({
     default: () => ''
   },
   data: {
-    type: Array,
-    default: () => []
+    type: Object,
+    default: () => {}
   },
 })
 
@@ -61,6 +62,10 @@ watch(() => props.data, (newVal: any) => {
   chartOptions.xAxis.data = newVal.x || []
   chartOptions.series![0].data = newVal.y || []
 })
+const EChartClick = (obj) => {
+  console.log('1', obj)
+  debugger
+}
 </script>
 <style lang="scss" scoped>
 </style>

+ 2 - 2
src/views/menduner/system/analysis/statisticAnalysis/components/Education.vue

@@ -19,8 +19,8 @@ const props = defineProps({
     default: () => ''
   },
   data: {
-    type: Array,
-    default: () => []
+    type: Object,
+    default: () => {}
   },
 })
 

+ 2 - 2
src/views/menduner/system/analysis/statisticAnalysis/components/SexDistribution.vue

@@ -19,8 +19,8 @@ const props = defineProps({
     default: () => ''
   },
   data: {
-    type: Array,
-    default: () => []
+    type: Object,
+    default: () => {}
   },
 })
 

+ 2 - 2
src/views/menduner/system/analysis/statisticAnalysis/components/WorkExperience.vue

@@ -19,8 +19,8 @@ const props = defineProps({
     default: () => ''
   },
   data: {
-    type: Array,
-    default: () => []
+    type: Object,
+    default: () => {}
   },
 })
 

+ 209 - 121
src/views/menduner/system/analysis/statisticAnalysis/index.vue

@@ -107,39 +107,53 @@
     <div class="flex flex-col">
       <!-- 数据对照 -->
       <el-row :gutter="16" class="row">
-        <el-col :md="4" :sm="12" :xs="24" :loading="loading">
-          <ComparisonCard  title="职位浏览量" :value="pageViews.total" />
-        </el-col>
-        <el-col :md="4" :sm="12" :xs="24" :loading="loading">
-          <ComparisonCard  title="收到的简历" :value="resumeReceived.total" />
-        </el-col>
-        <el-col :md="4" :sm="12" :xs="24" :loading="loading">
-          <ComparisonCard  title="已查看简历" :value="resumeViewed.total" />
-        </el-col>
-        <el-col :md="4" :sm="12" :xs="24" :loading="loading">
-          <ComparisonCard  title="已邀面试" :value="invitedInterviews.total" />
-        </el-col>
-        <el-col :md="4" :sm="12" :xs="24" :loading="loading">
-          <ComparisonCard  title="面试完成" :value="invitedCompleted.total" />
+        <el-col v-for="item in statisticList" :key="item.name" :md="4" :sm="12" :xs="24" :loading="loading">
+          <ComparisonCard
+            :title="item.title"
+            :value="statistic[item.name]"
+            style="cursor: pointer;"
+            @click="openDialog(item)"
+          />
         </el-col>
       </el-row>
       <el-row :gutter="16" class="row">
         <el-col :md="12">
-          <SexDistribution :data="sexDistributionData" title="性别分布" />
+          <SexDistribution :data="distribution.sexDistributionData" title="性别分布" />
         </el-col>
         <el-col :md="12">
-          <ageDistribution :data="ageDistributionData" title="年龄分布" />
+          <ageDistribution :data="distribution.ageDistributionData" title="年龄分布" />
         </el-col>
       </el-row>
       <el-row :gutter="16" class="row">
         <el-col :md="12">
-          <workExperience :data="workExperienceData" title="工作年限分布" />
+          <workExperience :data="distribution.workExperienceData" title="工作年限分布" />
         </el-col>
         <el-col :md="12">
-          <education :data="educationData" title="学历分布" />
+          <education :data="distribution.educationData" title="学历分布" />
         </el-col>
       </el-row>
     </div>
+    <!-- 弹窗 -->
+    <Dialog :title="currentItem.title+'详情'" v-model="showDialog" width="1200" @close="closeDialog">
+      <ContentWrap>
+        <el-table v-loading="dialogLoading" :data="tableData" :stripe="true" :show-overflow-tooltip="true">
+          <el-table-column
+            v-for="item in tableHeaders[currentItem.name]"
+            :key="item.prop"
+            :prop="item.prop"
+            :label="item.name"
+            :align="item.align || 'center'"
+          />
+        </el-table>
+        <!-- 分页 -->
+        <Pagination
+          :total="total"
+          v-model:page="page.pageNo"
+          v-model:limit="page.pageSize"
+          @pagination="paginationChange"
+        />
+      </ContentWrap>
+    </Dialog>
 </div>
 </template>
 
@@ -150,20 +164,17 @@ import ageDistribution from './components/AgeDistribution.vue'
 import workExperience from './components/WorkExperience.vue'
 import education from './components/Education.vue'
 import { statisticAnalysisApi } from '@/api/menduner/system/analysis/statisticAnalysis'
+// import { dealDictArrayData, dealDictObjData } from '@/utils/position'
 defineOptions({name: 'StatisticAnalysis'})
 
 const loading = ref(true) // 加载中
 
 /** 初始化 **/
 onMounted(async () => {
-  // loading.value = true
-  loading.value = false
+  loading.value = true
 })
 
-// const pageParams = {
-//   pageNo: 1,
-//   pageSize: 10,
-// }
+const page = reactive({ pageNo: 1, pageSize: 10 })
 const queryParams = reactive({
   pageNo: 1,
   pageSize: 10,
@@ -194,132 +205,209 @@ const timeRangeChange = (value) => {
   handleQuery()
 }
 
-// 职位浏览量
-const pageViews = reactive({ list: [], total: 0 })
-const getPageViewsList = async () => {
-  loading.value = true
-  try {
-    const data = await statisticAnalysisApi.getAnalysisJobBrowseNumPage(queryParams)
-    pageViews.list = data.list
-    pageViews.total = data.total
-  } finally {
-    loading.value = false
-  }
-}
+const apiArr = reactive({
+  // 统计
+  pageViews: statisticAnalysisApi.getAnalysisJobBrowseNumPage,
+  resumeReceived: statisticAnalysisApi.getAnalysisJobCvNewPage,
+  resumeViewed: statisticAnalysisApi.getAnalysisJobCvLookPage,
+  invitedInterviews: statisticAnalysisApi.getAnalysisInterviewWaitPage,
+  invitedCompleted: statisticAnalysisApi.getAnalysisInterviewCompletePage,
+  // 分布
+  sexDistributionData: statisticAnalysisApi.getAnalysisJobCvSexCount,
+  ageDistributionData: statisticAnalysisApi.getAnalysisJobCvAgeCount,
+  workExperienceData: statisticAnalysisApi.getAnalysisJobCvExpCount,
+  educationData: statisticAnalysisApi.getAnalysisJobCvEduCount,
+})
 
-// 收到的简历
-const resumeReceived = reactive({ list: [], total: 0 })
-const getResumeReceivedList = async () => {
-  loading.value = true
-  try {
-    const data = await statisticAnalysisApi.getAnalysisJobCvNewPage(queryParams)
-    resumeReceived.list = data.list
-    resumeReceived.total = data.total
-  } finally {
-    loading.value = false
-  }
-}
+// 统计
+const statisticList = [
+  { title: '职位浏览量', name: 'pageViews' },
+  { title: '收到的简历', name: 'resumeReceived' },
+  { title: '已查看简历', name: 'resumeViewed' },
+  { title: '已邀面试', name: 'invitedInterviews' },
+  { title: '面试完成', name: 'invitedCompleted' },
+]
+// 统计
+const statistic = reactive({
+  pageViews: 0,
+  resumeReceived: 0,
+  resumeViewed: 0,
+  invitedInterviews: 0,
+  invitedCompleted: 0,
+})
 
-// 已查看简历
-const resumeViewed = reactive({ list: [], total: 0 })
-const getResumeViewedList = async () => {
-  loading.value = true
-  try {
-    const data = await statisticAnalysisApi.getAnalysisJobCvLookPage(queryParams)
-    resumeViewed.list = data.list
-    resumeViewed.total = data.total
-  } finally {
-    loading.value = false
-  }
-}
+// 分布
+const distribution = reactive({
+  sexDistributionData: {},
+  ageDistributionData: {},
+  workExperienceData: {},
+  educationData: {},
+})
 
-// 已邀面试
-const invitedInterviews = reactive({ list: [], total: 0 })
-const getInvitedInterviewsList = async () => {
+// 统计
+const getList = async (typeName, deal = '') => {
   loading.value = true
   try {
-    const data = await statisticAnalysisApi.getAnalysisInterviewWaitPage(queryParams)
-    invitedInterviews.list = data.list
-    invitedInterviews.total = data.total
+    const data = await apiArr[typeName]({ ...queryParams, ...customTimeObj })
+    tableData.value = data.list || []
+    statistic[typeName] = data.total
+    if (deal) dealTableData()
   } finally {
     loading.value = false
+    dialogLoading.value = false
   }
 }
 
-// 面试完成
-const invitedCompleted = reactive({ list: [], total: 0 })
-const getInvitedCompletedList = async () => {
-  loading.value = true
-  try {
-    const data = await statisticAnalysisApi.getAnalysisInterviewCompletePage(queryParams)
-    invitedCompleted.list = data.list
-    invitedCompleted.total = data.total
-  } finally {
-    loading.value = false
-  }
+import { getDictOptions } from '@/utils/transform/getText'
+import { timesTampChange } from '@/utils/transform/date'
+import { DICT_TYPE, getDictLabel } from '@/utils/dict'
+
+const getText = (value, arr, itemText = 'name', itemValue = 'id') => { // 一维数组
+  if (!arr?.length || !(value && value !== 0)) return
+  const item = arr.find(formItem => formItem[itemValue] === value)
+  if (!item) return
+  return item[itemText]
 }
 
-// 性别分布
-const sexDistributionData = ref(null)
-const getAnalysisJobCvSexCount = async () => {
-  try {
-    const data = await statisticAnalysisApi.getAnalysisJobCvSexCount(queryParams)
-    if (data) sexDistributionData.value = data
-    console.log('性别分布', data)
-  } catch (error) {
-    console.log(error)
+const dealTableData = async () => {
+  if (currentItem.value.name === 'pageViews') {
+    const areaList = await getDictOptions('areaList')
+    tableData.value = tableData.value.map(item => {
+      item.salaryDisplay = `${item.payFrom}-${item.payTo}/${getDictLabel(DICT_TYPE.MENDUNER_PAY_UNIT, item.payUnit)}`
+      item.areaName = getText(item.areaId, areaList)
+      item.expName = getDictLabel(DICT_TYPE.MENDUNER_EXP_TYPE, item.expType)
+      item.eduName = getDictLabel(DICT_TYPE.MENDUNER_EDUCATION_TYPE, item.eduType)
+      return item
+    })
   }
-}
-// 年龄分布
-const ageDistributionData = ref(null)
-const getAnalysisJobCvAgeCount = async () => {
-  try {
-    const data = await statisticAnalysisApi.getAnalysisJobCvAgeCount(queryParams)
-    if (data) ageDistributionData.value = data
-  } catch (error) {
-    console.log(error)
+  if (currentItem.value.name === 'resumeReceived') {
+    const areaList = await getDictOptions('areaList')
+    tableData.value = tableData.value.map(item => {
+      item.areaName = getText(item.job.areaId, areaList)
+      item.salaryDisplay = `${item.job.payFrom}-${item.job.payTo}/${getDictLabel(DICT_TYPE.MENDUNER_PAY_UNIT, item.job.payUnit)}`
+      item.jobStatus = getDictLabel(DICT_TYPE.MENDUNER_JOB_STATUS, item.person.jobStatus)
+      item.expName = getDictLabel(DICT_TYPE.MENDUNER_EXP_TYPE, item.job.expType)
+      item.eduName = getDictLabel(DICT_TYPE.MENDUNER_EDUCATION_TYPE, item.job.eduType)
+      item.personName = item.person.name
+      return item
+    })
   }
-}
-// 工作年限分布
-const workExperienceData = ref(null)
-const getAnalysisJobCvExpCount = async () => {
-  try {
-    const data = await statisticAnalysisApi.getAnalysisJobCvExpCount(queryParams)
-    if (data) workExperienceData.value = data
-  } catch (error) {
-    console.log(error)
+  if (currentItem.value.name === 'resumeViewed') {
+    tableData.value = tableData.value.map(item => {
+      item.personName = item.person.name
+      item.address = item.job.address
+      item.typeName = item.type === 0 ? '平台投递': '赏金投递'
+      item.recommendPersonName = item.recommendPerson?.name || ''
+      return item
+    })
+  }
+  if (currentItem.value.name === 'invitedInterviews') {
+    tableData.value = tableData.value.map(item => {
+      item.personName = item.person.name
+      item.jobName = item.job.name
+      item.typeName = item.type === 0 ? '线上面试': '线下面试'
+      item.timeName = timesTampChange(item.time, 'Y-M-D h:m')
+      item.addressName = item.job.address
+      return item
+    })
+  }
+  if (currentItem.value.name === 'invitedCompleted') {
+    tableData.value = tableData.value.map(item => {
+      item.personName = item.person.name
+      item.jobName = item.job.name
+      item.typeName = item.type === 0 ? '线上面试': '线下面试'
+      item.timeName = timesTampChange(item.time, 'Y-M-D h:m')
+      item.addressName = item.job.address
+      return item
+    })
   }
 }
-// 学历分布
-const educationData = ref(null)
-const getAnalysisJobCvEduCount = async () => {
+
+// 分布
+const getDistributionCount = async (typeName) => {
   try {
-    const data = await statisticAnalysisApi.getAnalysisJobCvEduCount(queryParams)
-    if (data) educationData.value = data
+    const data = await apiArr[typeName]({ ...queryParams, ...customTimeObj })
+    distribution[typeName] = data || {}
   } catch (error) {
     console.log(error)
   }
 }
 
-
 /** 搜索按钮操作 */
 let customTimeObj
 const handleQuery = () => {
   customTimeObj = queryParams.type === '99' && queryParams.dateRange?.length === 2 ? customTimeObj = { 'time[0]': queryParams.dateRange.date[0] + ' 00:00:00', 'time[1]': queryParams.dateRange.date[1] + ' 23:59:59' } : {}
-  queryParams.value = { ...queryParams, ...customTimeObj }
-  queryParams.pageNo = 1
-  getPageViewsList()
-  getResumeReceivedList()
-  getResumeViewedList()
-  getInvitedInterviewsList()
-  getInvitedCompletedList()
-  getAnalysisJobCvSexCount()
-  getAnalysisJobCvAgeCount()
-  getAnalysisJobCvExpCount()
-  getAnalysisJobCvEduCount()
+  if (Object.keys(statistic).length) {
+    Object.keys(statistic).forEach(name => {
+      getList(name)
+    })
+  }
+  // 
+  if (Object.keys(distribution).length) {
+    Object.keys(distribution).forEach(name => {
+      getDistributionCount(name)
+    })
+  }
 }
 handleQuery()
 
+const showDialog = ref(false)
+const dialogLoading = ref(false)
+const tableData = ref([])
+const currentItem = ref({})
+// 打开弹窗
+const openDialog = (item) => {
+  dialogLoading.value = true
+  queryParams.pageNo = 1
+  currentItem.value = item
+  tableData.value = []
+  getList(item.name, '钻取')
+  showDialog.value = true
+}
+const closeDialog = () => {
+}
+
+const tableHeaders = {
+  pageViews: [
+    { name: '招聘职位', prop: 'name' },
+    { name: '薪酬', prop: 'salaryDisplay' },
+    { name: '工作地区', prop: 'areaName' },
+    { name: '工作经验', prop: 'expName' },
+    { name: '学历要求', prop: 'eduName' },
+    { name: '浏览量', prop: 'num' }
+  ],
+  resumeReceived: [
+    { name: '投递人', prop: 'personName' },
+    { name: '求职状态', prop: 'jobStatus' },
+    { name: '薪酬', prop: 'salaryDisplay' },
+    { name: '工作地区', prop: 'areaName' },
+    { name: '工作经验', prop: 'expName' },
+    { name: '学历要求', prop: 'eduName' },
+  ],
+  resumeViewed: [
+    { name: '简历标题', prop: 'title' },
+    { name: '投递人', prop: 'personName' },
+    { name: '投递类型', prop: 'typeName' },
+    { name: '推荐人', prop: 'recommendPersonName' },
+  ],
+  invitedInterviews: [
+    { name: '求职者', prop: 'personName' },
+    { name: '面试岗位', prop: 'jobName' },
+    { name: '面试类型', prop: 'typeName' },
+    { name: '面试时间', prop: 'timeName' },
+    { name: '面试地点', prop: 'addressName' },
+
+  ],
+  invitedCompleted: [
+    { name: '求职者', prop: 'personName' },
+    { name: '面试岗位', prop: 'jobName' },
+    { name: '面试类型', prop: 'typeName' },
+    { name: '面试时间', prop: 'timeName' },
+    { name: '面试地点', prop: 'addressName' },
+    { name: '反馈评价', prop: 'evaluate' },
+  ],
+}
+
 const enterpriseOption = [
   { label: '企业 1', value: '1' },
   { label: '企业 2', value: '2' },