| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846 | 
							- <template>
 
-   <div class="default-width message" :style="`height: calc(100vh - ${isEnterprise ? '130px' : '50px'});`">
 
-     <div class="message-left d-flex flex-column">
 
-       <div class="message-left-search d-flex align-center px-3 justify-space-between" >
 
-         <div>
 
-           <v-icon class="mr-3">mdi-history</v-icon>
 
-           最近联系人
 
-         </div>
 
-         <div>
 
-           <v-btn
 
-             density="compact"
 
-             :color="showDelete ? '' : 'red'"
 
-             :icon="showDelete ? 'mdi-close' : 'mdi-trash-can-outline'"
 
-             variant="text"
 
-             @click="showDelete = !showDelete"
 
-           >
 
-           </v-btn>
 
-         </div>
 
-         <!-- {{ connected ? '连接成功': '连接失败' }} -->
 
-       </div>
 
-       <div class="message-chat-box mt-5">
 
-         <v-overlay
 
-           :model-value="!IM.connected"
 
-           contained
 
-           class="align-center justify-center"
 
-         >
 
-           <v-progress-circular
 
-             color="primary"
 
-             size="64"
 
-             indeterminate
 
-           ></v-progress-circular>
 
-         </v-overlay>
 
-         <div v-if="conversationList.length">
 
-           <v-list density="compact" mandatory @update:selected="handleChange">
 
-             <v-list-item
 
-               v-for="(val, i) in conversationList"
 
-               :key="i"
 
-               :value="val"
 
-               color="primary"
 
-               class="mb-2"
 
-               :active="val.channel.channelID === info?.channel?.channelID"
 
-               :title="val.userInfoVo ? (val.userInfoVo.userInfoResp?.name ? val.userInfoVo.userInfoResp.name : val.userInfoVo.userInfoResp?.phone) : '系统消息'"
 
-               :subtitle="timesTampChange(+val.timestamp.padEnd(13, '0'))"
 
-             >
 
-               <template v-slot:title="{ title }">
 
-                 <div v-if="!isEnterprise" class="mt-2 d-flex align-center">
 
-                   {{ title }}
 
-                   <div class="ml-3 color-666 font-size-14 enterprise-name ellipsis" :style="{'color': val.channel.channelID === info?.channel?.channelID ? '#00897B' : '#666'}">
 
-                     {{ val.userInfoVo?.userInfoResp?.enterpriseAnotherName }}
 
-                     <span class="line" v-if="val.userInfoVo?.userInfoResp?.postNameCn && val.userInfoVo?.userInfoResp?.enterpriseAnotherName"></span>
 
-                     {{ val.userInfoVo?.userInfoResp?.postNameCn }}
 
-                   </div>
 
-                 </div>
 
-                 <div v-else class="mt-2">{{ title }}</div>
 
-               </template>
 
-               <template v-slot:subtitle="{ subtitle }">
 
-                 <div class="mt-2">{{ subtitle }}</div>
 
-               </template>
 
-               <template v-slot:prepend>
 
-                 <v-avatar :image="getUserAvatar(val?.userInfoVo?.userInfoResp?.avatar, val?.userInfoVo?.userInfoResp?.sex)"></v-avatar>
 
-               </template>
 
-               <template v-slot:append>
 
-                 <v-badge
 
-                   v-if="val.unread > 0"
 
-                   color="error"
 
-                   :content="val.unread"
 
-                   inline
 
-                 ></v-badge>
 
-                 <v-btn v-show="showDelete" density="compact" icon="mdi-trash-can-outline" variant="text" color="red" @click.stop="handleDelete(val)"></v-btn>
 
-               </template>
 
-             </v-list-item>
 
-           </v-list>
 
-           <div class="message-no-more-text mt-3">没有更多了</div>
 
-         </div>
 
-         <div v-else class="left-noData">
 
-           <Empty :elevation="false" message="暂无30天内联系人" width="300" height="150"></Empty>
 
-         </div>
 
-       </div>
 
-     </div>
 
-     <div class="message-right">
 
-       <div v-if="showRightNoData" class="right-noData">
 
