123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- <template>
- <view>
- <view v-for="(val, index) in items" :key="index" @tap.stop="handleDetail(val)" class="mList default-border">
- <!-- 基本信息 -->
- <view class="d-flex align-center">
- <view class="user-avatar">
- <image class="user-avatar-img" :src="getUserAvatar(val.person?.avatar, val.person?.sex)" mode="scaleToFill"></image>
- <image class="user-avatar-sex" :src="val?.person?.sex ? val?.person?.sex === '1' ? '/static/img/man.png' : '/static/img/female.png' : ''" alt="" mode="scaleToFill" />
- </view>
- <view style="flex: 1; margin-left: 10px;">
- <view class="d-flex justify-space-between align-center">
- <view class="font-size-18 default-text-color">{{ val.person?.name }}</view>
- <view v-if="current !== 4">
- <span v-if="current === 0" :style="{'color': val.status && val.status === '0' ? '#fb8c00' : '#00B760'}">
- {{ val.status && val.status === '0' ? '未查看' : '已查看' }}
- </span>
- <span v-else class="color-999">{{ val.status ? statusList.find(i => i.value === val.status)?.label : '' }}</span>
- </view>
- </view>
- <view class="ss-m-t-10">
- <span
- class="color-999"
- v-for="(key, index) in desc"
- :key="index"
- >
- {{ val.person?.[key] }}
- <span v-if="index !== desc.length - 1 && val.person?.[key]" class="ss-m-x-10">|</span>
- </span>
- </view>
- </view>
- </view>
- <view class="ss-m-t-15 color-999">
- <view>
- 投递职位:
- <image v-if="val.jobFairId" src="/static/svg/jobFair.svg" style="width: 15px; height: 15px;"></image>
- {{ formatName(val.job?.name) }}
- </view>
- <view>操作时间:{{ timesTampChange(val.createTime) }}</view>
- </view>
- <view class="sub-li-bottom ss-m-t-20">
- <view class="sub-li-bottom-item color-primary" @tap.stop="handlePreview(val)">查看/下载附件</view>
- <view
- class="sub-li-bottom-item d-flex align-center justify-center"
- @tap.stop="handleLoadMore(val)"
- :style="{'color': !actionItems(val)?.length ? '#ccc' : '#00B760'}"
- >
- <view>更多操作</view>
- <uni-icons type="list" class="ss-m-l-10" size="20" :color="!actionItems(val)?.length ? '#ccc' : '#00B760'"></uni-icons>
- </view>
- </view>
- </view>
- <!-- 更多操作 -->
- <uni-popup ref="popup" type="bottom" :mask-click="true">
- <view class="actions" v-if="itemData && Object.keys(itemData).length">
- <view
- class="action-item"
- v-for="(val, index) in actionItems(itemData)"
- :key="index"
- @tap.stop="val.click(itemData)"
- >{{ val.title }}</view>
- </view>
- <button class="big-cancel-button" @tap.stop="handleClosePopup">取消</button>
- </uni-popup>
- </view>
- </template>
- <script setup>
- import { ref } from 'vue'
- import { timesTampChange } from '@/utils/date'
- import { getUserAvatar } from '@/utils/avatar'
- import { formatName } from '@/utils/getText'
- import { preview } from '@/utils/preview'
- import { getDict } from '@/hooks/useDictionaries'
- import { userStore } from '@/store/user'
- import { defaultText, talkToUser } from '@/hooks/useIM'
- import { joinToTalentPool, joinEliminate, personCvUnfitCancel, personEntryByEnterprise, hireJobCvRelSettlement, personJobCvLook } from '@/api/resume'
- const emit = defineEmits(['refresh'])
- const props = defineProps({ items: Array, current: [Number, String] })
- const user = userStore()
- const statusList = ref([])
- getDict('menduner_interview_invite_status').then(({ data }) => {
- statusList.value = data.data || []
- })
- const desc = ['jobStatusName', 'eduName', 'expName']
- const popup = ref()
- const itemData = ref({})
- // 查看在线简历
- const handleDetail = async (val) => {
- if (!val.userId || !val.id) {
- uni.showToast({ title: '用户ID不存在', icon: 'none' })
- return
- }
- try {
- const {data } = await personJobCvLook(val.id)
- if (data) emit('refresh')
- } catch {}
- uni.navigateTo({
- url: `/pagesB/personnelDetails/index?id=${val.userId}&type=1`
- })
- }
- // 查看附件
- const handlePreview = async (val) => {
- if (!val.userId || !val.id) {
- uni.showToast({ title: '用户ID不存在', icon: 'none' })
- return
- }
- try {
- const {data } = await personJobCvLook(val.id)
- if (data) emit('refresh')
- } catch {}
- if (!val.url) {
- uni.showToast({ title: '附件地址不存在', icon: 'none' })
- return
- }
- preview(val.url)
- }
- // 更多操作
- const handleLoadMore = (val) => {
- if (!actionItems(val).length) {
- itemData.value = {}
- uni.showToast({ title: '暂无更多操作', icon: 'none' })
- return
- }
- itemData.value = val
- popup.value.open()
- }
- // 关闭操作弹窗
- const handleClosePopup = () => {
- popup.value.close()
- itemData.value = {}
- }
- // 加入储备
- const handleJoinToTalentPool = async (item) => {
- if (!item.userId) {
- uni.showToast({ title: '用户ID不存在', icon: 'none' })
- return
- }
- try {
- await joinToTalentPool(item.userId)
- uni.showToast({ title: '加入成功', icon: 'none' })
- handleClosePopup()
- emit('refresh')
- } catch {
- handleClosePopup()
- }
- }
- // 邀请面试
- const handleInterviewInvite = (item) => {
- if (item?.job?.status === '1') {
- uni.showToast({ title: '职位已关闭', icon: 'none' })
- return
- }
- uni.navigateTo({
- url: `/pagesB/InviteInterview/index?id=${item.userId}&jobId=${item.job.id}`
- })
- handleClosePopup()
- }
- // 不合适
- const handleEliminate = async (item) => {
- if (!item.userId) {
- uni.showToast({ title: '用户ID不存在', icon: 'none' })
- return
- }
- const query = {
- bizId: item.id,
- jobId: item.job.id,
- userId: item.userId,
- type: props.current === 0 ? '0' : '1' // 投递简历0 已邀约1
- }
- // 招聘会职位则带id
- if (item?.jobFairId) query.jobFairId = item.jobFairId
- try {
- await joinEliminate(query)
- uni.showToast({ title: '操作成功', icon: 'none' })
- handleClosePopup()
- emit('refresh')
- } catch {
- handleClosePopup()
- }
- }
- // 取消不合适
- const handleCancelEliminate = async (item) => {
- if (!item.id) {
- uni.showToast({ title: 'ID不存在', icon: 'none' })
- return
- }
- try {
- await personCvUnfitCancel(item.id)
- uni.showToast({ title: '操作成功', icon: 'none' })
- handleClosePopup()
- emit('refresh')
- } catch {
- handleClosePopup()
- }
- }
- // 立即沟通
- const handleToCommunicate = async (item) => {
- if (item?.job?.status === '1') {
- uni.showToast({ title: '职位已关闭', icon: 'none' })
- return
- }
- const userId = item.userId
- if (!userId) return
- const channel = await talkToUser({ userId, text: defaultText })
- const query = {
- id: userId,
- name: item?.person?.name || item?.person?.phone,
- channelID: channel.channelID,
- channelType: channel.channelType,
- avatar: item?.person?.avatar,
- sex: item?.person?.sex,
- }
- const queryStr = Object.keys(query).reduce((r, v) => {
- if (!query[v]) {
- return r
- }
- return r += `${v}=${encodeURIComponent(query[v])}&`
- }, '?')
- uni.navigateTo({
- url: `/pagesA/chart/index${queryStr.slice(0, -1)}`
- })
- handleClosePopup()
- }
- // 结算
- const handleSettlement = async (item) => {
- if (!item.id) {
- uni.showToast({ title: 'ID不存在', icon: 'none' })
- return
- }
- try {
- await hireJobCvRelSettlement(item.id)
- uni.showToast({ title: '操作成功', icon: 'none' })
- handleClosePopup()
- emit('refresh')
- // 更新账户信息
- setTimeout(async () => {
- await user.getAccountInfo()
- }, 2000)
- } catch {
- handleClosePopup()
- }
- }
- // 入职
- const handleEnterByEnterprise = async (item) => {
- console.log(item, '====入职====')
- if (!item.id) {
- uni.showToast({ title: 'ID不存在', icon: 'none' })
- return
- }
- try {
- await personEntryByEnterprise(item.id)
- uni.showToast({ title: '操作成功', icon: 'none' })
- handleClosePopup()
- emit('refresh')
- } catch {
- handleClosePopup()
- }
- }
- const actionItems = (item) => {
- const arr = []
- if (props.current === 0) arr.push({ title: '邀请面试', click: handleInterviewInvite }, { title: '立即沟通', click: handleToCommunicate })
- if ([0, 1].includes(props.current)) arr.push({ title: '不合适', click: handleEliminate })
- if (props.current === 4) arr.push({ title: '取消不合适', click: handleCancelEliminate })
- if (props.current === 2 && item?.job?.hire) arr.push({ title: '结算', click: handleSettlement })
- if (props.current === 1 && ['3', '4'].includes(item.status)) arr.push({ title: '入职', click: handleEnterByEnterprise })
- // 面试后才能够加入储备
- if ([1, 2, 3].includes(props.current) && !item.inTalentPool) arr.push({ title: '加入储备', click: handleJoinToTalentPool })
- return arr
- }
- </script>
- <style scoped lang="scss">
- .mList {
- border-radius: 12px;
- box-shadow: 1px 2px 12px rgba(0, 0, 0, 0.17);
- margin: 0 30rpx 20rpx 30rpx;
- padding: 30rpx;
- background-color: #fbfbfb;
- font-size: 28rpx;
- &:first-child {
- margin-top: 20rpx;
- }
- }
- .user-avatar {
- position: relative;
- &-img {
- width: 45px;
- height: 45px;
- border-radius: 50%;
- }
- &-sex {
- position: absolute;
- right: 0;
- bottom: 2px;
- width: 20px;
- height: 20px;
- background-color: #fff;
- border-radius: 50%;
- }
- }
- .action {
- font-size: 28rpx;
- &-item {
- text-align: center;
- width: 90vw;
- border-bottom: 1px solid #eee;
- height:44px;
- line-height: 44px;
- margin: 0 auto;
- color: #00B760;
- background-color: #fff !important;
- &:first-child {
- border-radius: 5px 5px 0 0;
- }
- &:last-child {
- border-radius: 0 0 5px 5px;
- border-bottom: none;
- }
- }
- }
- .big-cancel-button {
- width: 90vw;
- height:44px;
- line-height: 44px;
- margin: 10px auto;
- color: #fe574a;
- background-color: #fff !important;
- font-size: 28rpx;
- }
- .sub-li-bottom {
- display: flex;
- justify-content: space-between;
- // align-items: flex-end;
- margin-top: 10px;
- font-size: 13px;
- &-item {
- width: 50%;
- height: 35px;
- line-height: 35px;
- text-align: center;
- margin-right: 15px;
- background-color: #f7f8fa;
- border-radius: 4px;
- &:nth-child(2) {
- margin-right: 0;
- }
- }
- }
- </style>
|