Files
ks-app-employment-service/pages/msglog/messageDetail.vue
2026-05-20 20:50:51 +08:00

344 lines
11 KiB
Vue

<template>
<AppLayout>
<view class="detail-content">
<scroll-view scroll-y class="detail-scroll">
<view class="scroll-body" v-if="message">
<view class="msg-card" :class="{ unread: message.isRead === '0' }">
<view class="card-row">
<view class="card-icon">
<image class="card-icon-img" v-if="message.title === '招聘会预约提醒'" src="/static/icon/msgtype.png"></image>
<image class="card-icon-img" v-else-if="message.title === '职位上新'" src="/static/icon/msgtype2.png"></image>
<image class="card-icon-img" v-else-if="message.title === '系统通知'" src="/static/icon/msgtype3.png"></image>
<image class="card-icon-img card-icon-default" v-else src="/static/icon/bell.png"></image>
</view>
<view class="card-info">
<view class="info-title-row">
<view class="unread-dot" v-if="message.isRead === '0'"></view>
<text class="info-title" :class="{ 'title-bold': message.isRead === '0' }">{{ message.title }}</text>
</view>
<view class="info-meta">
<text class="info-time">{{ message.createTime || message.date }}</text>
</view>
</view>
</view>
<view class="card-divider"></view>
<view class="card-subtitle" v-if="message.subTitle">
<text class="subtitle-label">摘要</text>
<text class="subtitle-text">{{ message.subTitle }}</text>
</view>
<view class="card-content" v-if="message.noticeContent">
<text class="content-label">详情</text>
<text class="content-text">{{ message.noticeContent }}</text>
</view>
<view class="card-footer" v-if="message.noticeType === '4'">
<text class="footer-hint" @click="handleMsgClick">点击查看详情</text>
<uni-icons color="#909090" type="right" size="14"></uni-icons>
</view>
</view>
<!-- <view class="info-card">
<view class="info-item">
<text class="info-item-label">消息类型</text>
<text class="info-item-value">{{ message.noticeType === '4' ? '职位相关' : message.title }}</text>
</view>
<view class="info-item">
<text class="info-item-label">接收时间</text>
<text class="info-item-value">{{ message.createTime || message.date }}</text>
</view>
<view class="info-item">
<text class="info-item-label">阅读状态</text>
<text class="info-item-value status-text" :class="{ unread: message.isRead === '0' }">{{ message.isRead === '0' ? '未读' : '已读' }}</text>
</view>
</view> -->
</view>
<view class="empty-state" v-else-if="!loading">
<image class="empty-icon" src="/static/icon/empty.png" mode="aspectFit"></image>
<text class="empty-text">消息不存在</text>
<text class="empty-desc">该消息可能已被删除</text>
</view>
<view class="loading-state" v-if="loading">
<text class="loading-text">加载中...</text>
</view>
</scroll-view>
</view>
</AppLayout>
</template>
<script setup>
import { inject, ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
const { $api, navTo } = inject('globalFunction');
import { useReadMsg } from '@/stores/useReadMsg';
const message = ref(null);
const loading = ref(false);
const hasMarkedRead = ref(false);
onLoad(() => {
const item = uni.getStorageSync('currentMessageDetail');
if (item) {
message.value = item;
if (item.isRead === '0') {
markAsRead(item);
}
}
loading.value = false;
});
function goBack() {
uni.navigateBack();
}
function markAsRead(item) {
if (!item.noticeId || hasMarkedRead.value) return;
hasMarkedRead.value = true;
$api.createRequest('/app/notice/read/noticeRead', { id: item.noticeId }, 'POST').then(() => {
message.value.isRead = '1';
useReadMsg().fetchMessages();
}).catch(err => {
console.error('标记已读失败:', err);
});
}
function handleMsgClick() {
const item = message.value;
if (!item) return;
if (item.noticeType === '4') {
if (item.bussinessIdEncrypt) {
navTo(`/packageA/pages/post/post?jobId=${encodeURIComponent(item.bussinessId)}&encryptJobId=${encodeURIComponent(item.bussinessIdEncrypt)}`);
}
return;
}
// switch (item.title) {
// case '职位上新':
// navTo('/packageA/pages/newJobPosition/newJobPosition');
// break;
// case '招聘会预约提醒':
// navTo('/packageA/pages/reservation/reservation');
// break;
// case '系统通知':
// navTo('/packageA/pages/systemNotification/systemNotification');
// break;
// }
}
</script>
<style lang="stylus" scoped>
.detail-content
height: 100vh
display: flex
flex-direction: column
background: #F5F6FA
.detail-header
display: flex
align-items: center
justify-content: space-between
padding: 20rpx 28rpx
background: #FFFFFF
position: relative
.header-back
width: 60rpx
height: 60rpx
display: flex
align-items: center
justify-content: center
.header-title
font-size: 36rpx
font-weight: 600
color: #1A1A1A
position: absolute
left: 50%
transform: translateX(-50%)
.header-right
width: 60rpx
.detail-scroll
flex: 1
overflow: hidden
.scroll-body
padding: 28rpx
padding-bottom: 40rpx
.msg-card
background: #FFFFFF
border-radius: 20rpx
padding: 32rpx
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06)
transition: all 0.2s ease
&:active
transform: scale(0.99)
&.unread
border-left: 6rpx solid #FF4757
.card-row
display: flex
align-items: center
.card-icon
width: 88rpx
height: 88rpx
border-radius: 50%
display: flex
align-items: center
justify-content: center
margin-right: 24rpx
flex-shrink: 0
.card-icon-img
width: 100%
height: 100%
border-radius: 50%
.card-icon-default
width: 60%
height: 60%
.card-info
flex: 1
min-width: 0
.info-title-row
display: flex
align-items: center
margin-bottom: 12rpx
.unread-dot
width: 14rpx
height: 14rpx
background: #FF4757
border-radius: 50%
margin-right: 10rpx
flex-shrink: 0
.info-title
font-size: 34rpx
color: #1A1A1A
font-weight: 500
line-height: 1.3
&.title-bold
font-weight: 700
.info-meta
display: flex
align-items: center
.info-status
font-size: 24rpx
color: #FF4757
display: flex
align-items: center
margin-right: 20rpx
&.read
color: #BBBBBB
.status-dot
width: 10rpx
height: 10rpx
background: #FF4757
border-radius: 50%
margin-right: 6rpx
.info-time
font-size: 24rpx
color: #AAAAAA
.card-divider
height: 1rpx
background: #F0F0F0
margin: 28rpx 0
.card-subtitle
margin-bottom: 24rpx
.subtitle-label
display: inline-block
font-size: 22rpx
color: #FFFFFF
background: #256BFA
border-radius: 6rpx
padding: 2rpx 12rpx
margin-bottom: 12rpx
.subtitle-text
display: block
font-size: 28rpx
color: #333333
line-height: 1.5
.card-content
.content-label
display: inline-block
font-size: 22rpx
color: #FFFFFF
background: #9E74FD
border-radius: 6rpx
padding: 2rpx 12rpx
margin-bottom: 12rpx
.content-text
display: block
font-size: 28rpx
color: #555555
line-height: 1.7
.card-footer
margin-top: 32rpx
padding-top: 24rpx
border-top: 1rpx dashed #E8E8E8
display: flex
align-items: center
justify-content: center
.footer-hint
font-size: 26rpx
color: #256BFA
margin-right: 4rpx
.info-card
background: #FFFFFF
border-radius: 20rpx
padding: 24rpx 32rpx
margin-top: 24rpx
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06)
.info-item
display: flex
justify-content: space-between
align-items: center
padding: 20rpx 0
border-bottom: 1rpx solid #F5F5F5
&:last-child
border-bottom: none
.info-item-label
font-size: 26rpx
color: #999999
.info-item-value
font-size: 26rpx
color: #333333
font-weight: 500
&.status-text.unread
color: #FF4757
.empty-state
display: flex
flex-direction: column
align-items: center
justify-content: center
padding: 200rpx 40rpx
.empty-icon
width: 200rpx
height: 200rpx
margin-bottom: 32rpx
opacity: 0.5
.empty-text
font-size: 30rpx
color: #999999
font-weight: 500
margin-bottom: 12rpx
.empty-desc
font-size: 26rpx
color: #CCCCCC
.loading-state
display: flex
justify-content: center
padding: 200rpx 0
.loading-text
font-size: 28rpx
color: #BBBBBB
</style>