-         <Empty :elevation="false" message="与您进行过沟通的 Boss 都会在左侧列表中显示"></Empty>
 
-       </div>
 
-       <Chatting
 
-         ref="chatRef"
 
-         :items="messageItems"
 
-         :info="info"
 
-         :interview="interview"
 
-         :has-more="hasMore"
 
-         :updateConversation="updateConversation"
 
-         :updateUnreadCount="updateUnreadCount"
 
-         :resetUnread="resetUnread"
 
-         @handleSend="handleUpdate"
 
-         @handleMore="handleGetMore"
 
-         @handleAgree="handleAgree"
 
-         @handleRefuse="handleRefuse"
 
-         @handlePreview="handlePreview"
 
-         @handleSendResume="handleSendResume"
 
-         @handleBack="handleBack"
 
-       >
 
-         <template #tools>
 
-           <v-btn
 
-             v-for="tool in tools"
 
-             :key="tool.name"
 
-             size="small"
 
-             class="mr-3"
 
-             :disabled="tool.disabled"
 
-             :color="tool.color"
 
-             @click="tool.handle(tool)"
 
-           >
 
-             <v-progress-circular
 
-               v-if="tool.loading"
 
-               :width="2"
 
-               :size="16"
 
-               color="white"
 
-               class="mr-2"
 
-               indeterminate
 
-             ></v-progress-circular>
 
-             <v-icon v-else class="mr-2">{{ tool.icon }}</v-icon>
 
-             {{ tool.disabled ? tool.disabledText : tool.name }}
 
-           </v-btn>
 
-         </template>
 
-       </Chatting>
 
-     </div>
 
-   </div>
 
-   <!-- 附件上传 -->
 
-   <CtDialog
 
-     :visible="showUploadDialog"
 
-     :widthType="2"
 
-     :footer="true"
 
-     title="附件简历上传"
 
-     titleClass="text-h6"
 
-     @close="showUploadDialog = false"
 
-     @submit="handleSubmitAttachment"
 
-   >
 
-     <CtForm ref="CtFormRef" :items="formItems">
 
-       <template #uploadFile="{ item }">
 
-         <TextInput v-model="item.value" :item="item" @click="openFileInput"></TextInput>
 
-         <File ref="uploadFile" @success="handleUploadResume"></File>
 
-       </template>
 
-     </CtForm>
 
-     <div class="color-666" style="font-size: 13px;">* 仅支持.doc, .docx, .pdf文件</div>
 
-   </CtDialog>
 
-   <!-- 面试邀请 -->
 
-   <CtDialog :visible="showInvite" :widthType="4" titleClass="text-h6" title="邀请面试" @close="showInvite = false" @submit="handleSubmit">
 
-     <InvitePage v-if="showInvite" ref="inviteRef" :item-data="itemData" :position="positionList"></InvitePage>
 
-   </CtDialog>
 
-   <TipDialog :visible="showTip" icon="mdi-check-circle-outline" message="面试邀请发送成功" @close="showTip = false">
 
-     <div class="color-primary text-decoration-underline cursor-pointer" @click="handleToInterviewManagement">点击到面试中查看。</div>
 
-   </TipDialog>
 
-   <!-- 求简历-选择求简历的职位 -->
 
-   <CtDialog :visible="showSelectPosition" :widthType="2" titleClass="text-h6" title="选择要求简历的职位" @close="showSelectPosition = false" @submit="handleRequestResumeSubmit">
 
-     <CtForm v-if="showSelectPosition" ref="requestFromRef" :items="requestFormItems"></CtForm>
 
-   </CtDialog>
 
-   <!-- 选择附件简历投递 -->
 
-   <CtDialog :visible="showResume" :widthType="2" titleClass="text-h6" title="发送简历" @close="showResume = false; selectResume = null; enRequestPositionInfo = {}" @submit="handleSubmitResume">
 
-     <div style="position: relative; min-height: 200px">
 
-       <v-radio-group v-model="selectResume">
 
-         <div v-for="val in resumeList" :key="val.id" class="d-flex align-center radioBox">
 
