|
@@ -1,89 +1,56 @@
|
|
|
<template>
|
|
|
<v-card class="card-box pa-5">
|
|
|
<div class="d-flex justify-space-between">
|
|
|
- <TextUI :item="textItem" @enter="handleEnter" @appendInnerClick="handleEnter"></TextUI>
|
|
|
- <v-btn color="primary" prependIcon="mdi-filter-multiple-outline" class="half-button" variant="tonal" @click="screen = true">筛选</v-btn>
|
|
|
+ <div></div>
|
|
|
+ <v-btn color="primary" prependIcon="mdi-filter-multiple-outline" class="half-button" variant="tonal" @click="openDrawer">筛选</v-btn>
|
|
|
</div>
|
|
|
- <div v-if="items.length" class="d-flex align-center" style="margin-left: 14px;">
|
|
|
- <v-checkbox v-model="selectAll" :label="!selectAll ? '全选' : `已选中${selectList.length}条`" hide-details color="primary" @update:model-value="handleChangeSelectAll"></v-checkbox>
|
|
|
- <v-btn class="ml-8" :disabled="!selectAll" color="primary" variant="tonal" size="small">邀请面试</v-btn>
|
|
|
- <v-btn class="mx-3" :disabled="!selectAll" color="primary" variant="tonal" size="small">简历回复</v-btn>
|
|
|
- <v-btn :disabled="!selectAll" color="primary" variant="tonal" size="small">批量导出</v-btn>
|
|
|
- <v-btn class="mx-3" :disabled="!selectAll" color="primary" variant="tonal" size="small">踢出人才库</v-btn>
|
|
|
- <v-btn :disabled="!selectAll" color="primary" variant="tonal" size="small">移动到回收站</v-btn>
|
|
|
- <v-btn class="ml-3" :disabled="!selectAll" color="primary" variant="tonal" size="small">加入黑名单</v-btn>
|
|
|
- </div>
|
|
|
- <div v-if="items.length">
|
|
|
- <div v-for="val in items" :key="val.id" class="list-item mb-3">
|
|
|
- <div class="top">
|
|
|
- <v-checkbox class="mr-5" v-model="val.select" color="primary" density="compact" hide-details @update:model-value="handleChangeSelect"></v-checkbox>
|
|
|
- <span>应聘/意向职位:{{ val.job.name }}</span>
|
|
|
- <span class="mx-10">加入时间:{{ val.createTime }}</span>
|
|
|
- <span>人才分类:{{ val.type }}</span>
|
|
|
- </div>
|
|
|
- <div @click.stop="talentPoolDetails(val)" class="px-5 py-3 d-flex justify-space-between align-center cursor-pointer">
|
|
|
- <div class="d-flex">
|
|
|
+ <div v-if="dataList?.length" class="mt-3">
|
|
|
+ <v-data-table
|
|
|
+ class="mt-3"
|
|
|
+ :items="dataList"
|
|
|
+ :headers="headers"
|
|
|
+ hover
|
|
|
+ :disable-sort="true"
|
|
|
+ item-value="id"
|
|
|
+ >
|
|
|
+ <template #bottom></template>
|
|
|
+ <template v-slot:[`item.name`]="{ item }">
|
|
|
+ <div class="d-flex align-center cursor-pointer" @click="talentPoolDetails(item)">
|
|
|
<v-badge
|
|
|
bordered
|
|
|
- offset-x="6"
|
|
|
- offset-y="44"
|
|
|
- :color="val.sex ? (val.sex === '1' ? '#1867c0' : 'error') : 'error'"
|
|
|
- :icon="val.sex ? (val.sex === '1' ? 'mdi-gender-male' : 'mdi-gender-female') : 'mdi-gender-female'">
|
|
|
- <v-avatar size="large" :image="val.avatar || 'https://minio.citupro.com/dev/menduner/7.png'"></v-avatar>
|
|
|
+ offset-y="6"
|
|
|
+ :color="badgeColor(item)"
|
|
|
+ :icon="badgeIcon(item)">
|
|
|
+ <v-avatar size="40" :image="getUserAvatar(item.avatar, item.sex)"></v-avatar>
|
|
|
</v-badge>
|
|
|
- <div class="ml-5">
|
|
|
- <div class="user-name">{{ val.name }}</div>
|
|
|
- <div class="mt-2 user-info">
|
|
|
- <span v-for="(k, i) in dict" :key="k">
|
|
|
- {{ val[k] }}
|
|
|
- <span v-if="i !== dict.length - 1" class="mx-3">|</span>
|
|
|
- </span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- <v-btn color="primary" variant="tonal" @click.stop="{}">和TA聊聊</v-btn>
|
|
|
- <v-btn class="ml-3" color="primary" @click.stop="{}">邀请面试</v-btn>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="d-flex mx-5 bottom cursor-pointer">
|
|
|
- <div class="experience" v-if="val.exp.length">
|
|
|
- <div class="second-title">工作经验</div>
|
|
|
- <v-timeline density="compact" align="start" side="end" truncate-line="both">
|
|
|
- <v-timeline-item v-for="(j, i) in val.exp" :key="i" dot-color="primary" size="small">
|
|
|
- <div class="timeline-item mt-1">
|
|
|
- <div>{{ j.startTime }}-{{ j.endTime }} ({{ j.year }})</div>
|
|
|
- <div class="timeline-item-name ellipsis">{{ j.name }}</div>
|
|
|
- <div class="timeline-item-name ellipsis">{{ j.jobName }}</div>
|
|
|
- </div>
|
|
|
- </v-timeline-item>
|
|
|
- </v-timeline>
|
|
|
- </div>
|
|
|
- <div class="edu" v-if="val.edu.length">
|
|
|
- <div class="second-title">教育经历</div>
|
|
|
- <v-timeline density="compact" align="start" side="end" truncate-line="both">
|
|
|
- <v-timeline-item v-for="(j, i) in val.edu" :key="i" dot-color="primary" size="small">
|
|
|
- <div class="timeline-item mt-1">
|
|
|
- <div>{{ j.startTime }}-{{ j.endTime }}</div>
|
|
|
- <div class="timeline-item-name ellipsis">{{ j.name }}</div>
|
|
|
- <div class="timeline-item-name ellipsis">{{ j.major }}</div>
|
|
|
- </div>
|
|
|
- </v-timeline-item>
|
|
|
- </v-timeline>
|
|
|
+ <span class="defaultLink ml-3">{{ item?.name }}</span>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ </template>
|
|
|
+ <template v-slot:[`item.advantage`]="{ item }">
|
|
|
+ <template v-if="item.advantage">
|
|
|
+ <v-btn color="primary" variant="tonal" @click="advantageDetail(item.advantage)">查看</v-btn>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ <template v-slot:[`item.actions`]="{ item }">
|
|
|
+ <v-btn color="primary" variant="text" @click="handleRemove(item)">踢出人才库</v-btn>
|
|
|
+ <v-btn color="primary" variant="text" @click="talentPoolDetails(item)">人才详情</v-btn>
|
|
|
+ </template>
|
|
|
+ </v-data-table>
|
|
|
<CtPagination
|
|
|
:total="total"
|
|
|
- :page="query.pageNo"
|
|
|
- :limit="query.pageSize"
|
|
|
+ :page="pageInfo.pageNo"
|
|
|
+ :limit="pageInfo.pageSize"
|
|
|
@handleChange="handleChangePage"
|
|
|
></CtPagination>
|
|
|
</div>
|
|
|
<Empty v-else :message="tipsText" :elevation="false" class="mt-15"></Empty>
|
|
|
|
|
|
<v-navigation-drawer v-model="screen" location="right" absolute temporary width="700">
|
|
|
- <FilterPage></FilterPage>
|
|
|
+ <FilterPage
|
|
|
+ ref="FilterPageRef"
|
|
|
+ @confirm="handleConfirm"
|
|
|
+ @cancel="screen = false"
|
|
|
+ ></FilterPage>
|
|
|
</v-navigation-drawer>
|
|
|
</v-card>
|
|
|
</template>
|
|
@@ -92,147 +59,92 @@
|
|
|
// import { useRouter } from 'vue-router'
|
|
|
// const router = useRouter()
|
|
|
defineOptions({ name: 'enterprise-talent-pool'})
|
|
|
-import { ref } from 'vue'
|
|
|
-import TextUI from '@/components/FormUI/TextInput'
|
|
|
+import { useI18n } from '@/hooks/web/useI18n'; const { t } = useI18n()
|
|
|
+import { computed, reactive, ref } from 'vue'
|
|
|
+import Snackbar from '@/plugins/snackbar'
|
|
|
import FilterPage from './components/filter.vue'
|
|
|
+import { dealDictArrayData } from '@/utils/position'
|
|
|
+import { getTalentPoolPage } from '@/api/recruit/enterprise/resumeManagement/talentPool'
|
|
|
+import { removeFormTalentPool } from '@/api/recruit/enterprise/personnel'
|
|
|
+import { timesTampChange } from '@/utils/date'
|
|
|
+import { getUserAvatar } from '@/utils/avatar'
|
|
|
|
|
|
+
|
|
|
+let query = {}
|
|
|
const screen = ref(false)
|
|
|
-const selectAll = ref(false)
|
|
|
-const selectList = ref([])
|
|
|
-const items = ref([
|
|
|
- {
|
|
|
- job: {
|
|
|
- name: '客房服务员'
|
|
|
- },
|
|
|
- createTime: '2026-11-12',
|
|
|
- type: '默认分类',
|
|
|
- name: '花城',
|
|
|
- age: '27岁',
|
|
|
- expName: '3年经验',
|
|
|
- areaName: '广州',
|
|
|
- userId: '1',
|
|
|
- id: '1793583467288223745',
|
|
|
- sex: '2',
|
|
|
- select: false,
|
|
|
- eduName: '本科',
|
|
|
- payName: '薪资面议',
|
|
|
- avatar: 'https://cdn.vuetifyjs.com/images/john.jpg',
|
|
|
- exp: [
|
|
|
- {
|
|
|
- startTime: '2016.05',
|
|
|
- endTime: '2018.05',
|
|
|
- year: '2年',
|
|
|
- name: '广州辞图科技有限公司',
|
|
|
- jobName: '前台'
|
|
|
- },
|
|
|
- {
|
|
|
- startTime: '2016.05',
|
|
|
- endTime: '2018.05',
|
|
|
- year: '2年',
|
|
|
- name: '广州辞图科技有限公司',
|
|
|
- jobName: '前台'
|
|
|
- }
|
|
|
- ],
|
|
|
- edu: [
|
|
|
- {
|
|
|
- startTime: '2016.05',
|
|
|
- endTime: '2018.05',
|
|
|
- name: '广州大学',
|
|
|
- major: '酒店管理'
|
|
|
- }
|
|
|
- ]
|
|
|
- },
|
|
|
- {
|
|
|
- job: {
|
|
|
- name: '客房服务员'
|
|
|
- },
|
|
|
- createTime: '2026-11-12',
|
|
|
- type: '默认分类',
|
|
|
- name: '花城',
|
|
|
- age: '27岁',
|
|
|
- expName: '3年经验',
|
|
|
- areaName: '广州',
|
|
|
- userId: '1',
|
|
|
- id: '1793583467288223745',
|
|
|
- sex: '2',
|
|
|
- select: false,
|
|
|
- eduName: '本科',
|
|
|
- payName: '薪资面议',
|
|
|
- avatar: 'https://cdn.vuetifyjs.com/images/john.jpg',
|
|
|
- exp: [
|
|
|
- {
|
|
|
- startTime: '2016.05',
|
|
|
- endTime: '2018.05',
|
|
|
- year: '2年',
|
|
|
- name: '广州辞图科技有限公司',
|
|
|
- jobName: '前台'
|
|
|
- },
|
|
|
- {
|
|
|
- startTime: '2016.05',
|
|
|
- endTime: '2018.05',
|
|
|
- year: '2年',
|
|
|
- name: '广州辞图科技有限公司',
|
|
|
- jobName: '前台'
|
|
|
- }
|
|
|
- ],
|
|
|
- edu: [
|
|
|
- {
|
|
|
- startTime: '2016.05',
|
|
|
- endTime: '2018.05',
|
|
|
- name: '广州大学',
|
|
|
- major: '酒店管理'
|
|
|
- }
|
|
|
- ]
|
|
|
- }
|
|
|
-])
|
|
|
-items.value = [] // 暂定无数据展示
|
|
|
+const dataList = ref([])
|
|
|
+// dataList.value = [] // 暂定无数据展示
|
|
|
const tipsText = ref('暂无数据')
|
|
|
const total = ref(2)
|
|
|
-const query = ref({
|
|
|
- pageNo: 1,
|
|
|
- pageSize: 10
|
|
|
-})
|
|
|
+const pageInfo = reactive({ pageNo: 1, pageSize: 10 })
|
|
|
|
|
|
-const textItem = ref({
|
|
|
- type: 'text',
|
|
|
- width: 600,
|
|
|
- value: '',
|
|
|
- label: '请输入简历姓名/职位名称',
|
|
|
- appendInnerIcon: 'mdi-magnify'
|
|
|
-})
|
|
|
-const dict = ['age', 'expName', 'areaName', 'eduName', 'payName']
|
|
|
|
|
|
-const handleEnter = (e) => {
|
|
|
- console.log(e, 'enter')
|
|
|
-}
|
|
|
+// 获取数据
|
|
|
+const getData = async () => {
|
|
|
+ const obj = { ...pageInfo, ...query }
|
|
|
+ console.log('obj', obj)
|
|
|
+ const { list, total: number } = await getTalentPoolPage(pageInfo)
|
|
|
+ total.value = number
|
|
|
+ dataList.value = list?.length ? dealDictArrayData([], list) : []
|
|
|
+ console.log('items.value', dataList.value)
|
|
|
+}
|
|
|
+getData()
|
|
|
+
|
|
|
|
|
|
-const dealSelect = () => {
|
|
|
- selectList.value = items.value.filter(e => e.select).map(k => k.id)
|
|
|
+// 移出人才库
|
|
|
+const handleRemove = async (item) => {
|
|
|
+ if (!item.userId) return Snackbar.warning('数据异常')
|
|
|
+ await removeFormTalentPool(item.userId)
|
|
|
+ Snackbar.success(t('common.operationSuccessful'))
|
|
|
+ getData()
|
|
|
}
|
|
|
|
|
|
-// 全选
|
|
|
-const handleChangeSelectAll = () => {
|
|
|
- items.value.map(k => {
|
|
|
- k.select = selectAll.value
|
|
|
- return k
|
|
|
- })
|
|
|
- dealSelect()
|
|
|
+const handleChangePage = (e) => {
|
|
|
+ pageInfo.pageNo = e
|
|
|
+ getData()
|
|
|
}
|
|
|
-// 单选
|
|
|
-const handleChangeSelect = () => {
|
|
|
- const length = items.value.filter(k => k.select).length
|
|
|
- selectAll.value = length > 0 ? true : false
|
|
|
- dealSelect()
|
|
|
+
|
|
|
+// 筛选
|
|
|
+const handleConfirm = (params) => {
|
|
|
+ screen.value = false
|
|
|
+ pageInfo.pageNo = 1
|
|
|
+ query = { ...params }
|
|
|
+ getData()
|
|
|
}
|
|
|
|
|
|
-const handleChangePage = () => {
|
|
|
- // 分页获取新数据后勾选
|
|
|
- selectList.value.forEach(e => {
|
|
|
- const obj = items.value.find(k => k.id === e)
|
|
|
- if (obj) obj.select = true
|
|
|
- })
|
|
|
+const FilterPageRef = ref()
|
|
|
+const openDrawer = () => {
|
|
|
+ screen.value = true
|
|
|
+ if (Object.keys(query).length) FilterPageRef.value?.setValue(query)
|
|
|
+ else FilterPageRef.value?.resetValue()
|
|
|
}
|
|
|
|
|
|
+const headers = [
|
|
|
+ { title: '姓名', key: 'name', sortable: false },
|
|
|
+ { title: '求职状态', key: 'jobStatusName', sortable: false },
|
|
|
+ // { title: '求职类型', key: 'jobName', sortable: false },
|
|
|
+ { title: '电话号码', key: 'phone', sortable: false },
|
|
|
+ { title: '常用邮箱', key: 'email', sortable: false },
|
|
|
+ // { title: '微信二维码', key: 'wxCode', sortable: false },
|
|
|
+ { title: '出生日期', key: 'birthday', sortable: false, value: item => timesTampChange(item.birthday, 'Y-M-D') },
|
|
|
+ // { title: '加入时间', key: 'createTime', sortable: false, value: item => timesTampChange(item.createTime, 'Y-M-D') },
|
|
|
+ { title: '婚姻状况', key: 'maritalStatusName', sortable: false },
|
|
|
+ { title: '所在城市', key: 'areaName', sortable: false },
|
|
|
+ { title: '户籍地', key: 'regName', sortable: false },
|
|
|
+ { title: '首次工作时间', key: 'firstWorkTime', sortable: false, value: item => timesTampChange(item.firstWorkTime, 'Y-M-D') },
|
|
|
+ // { title: '个人优势', key: 'advantage', sortable: false },
|
|
|
+ { title: '工作年限', key: 'expName', sortable: false },
|
|
|
+ { title: '最高学历', key: 'eduName', sortable: false },
|
|
|
+ { title: '操作', value: 'actions', sortable: false }
|
|
|
+]
|
|
|
+const badgeColor = computed(() => (item) => {
|
|
|
+ return (item && item.sex) ? (item.sex === '1' ? '#1867c0' : 'error') : 'error'
|
|
|
+})
|
|
|
+
|
|
|
+const badgeIcon = computed(() => (item) => {
|
|
|
+ return (item && item.sex) ? (item.sex === '1' ? 'mdi-gender-male' : 'mdi-gender-female') : 'mdi-gender-female'
|
|
|
+})
|
|
|
+
|
|
|
// 人才详情
|
|
|
const talentPoolDetails = ({ userId, id }) => {
|
|
|
if (!userId || !id) return
|