-           <v-radio :label="val.title" :value="val.id"  color="primary"></v-radio>
 
-           <span class="defaultLink mx-3" style="font-size: 14px;" @click.stop="previewFile(val.url)">预览</span>
 
-         </div>
 
-       </v-radio-group>
 
-     </div>
 
-   </CtDialog>
 
- </template>
 
- <script setup>
 
- defineOptions({ name: 'personal-message-index'})
 
- import InvitePage from '@/views/recruit/enterprise/interviewManagement/components/invite'
 
- import { ref, inject, watch, nextTick, computed } from 'vue'
 
- import { useRoute } from 'vue-router'
 
- import Chatting from './components/chatting.vue'
 
- import { initConnect, send, initChart, getMoreMessages, checkConversation } from '@/hooks/web/useIM'
 
- import { useI18n } from '@/hooks/web/useI18n'
 
- import { getPositionDetails, jobCvRelCheckSend, jobCvRelSend, jobCvRelHireSend } from '@/api/position'
 
- import { getInterviewInviteListByInviteUserId, getMessageType } from '@/api/common'
 
- // import { getUserInfo } from '@/api/personal/user'
 
- import { getBaseInfo } from '@/api/common'
 
- import { getJobAdvertised } from '@/api/enterprise'
 
- import { saveInterviewInvite } from '@/api/recruit/enterprise/interview'
 
- import { savePersonResumeCv } from '@/api/recruit/personal/resume'
 
- import { userInterviewInviteReject, userInterviewInviteConsent } from '@/api/recruit/personal/personalCenter'
 
- import { getPersonResumeCv } from '@/api/recruit/personal/resume'
 
- import { useIMStore } from '@/store/im'
 
- import { useUserStore } from '@/store/user'
 
- import Snackbar from '@/plugins/snackbar'
 
- import Confirm from '@/plugins/confirm'
 
- import { getUserAvatar } from '@/utils/avatar'
 
- import { dealDictArrayData } from '@/utils/position'
 
- import { previewFile } from '@/utils'
 
- import { timesTampChange } from '@/utils/date'
 
- import { useRouter } from 'vue-router'
 
- const { t } = useI18n()
 
- const chatRef = ref()
 
- const IM = useIMStore()
 
- // 自己的信息
 
- const { entBaseInfo } = useUserStore()
 
- const isEnterprise = inject('isEnterprise')
 
- // 实例
 
- const route = useRoute()
 
- const channelItem = ref(null)
 
- const messageItems = ref([])
 
- const pageSize = ref(1)
 
- const hasMore = ref(false)
 
- const positionList = ref([])
 
- const showTip = ref(false)
 
- const showInvite = ref(false)
 
- // 企业-求简历
 
- const showSelectPosition = ref(false)
 
- const requestFromRef = ref()
 
- const requestFormItems = ref({
 
-   options: [
 
-     {
 
-       type: 'autocomplete',
 
-       key: 'jobId',
 
-       value: null,
 
-       label: '招聘职位 *',
 
-       outlined: true,
 
-       clearable: false,
 
-       itemText: 'label',
 
-       itemValue: 'value',
 
-       rules: [v => !!v || '请选择招聘职位'],
 
-       items: positionList
 
-     }
 
-   ]
 
- })
 
- const showDelete = ref(false)
 
- const itemData = ref({})
 
- const inviteRef = ref()
 
- // 发送简历
 
- const showResume = ref(false)
 
- const resumeList = ref([])
 
- const selectResume = ref(null)
 
- // 众聘 介绍人个人id
 
- const isEmployment = ref('-1')
 
- // 上传附件简历
 
- const CtFormRef = ref()
 
- const formItems = ref({
 
-   options: [
 
-     {
 
-       type: 'text',
 
-       key: 'title',
 
-       value: '',
 
-       label: '附件简历名称 *',
 
-       rules: [v => !!v || '请输入附件简历名称']
 
-     },
 
-     {
 
-       slotName: 'uploadFile',
 
-       key: 'url',
 
-       value: '',
 
-       truthValue: '',
 
-       label: '点击上传附件简历 *',
 
-       outline: true,
 
-       rules: [v => !!v || '请上传您的附件简历']
 
-     }
 
-   ]
 
- })
 
- // 求职者面试列表
 
- const interview = ref([])
 
- const showRightNoData = ref(false)
 
- const info = ref({})
 
- const enterpriseTools = ref([
 
-   { name: '求简历', key: 'requestResume', icon: 'mdi-email', color:"primary", loading: false, handle: handleInvite, disabled: false, disabledText: '简历已接收' },
 
-   { name: '面试邀约', key: 'interviewInvite', icon: 'mdi-email', color:"primary", loading: false, handle: handleInvite, disabled: false, disabledText: '面试邀约' }
 
- ])
 
- const userTools = ref([
 
-   {
 
-     name: '发送简历',
 
-     key: 'sendResume',
 
-     icon: 'mdi-email',
 
-     color:"primary",
 
-     loading: false,
 
-     handle: handleSendResume,
 
-     disabled: false,
 
-     disabledText: '简历已投递'
 
-   }
 
- ])
 
- // const tools = isEnterprise ? enterpriseTools.value : userTools.value
 
- const tools = computed(() => {
 
-   return isEnterprise ? enterpriseTools.value : userTools.value
 
- })
 
- const positionInfo = ref({})
 
- // const isSendResume = ref(false)
 
- if (!IM) {
 
-   console.log('IM is disconnected')
 
- }
 
- // 职位进入
 
- if (route.query.id) {
 
-   const api = route.query.enterprise ? getPositionDetails : getBaseInfo // getBaseInfo  getUserInfo
 
-   // const res = await api({ id: route.query.id })
 
-   const res = await api(route.query.enterprise ? { id: route.query.id } : { userId: route.query.id })
 
-   if (!res) {
 
-     Snackbar.error('个人资料为空')
 
-   } else {
 
-     const query = route.query.enterprise ? [res.contact?.userId, res.contact?.enterpriseId] : [res?.userId]
 
-     nextTick(async () => {
 
-       const { channel } = await checkConversation(...query)
 
-       const items = [
 
-         {
 
-           channel,
 
-           userInfoVo: {
 
-             userInfoResp: route.query.enterprise ? res.contact : { ...res, userId: res?.userId}
 
-           }
 
-         }
 
-       ]
 
-       handleChange(items)
 
-     })
 
-   }
 
-   
 
- }
 
- const {
 
-   conversationList,
 
-   updateConversation,
 
-   updateUnreadCount,
 
-   deleteConversations,
 
-   resetUnread
 
- } = initConnect(async (successful) => {
 
-   if (!successful) {
 
-     Snackbar.error('发送失败')
 
-     return
 
-   }
 
-   chatRef.value.reset()
 
-   // 发送成功
 
-   const { list } = await getMoreMessages(1, channelItem.value)
 
-   // updateConversation()
 
-   messageItems.value = list.value
 
-   chatRef.value.scrollBottom()
 
- })
 
- const getInterviewInviteList = async () => {
 
-   if (!info.value.userId) return
 
-   const data = await getInterviewInviteListByInviteUserId(info.value.userId)
 
-   interview.value = data.slice(0, 1)
 
- }
 
- // 在当前频道中有新消息时更新未读消息数量
 
- const updateUnreadMessageCount = (val) => {
 
-   const obj = val.find(e => e.userInfoVo.userId === info.value.userId)
 
-   if (!obj?.unread || obj.unread === 0) return
 
-   delete info.value.unread
 
-   Object.assign(info.value, { unread: obj.unread, enterpriseId: entBaseInfo?.enterpriseId })
 
- }
 
- watch(
 
-   () => conversationList.value,
 
-   async (val) => {
 
-     // 数据发生变化
 
-     if (channelItem.value && IM.fromChannel === channelItem.value.channelID) {
 
-       // 更新
 
-       const { list } = await getMoreMessages(1, channelItem.value)
 
-       messageItems.value = list.value
 
-       if (Object.keys(info.value).length) updateUnreadMessageCount(val)
 
-       chatRef.value.scrollBottom()
 
-     }
 
-   },
 
-   {
 
-     deep: true,
 
-     immediate: true
 
-   }
 
- )
 
- // 获取职位信息
 
- async function getMessageTypeSync () {
 
-   const data = await getMessageType({
 
-     fromUid: IM.uid,
 
-     channelId: channelItem.value?.channelID,
 
-     type: 102,
 
-     page: {
 
-       current: 1,
 
-       size: 1,
 
-       orders: [
 
-         { column: 'message_seq', asc: false }
 
-       ]
 
-     }
 
-   })
 
-   if (!data.records || !data.records.length) { 
 
-     return
 
-   }
 
-   const _item = data.records.pop()
 
-   const _itemJSON = JSON.parse(_item.payload)
 
-   const _content = JSON.parse(_itemJSON.content)
 
-   positionInfo.value = _content.positionInfo
 
-   const check = await jobCvRelCheckSend({ jobId: _content.positionInfo.id })
 
-   handleChangeSendResumeStatus(check)
 
- }
 
- // 修改发送状态
 
- function handleChangeSendResumeStatus (status) {
 
-   if (!isEnterprise) {
 
-     const item = userTools.value.find(e => e.key === 'sendResume')
 
-     item.disabled = status
 
-   }
 
- }
 
- async function handleChange (items) {
 
-   try {
 
-     chatRef.value.changeOverlay(true)
 
-     const { userInfoVo, channel: myChannel, unread } = items.pop()
 
-     info.value = userInfoVo?.userInfoResp ?? { name: '系统消息' }
 
-     Object.assign(info.value, {
 
-       channel: myChannel,
 
-       unread
 
-     })
 
-     // 个人端获取面试信息
 
-     if (!isEnterprise) getInterviewInviteList()
 
-     const userId = userInfoVo.userInfoResp.userId
 
-     const enterpriseId = userInfoVo.userInfoResp.enterpriseId || undefined
 
-     const { channel, list, more } = await initChart(userId, enterpriseId)
 
-     // console.log('--------',list)
 
-     channelItem.value = channel.value
 
-     // 获取最近职位记录
 
-     getMessageTypeSync()
 
-     messageItems.value = list.value
 
-     hasMore.value = more
 
-     chatRef.value.scrollBottom()
 
-     // 点开窗口消除未读数量
 
-     await resetUnread(channel.value, entBaseInfo?.enterpriseId)
 
-     await updateConversation()
 
-     updateUnreadCount()
 
-   } catch (error) {
 
-     messageItems.value = []
 
-   } finally {
 
-     chatRef.value.changeOverlay(false)
 
-   }
 
- }
 
- // 普通消息
 
- const handleUpdate = (val) => {
 
-   send(val.value, channelItem.value)
 
- }
 
- // 选择文件
 
- const uploadFile = ref()
 
- const openFileInput = () => {
 
-   uploadFile.value.trigger()
 
- }
 
- // 上传附件
 
- const handleUploadResume = async (url, title, filename) => {
 
-   const obj = formItems.value.options.find(e => e.key === 'url')
 
-   obj.value = filename
 
-   obj.truthValue = url
 
- }
 
- // 获取简历
 
- const showUploadDialog = ref(false)
 
- const enRequestPositionInfo = ref({}) // 企业求简历时选中的职位信息
 
- async function handleSendResume (item) {
 
-   try {
 
-     item.loading = true
 
-     // 获取简历列表
 
-     const result = await getPersonResumeCv()
 
-     if (result.length === 0) {
 
-       Snackbar.warning(t('resume.resumeYetSubmit'))
 
-       showUploadDialog.value = true
 
-       return
 
-     }
 
-     resumeList.value = result
 
-     if (item?.content?.query?.positionInfo?.data && Object.keys(item?.content?.query?.positionInfo?.data).length) enRequestPositionInfo.value = item?.content?.query?.positionInfo?.data
 
-     showResume.value = true
 
-   } finally {
 
-     item.loading = false
 
-   }
 
- }
 
- // 撤回简历
 
- async function handleBack (val) {
 
-   console.log(val)
 
-   try {
 
-     // 撤回简历
 
-     // 撤回聊天
 
-     // await messageBack({
 
-     //   channelId: val.channel_id,
 
-     //   messageId: val.message_id,
 
-     //   nickName: baseInfo.name
 
-     //   // enterpriseId: ''
 
-     // })
 
-   } catch (error) {
 
-     console.log(error)
 
-   }
 
- }
 
- /**
 
-  * 发送简历
 
-  * text param
 
-  * {
 
-  *  remark: 备注
 
-  *  query: {} 自定义参数 access -1 未确定 0 拒绝 1 同意
 
-  *  type: 1 => 发送简历
 
-  *        2 => 索要简历
 
-  *        3 => 信息描述
 
-  * }
 
-  */
 
- // 没有上传过简历的弹窗上传并发送给对方
 
- const handleSubmitAttachment = async () => {
 
-   const { valid } = await CtFormRef.value.formRef.validate()
 
-   if (!valid) return
 
-   const obj = {}
 
-   formItems.value.options.forEach(e => {
 
-     obj[e.key] = e.truthValue || e.value
 
-   })
 
-   if (!obj.title || !obj.url) return
 
-   await savePersonResumeCv(obj)
 
-   const text = {
 
-     remark: '发送简历',
 
-     query: {
 
-       src: obj.url,
 
-       title: obj.title
 
-     },
 
-     type: 1
 
-   }
 
-   if (enRequestPositionInfo.value) text.query.positionInfo = enRequestPositionInfo.value
 
-   send (JSON.stringify(text), channelItem.value, 105)
 
-   // 简历投递至简历库
 
-   if (isEmployment.value !== '-1') {
 
-     await jobCvRelHireSend({
 
-       jobId: positionInfo.value.id,
 
-       url: obj.url,
 
-       recommendUserId: isEmployment.value
 
-     })
 
-   } else {
 
-     const jobId = enRequestPositionInfo.value && enRequestPositionInfo.value?.id ? enRequestPositionInfo.value?.id : positionInfo.value.id
 
-     const type = (enRequestPositionInfo.value && Object.keys(enRequestPositionInfo.value).length ? enRequestPositionInfo.value.hire : positionInfo.value.hire) ? 1 : 0
 
-     await jobCvRelSend({
 
-       jobId,
 
-       title: obj.title,
 
-       url: obj.url,
 
-       type
 
-     })
 
-   }
 
-   handleChangeSendResumeStatus(true)
 
-   showUploadDialog.value = false
 
-   enRequestPositionInfo.value = {}
 
- }
 
- async function handleSubmitResume () {
 
-   if (!selectResume.value) {
 
-     Snackbar.error(t('resume.selectResumeToSubmit'))
 
-     return
 
-   }
 
-   const _info = resumeList.value.find((item) => item.id === selectResume.value)
 
-   const text = {
 
-     remark: '发送简历',
 
-     query: {
 
-       src: _info.url,
 
-       title: _info.title,
 
-       id: _info.id,
 
-     },
 
-     type: 1
 
-   }
 
-   if (enRequestPositionInfo.value) text.query.positionInfo = enRequestPositionInfo.value
 
-   send (JSON.stringify(text), channelItem.value, 105)
 
-   // 简历投递至简历库
 
-   if (isEmployment.value !== '-1') {
 
-     await jobCvRelHireSend({
 
-       jobId: positionInfo.value.id,
 
-       url: _info.url,
 
-       recommendUserId: isEmployment.value
 
-     })
 
-   } else {
 
-     const jobId = enRequestPositionInfo.value && enRequestPositionInfo.value?.id ? enRequestPositionInfo.value?.id : positionInfo.value.id
 
-     const type = (enRequestPositionInfo.value && Object.keys(enRequestPositionInfo.value).length ? enRequestPositionInfo.value.hire : positionInfo.value.hire) ? 1 : 0
 
-     await jobCvRelSend({
 
-       jobId,
 
-       title: _info.title,
 
-       url: _info.url,
 
-       type
 
-     })
 
-   }
 
-   handleChangeSendResumeStatus(true)
 
-   showResume.value = false
 
-   enRequestPositionInfo.value = {}
 
- }
 
- // 简历预览
 
- const handlePreview = (val) => {
 
-   previewFile(val.content.query.src)
 
- }
 
- const handleGetMore = async () => {
 
-   // 当前滚动条高度
 
-   const scrollHeight = chatRef.value.chatRef.scrollHeight
 
-   // 当前滚动条距离
 
-   const scrollTop = chatRef.value.chatRef.scrollTop
 
-   try {
 
-     chatRef.value.changeLoading(true)
 
-     pageSize.value++
 
-     const { list, more } = await getMoreMessages(pageSize.value, channelItem.value)
 
-     messageItems.value.unshift(...list.value)
 
-     hasMore.value = more
 
-     nextTick(() => {
 
-       // 渲染后高度
 
-       const _scrollHeight = chatRef.value.chatRef.scrollHeight
 
-       chatRef.value.chatRef.scrollTop = _scrollHeight - scrollHeight - scrollTop
 
-     })
 
-   } finally {
 
-     chatRef.value.changeLoading(false)
 
-   }
 
- }
 
- const handleDelete = async ({ channel }) => {
 
-   await deleteConversations(channel, entBaseInfo?.enterpriseId)
 
-   await updateConversation()
 
-   updateUnreadCount()
 
- }
 
- // 没有企业ID则enterpriseId为undefined
 
- // 发送消息体 { text, type: 2 }
 
- // 面试邀约
 
- const getPositionList = async () => {
 
-   const data = await getJobAdvertised({})
 
-   if (!data.length) return
 
-   const list = dealDictArrayData([], data)
 
-   positionList.value = list.map(e => {
 
-     const salary = e.payFrom && e.payTo ? `${e.payFrom ? e.payFrom + '-' : ''}${e.payTo}${e.payName ? '/' + e.payName : ''}` : '面议'
 
-     return {
 
-       label: `${e.name}${e.areaName ? '_' + e.areaName : ''} ${salary}`,
 
-       value: e.id,
 
-       data: e
 
-     }
 
-   })
 
- }
 
- async function handleInvite (item) {
 
-   item.loading = true
 
-   positionList.value = []
 
-   try {
 
-     await getPositionList()
 
-     if (!positionList.value.length) return Snackbar.warning('请先发布职位')
 
-     if (item.key === 'requestResume') return showSelectPosition.value = true
 
-     showInvite.value = true
 
-   } catch (error) {
 
-     console.log(error)
 
-   } finally {
 
-     item.loading = false
 
-   }
 
- }
 
- // 企业-发送面试邀请
 
- const handleSubmit = async () => {
 
-   const { valid } = await inviteRef.value.CtFormRef.formRef.validate()
 
-   if (!valid) {
 
-     return
 
-   }
 
-   const query = inviteRef.value.getQuery()
 
-   if (!query.time) {
 
-     Snackbar.warning('时间不能为空')
 
-     return
 
-   }
 
-   query.userId = info.value.userId
 
-   query.positionInfo = positionList.value.find(e => e.value === query.jobId)
 
-   // 需要id
 
-   const data = await saveInterviewInvite(query)
 
-   // 保留邀请id
 
-   query.id = data.id
 
-   showTip.value = true
 
-   send(JSON.stringify(query), channelItem.value, 101)
 
-   showInvite.value = false
 
- }
 
- const router = useRouter()
 
- const handleToInterviewManagement = () => {
 
-   router.push('/recruit/enterprise/interviewManagement')
 
- }
 
- // 企业-求简历
 
- const handleRequestResumeSubmit = async () => {
 
-   const { valid } = await requestFromRef.value.formRef.validate()
 
-   if (!valid) return
 
-   const jobId = requestFormItems.value.options.find(e => e.key === 'jobId').value
 
-   const positionInfo = positionList.value.find(e => e.value === jobId)
 
-   const text = {
 
-     remark: '求简历',
 
-     query: {
 
-       src: '',
 
-       title: '',
 
-       id: '',
 
-       positionInfo
 
-     },
 
-     type: 2
 
-   }
 
-   send (JSON.stringify(text), channelItem.value, 105)
 
-   showSelectPosition.value = false
 
- }
 
- const handleAgree = (val) => {
 
-   if (!val.id) return
 
-   const query = {
 
-     id: val.id
 
-   }
 
-   const type = route?.meta?.loginType === 'enterprise' ? 'entBaseInfo' : 'baseInfo'
 
-   const baseInfo = localStorage.getItem(type)
 
-   if (baseInfo) {
 
-     const { phone } = JSON.parse(baseInfo)
 
-     query.phone = phone
 
-   }
 
-   Confirm(t('common.confirmTitle'), '是否确定接收此面试邀请?').then(async () => {
 
-     await userInterviewInviteConsent(query)
 
-     Snackbar.success(t('common.operationSuccessful'))
 
-     getInterviewInviteList()
 
-     send(JSON.stringify({ id: val.id }), channelItem.value, 104)
 
-   })
 
- }
 
- // 拒绝面试邀请
 
- const handleRefuse = (val) => {
 
-   if (!val.id) return
 
-   Confirm(t('common.confirmTitle'), '您是否确定要拒绝此面试邀请?').then(async () => {
 
-     await userInterviewInviteReject(val.id)
 
-     Snackbar.success(t('common.operationSuccessful'))
 
-     getInterviewInviteList()
 
-     send(JSON.stringify({ id: val.id }), channelItem.value, 103)
 
-   })
 
- }
 
- </script>
 
- <style scoped lang="scss">
 
- .message {
 
-   display: flex;
 
-   &-left {
 
-     position: relative;
 
-     flex-shrink: 0;
 
-     height: 100%;;
 
-     width: 360px;
 
-     background-color: #fff;
 
-     border-radius: 8px;
 
-     margin-right: 12px;
 
-     .message-left-search {
 
-       width: 100%;
 
-       height: 60px;
 
-       background: linear-gradient(90deg, #f5fcfc, #fcfbfa);
 
-       border-radius: 8px 8px 0 0;
 
-     }
 
-     .message-chat-box {
 
-       height: 0;
 
-       flex: 1;
 
-       overflow: auto;
 
-       padding-bottom: 20px;
 
-       .chat-item {
 
-         position: relative;
 
-         width: 100%;
 
-         height: 78px;
 
-         padding: 14px 12px;
 
-         cursor: pointer;
 
-         &:hover {
 
-           background-color: #f8f8f8;
 
-         }
 
-         .chat-item-time {
 
-           position: absolute;
 
-           right: 12px;
 
-           top: 50%;
 
-           transform: translateY(-50%);
 
-         }
 
-         .title-box {
 
-           max-width: 114px;
 
-           overflow: hidden;
 
-           white-space: nowrap;
 
-           text-overflow: ellipsis;
 
-           display: inline-block;
 
-         }
 
-       }
 
-     }
 
-     .message-no-more-text {
 
-       color: var(--color-999);
 
-       font-size: 14px;
 
-       text-align: center
 
-     }
 
-     .left-noData {
 
-       position: absolute;
 
-       top: 50%;
 
-       left: 50%;
 
-       transform: translate(-50%, -50%);
 
-     }
 
-   }
 
-   &-right {
 
-     height: 100%;
 
-     flex: 1;
 
-     width: 0;
 
-     position: relative;
 
-     background-color: #fff;
 
-     border-radius: 8px;
 
-     .right-noData {
 
-       position: absolute;
 
-       top: 50%;
 
-       left: 50%;
 
-       transform: translate(-50%, -50%);
 
-     }
 
-   }
 
- }
 
- .enterprise-name {
 
-   max-width: 150px;
 
-   .line {
 
-     display: inline-block;
 
-     width: 1px;
 
-     height: 12px;
 
-     vertical-align: middle;
 
-     background-color: #e0e0e0;
 
-     margin: 0 3px;
 
-   }
 
- }
 
- .radioBox {
 
-   &:hover {
 
-     border-radius: 2px;
 
-     background-color: var(--color-f8);
 
-   }
 
- }
 
- </style>
 
 
  |