| | |
| | | v-for="(item) in messageList" |
| | | :key="item.id" |
| | | class="message-item" |
| | | :class="{ 'unread': !item.read }"> |
| | | :class="{ |
| | | 'unread': !item.read, |
| | | [getApprovalTypeClass(item.noticeTitle)]: true |
| | | }"> |
| | | <view class="message-content"> |
| | | <view class="message-header"> |
| | | <text class="message-title">{{ item.noticeTitle }}</text> |
| | | <text class="message-time">{{ formatTime(item.createTime) }}</text> |
| | | </view> |
| | | <text class="message-desc">{{ item.noticeContent }}</text> |
| | | <view class="message-footer"> |
| | | <view v-if="activeTab === 0" |
| | | class="message-footer"> |
| | | <text class="message-view" |
| | | @click="goToDetail(item)"> |
| | | 去查看 > |
| | | 确认消息 |
| | | </text> |
| | | </view> |
| | | </view> |
| | |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { listNotice } from "@/api/login.js"; |
| | | import { onShow } from "@dcloudio/uni-app"; |
| | | import { listNotice, confirmMessage, getNoticeCount } from "@/api/login.js"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | |
| | | // 标签页数据 |
| | |
| | | return `${Y}-${M}-${D} ${h}:${m}`; |
| | | }; |
| | | |
| | | // 根据标题获取审批类型对应的样式类名 |
| | | const getApprovalTypeClass = (title) => { |
| | | if (!title) return 'type-default'; |
| | | const titleStr = title.toString().trim(); |
| | | |
| | | if (titleStr.includes('采购审批') || titleStr.includes('采购')) { |
| | | return 'type-purchase'; |
| | | } else if (titleStr.includes('报价审批') || titleStr.includes('报价')) { |
| | | return 'type-quotation'; |
| | | } else if (titleStr.includes('发货审批') || titleStr.includes('发货')) { |
| | | return 'type-shipment'; |
| | | } else if (titleStr.includes('公出') || titleStr.includes('公出管理')) { |
| | | return 'type-business-trip'; |
| | | } else if (titleStr.includes('请假') || titleStr.includes('请假管理')) { |
| | | return 'type-leave'; |
| | | } else if (titleStr.includes('出差') || titleStr.includes('出差管理')) { |
| | | return 'type-travel'; |
| | | } else if (titleStr.includes('报销') || titleStr.includes('报销管理')) { |
| | | return 'type-reimbursement'; |
| | | } else if (titleStr.includes('危险作业')) { |
| | | return 'type-dangerous'; |
| | | } |
| | | |
| | | return 'type-default'; |
| | | }; |
| | | |
| | | // 根据 noticeTitle 判断跳转页面 |
| | | const getJumpPathByTitle = (title, appJumpPath) => { |
| | | if (!title) return null; |
| | | |
| | | const titleStr = title.toString().trim(); |
| | | |
| | | // 尝试从 appJumpPath 中提取 approveId |
| | | let approveId = null; |
| | | if (appJumpPath) { |
| | | const queryIndex = appJumpPath.indexOf('?'); |
| | | if (queryIndex !== -1) { |
| | | const queryString = appJumpPath.substring(queryIndex + 1); |
| | | const params = queryString.split('&'); |
| | | params.forEach(param => { |
| | | const [key, value] = param.split('='); |
| | | if (key === 'approveId' && value) { |
| | | approveId = decodeURIComponent(value); |
| | | } |
| | | }); |
| | | } |
| | | // 如果没有在查询参数中找到,尝试从路径中提取(如 /pages/xxx/xxx/123) |
| | | if (!approveId) { |
| | | const pathParts = appJumpPath.split('/'); |
| | | const lastPart = pathParts[pathParts.length - 1]; |
| | | if (lastPart && !lastPart.includes('?') && !lastPart.includes('.')) { |
| | | approveId = lastPart; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 根据标题判断审批类型和跳转路径 |
| | | if (titleStr.includes('采购审批') || titleStr.includes('采购')) { |
| | | if (approveId) { |
| | | uni.setStorageSync('approveId', approveId); |
| | | uni.setStorageSync('approveType', '5'); |
| | | return `/pages/cooperativeOffice/collaborativeApproval/approve?approveType=5`; |
| | | } |
| | | return `/pages/cooperativeOffice/collaborativeApproval/index5`; |
| | | } else if (titleStr.includes('报价审批') || titleStr.includes('报价')) { |
| | | if (approveId) { |
| | | uni.setStorageSync('approveId', approveId); |
| | | uni.setStorageSync('approveType', '6'); |
| | | return `/pages/cooperativeOffice/collaborativeApproval/approve?approveType=6`; |
| | | } |
| | | return `/pages/cooperativeOffice/collaborativeApproval/index6`; |
| | | } else if (titleStr.includes('发货审批') || titleStr.includes('发货')) { |
| | | if (approveId) { |
| | | uni.setStorageSync('approveId', approveId); |
| | | uni.setStorageSync('approveType', '7'); |
| | | return `/pages/cooperativeOffice/collaborativeApproval/approve?approveType=7`; |
| | | } |
| | | return `/pages/cooperativeOffice/collaborativeApproval/index7`; |
| | | } else if (titleStr.includes('公出') || titleStr.includes('公出管理')) { |
| | | if (approveId) { |
| | | uni.setStorageSync('approveId', approveId); |
| | | uni.setStorageSync('approveType', '1'); |
| | | return `/pages/cooperativeOffice/collaborativeApproval/approve?approveType=1`; |
| | | } |
| | | return `/pages/cooperativeOffice/collaborativeApproval/index1`; |
| | | } else if (titleStr.includes('请假') || titleStr.includes('请假管理')) { |
| | | if (approveId) { |
| | | uni.setStorageSync('approveId', approveId); |
| | | uni.setStorageSync('approveType', '2'); |
| | | return `/pages/cooperativeOffice/collaborativeApproval/approve?approveType=2`; |
| | | } |
| | | return `/pages/cooperativeOffice/collaborativeApproval/index2`; |
| | | } else if (titleStr.includes('出差') || titleStr.includes('出差管理')) { |
| | | if (approveId) { |
| | | uni.setStorageSync('approveId', approveId); |
| | | uni.setStorageSync('approveType', '3'); |
| | | return `/pages/cooperativeOffice/collaborativeApproval/approve?approveType=3`; |
| | | } |
| | | return `/pages/cooperativeOffice/collaborativeApproval/index3`; |
| | | } else if (titleStr.includes('报销') || titleStr.includes('报销管理')) { |
| | | if (approveId) { |
| | | uni.setStorageSync('approveId', approveId); |
| | | uni.setStorageSync('approveType', '4'); |
| | | return `/pages/cooperativeOffice/collaborativeApproval/approve?approveType=4`; |
| | | } |
| | | return `/pages/cooperativeOffice/collaborativeApproval/index4`; |
| | | } else if (titleStr.includes('危险作业')) { |
| | | if (approveId) { |
| | | uni.setStorageSync('approveId', approveId); |
| | | uni.setStorageSync('approveType', '8'); |
| | | return `/pages/cooperativeOffice/collaborativeApproval/approve?approveType=8`; |
| | | } |
| | | return `/pages/cooperativeOffice/collaborativeApproval/index8`; |
| | | } |
| | | |
| | | // 如果都不匹配,尝试使用原始的 appJumpPath |
| | | if (appJumpPath) { |
| | | let jumpPath = appJumpPath; |
| | | if (jumpPath.indexOf("/") !== 0) { |
| | | jumpPath = "/" + jumpPath; |
| | | } |
| | | return jumpPath; |
| | | } |
| | | |
| | | return null; |
| | | }; |
| | | |
| | | // 更新 tab 栏角标 |
| | | const updateTabBarBadge = () => { |
| | | if (userId.value) { |
| | | getNoticeCount(userId.value) |
| | | .then(res => { |
| | | const count = res.data || 0; |
| | | // 更新tabbar的角标 |
| | | if (count > 0) { |
| | | uni.setTabBarBadge({ |
| | | index: 1, // 消息标签页的索引 |
| | | text: count.toString(), |
| | | }); |
| | | } else { |
| | | uni.removeTabBarBadge({ |
| | | index: 1, |
| | | }); |
| | | } |
| | | }) |
| | | .catch(error => { |
| | | console.error("获取未读消息数量失败:", error); |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | // 跳转到详情页 |
| | | const goToDetail = item => { |
| | | if (item.jumpPath.indexOf("/") === 0) { |
| | | uni.navigateTo({ |
| | | url: item.jumpPath, |
| | | }); |
| | | } else { |
| | | uni.navigateTo({ |
| | | url: "/" + item.jumpPath, |
| | | }); |
| | | } |
| | | confirmMessage(item.noticeId, 1).then(res => { |
| | | if (res.code === 200) { |
| | | // uni.showToast({ title: "确认成功", icon: "success" }); |
| | | loadMessages(false); |
| | | |
| | | // 更新 tab 栏角标 |
| | | updateTabBarBadge(); |
| | | |
| | | // 根据 noticeTitle 判断跳转页面 |
| | | const jumpPath = getJumpPathByTitle(item.noticeTitle, item.appJumpPath); |
| | | |
| | | if (jumpPath) { |
| | | console.log('跳转路径:', jumpPath); |
| | | console.log('消息标题:', item.noticeTitle); |
| | | console.log('消息数据:', item); |
| | | |
| | | uni.navigateTo({ |
| | | url: jumpPath, |
| | | fail: (err) => { |
| | | console.error('跳转失败:', err); |
| | | uni.showToast({ |
| | | title: "跳转失败,请检查路径", |
| | | icon: "none", |
| | | }); |
| | | } |
| | | }); |
| | | } else { |
| | | console.warn('无法根据标题判断跳转页面:', item.noticeTitle); |
| | | uni.showToast({ |
| | | title: "无法跳转,请手动进入", |
| | | icon: "none", |
| | | }); |
| | | } |
| | | } else { |
| | | uni.showToast({ title: "确认失败", icon: "none" }); |
| | | } |
| | | }); |
| | | }; |
| | | const userStore = useUserStore(); |
| | | const userId = ref(""); |
| | |
| | | onMounted(() => { |
| | | getUserId().then(() => { |
| | | loadMessages(); |
| | | // 更新 tab 栏角标 |
| | | updateTabBarBadge(); |
| | | }); |
| | | }); |
| | | |
| | | // 页面显示时也更新角标(从其他页面返回时) |
| | | onShow(() => { |
| | | if (userId.value) { |
| | | updateTabBarBadge(); |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | // 全局变量 |
| | | $primary-color: #2c7be5; |
| | | $primary-color: #2979ff; |
| | | $primary-light: #4a90e2; |
| | | $success-color: #4cd964; |
| | | $warning-color: #ff9500; |
| | | $danger-color: #ff3b30; |
| | | $text-primary: #333333; |
| | | $text-secondary: #666666; |
| | | $text-tertiary: #999999; |
| | | $bg-color: #f5f7fa; |
| | | $text-primary: #1f2937; |
| | | $text-secondary: #6b7280; |
| | | $text-tertiary: #9ca3af; |
| | | $bg-color: #f9fafb; |
| | | $card-bg: #ffffff; |
| | | $border-color: #e8e8e8; |
| | | $shadow-sm: 0 2rpx 8rpx rgba(0, 0, 0, 0.08); |
| | | $border-color: #e5e7eb; |
| | | $shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1); |
| | | $shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1); |
| | | $shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1); |
| | | |
| | | .message-page { |
| | | min-height: 100vh; |
| | | background-color: $bg-color; |
| | | background: linear-gradient(180deg, #f9fafb 0%, #ffffff 100%); |
| | | padding-bottom: 30rpx; |
| | | } |
| | | |
| | | /* 标签页容器 */ |
| | | .tabs-container { |
| | | background-color: #ffffff; |
| | | margin-bottom: 20rpx; |
| | | box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08); |
| | | margin-bottom: 12rpx; |
| | | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); |
| | | position: sticky; |
| | | top: 0; |
| | | z-index: 10; |
| | | } |
| | | |
| | | /* 消息列表 */ |
| | | .message-list { |
| | | margin: 0 20rpx 20rpx; |
| | | padding: 0 24rpx 24rpx; |
| | | min-height: 600rpx; |
| | | height: calc(100vh - 200rpx); |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | /* 加载状态 */ |
| | | .loading-state { |
| | | background-color: $card-bg; |
| | | border-radius: 16rpx; |
| | | border-radius: 20rpx; |
| | | box-shadow: $shadow-sm; |
| | | text-align: center; |
| | | padding: 120rpx 0; |
| | | margin-bottom: 20rpx; |
| | | margin: 0 0 24rpx 0; |
| | | border: 1px solid rgba(0, 0, 0, 0.05); |
| | | width: 100%; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .loading-text { |
| | |
| | | .message-item { |
| | | display: flex; |
| | | align-items: flex-start; |
| | | background-color: $card-bg; |
| | | border-radius: 16rpx; |
| | | background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%); |
| | | border-radius: 20rpx; |
| | | box-shadow: $shadow-sm; |
| | | padding: 24rpx; |
| | | margin-bottom: 20rpx; |
| | | margin-right: 40rpx; |
| | | transition: all 0.3s ease; |
| | | padding: 32rpx; |
| | | margin: 0 0 24rpx 0; |
| | | border: 1px solid rgba(0, 0, 0, 0.05); |
| | | transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); |
| | | position: relative; |
| | | overflow: hidden; |
| | | width: 100%; |
| | | box-sizing: border-box; |
| | | |
| | | &::before { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | width: 6rpx; |
| | | height: 100%; |
| | | background: linear-gradient(180deg, $primary-color 0%, $primary-light 100%); |
| | | opacity: 0; |
| | | transition: opacity 0.3s ease; |
| | | } |
| | | } |
| | | |
| | | .message-item:hover { |
| | | box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.12); |
| | | transform: translateY(-2rpx); |
| | | .message-item:active { |
| | | transform: scale(0.98); |
| | | box-shadow: $shadow-md; |
| | | } |
| | | |
| | | .message-item.unread { |
| | | border-left: 4rpx solid $primary-color; |
| | | &::before { |
| | | opacity: 1; |
| | | } |
| | | |
| | | .message-title { |
| | | font-weight: 700; |
| | | } |
| | | |
| | | .message-title::before { |
| | | content: ''; |
| | | display: inline-block; |
| | | width: 12rpx; |
| | | height: 12rpx; |
| | | border-radius: 50%; |
| | | margin-right: 12rpx; |
| | | vertical-align: middle; |
| | | animation: pulse 2s infinite; |
| | | } |
| | | } |
| | | |
| | | /* 消息图标 */ |
| | | .message-icon { |
| | | margin-right: 20rpx; |
| | | margin-top: 4rpx; |
| | | // 采购审批 - 蓝色 |
| | | .message-item.type-purchase.unread { |
| | | background: linear-gradient(135deg, #ffffff 0%, #e3f2fd 100%); |
| | | border: 1px solid rgba(33, 150, 243, 0.2); |
| | | box-shadow: 0 2px 8px rgba(33, 150, 243, 0.15); |
| | | |
| | | &::before { |
| | | background: linear-gradient(180deg, #2196f3 0%, #1976d2 100%); |
| | | } |
| | | |
| | | .message-title { |
| | | color: #1976d2; |
| | | } |
| | | |
| | | .message-title::before { |
| | | background: #1976d2; |
| | | } |
| | | |
| | | .message-view { |
| | | background: linear-gradient(135deg, #2196f3 0%, #1976d2 100%); |
| | | box-shadow: 0 4rpx 12rpx rgba(33, 150, 243, 0.3); |
| | | } |
| | | } |
| | | |
| | | // 报价审批 - 绿色 |
| | | .message-item.type-quotation.unread { |
| | | background: linear-gradient(135deg, #ffffff 0%, #e8f5e9 100%); |
| | | border: 1px solid rgba(76, 175, 80, 0.2); |
| | | box-shadow: 0 2px 8px rgba(76, 175, 80, 0.15); |
| | | |
| | | &::before { |
| | | background: linear-gradient(180deg, #4caf50 0%, #388e3c 100%); |
| | | } |
| | | |
| | | .message-title { |
| | | color: #388e3c; |
| | | } |
| | | |
| | | .message-title::before { |
| | | background: #388e3c; |
| | | } |
| | | |
| | | .message-view { |
| | | background: linear-gradient(135deg, #4caf50 0%, #388e3c 100%); |
| | | box-shadow: 0 4rpx 12rpx rgba(76, 175, 80, 0.3); |
| | | } |
| | | } |
| | | |
| | | // 发货审批 - 橙色 |
| | | .message-item.type-shipment.unread { |
| | | background: linear-gradient(135deg, #ffffff 0%, #fff3e0 100%); |
| | | border: 1px solid rgba(255, 152, 0, 0.2); |
| | | box-shadow: 0 2px 8px rgba(255, 152, 0, 0.15); |
| | | |
| | | &::before { |
| | | background: linear-gradient(180deg, #ff9800 0%, #f57c00 100%); |
| | | } |
| | | |
| | | .message-title { |
| | | color: #f57c00; |
| | | } |
| | | |
| | | .message-title::before { |
| | | background: #f57c00; |
| | | } |
| | | |
| | | .message-view { |
| | | background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%); |
| | | box-shadow: 0 4rpx 12rpx rgba(255, 152, 0, 0.3); |
| | | } |
| | | } |
| | | |
| | | // 公出管理 - 紫色 |
| | | .message-item.type-business-trip.unread { |
| | | background: linear-gradient(135deg, #ffffff 0%, #f3e5f5 100%); |
| | | border: 1px solid rgba(156, 39, 176, 0.2); |
| | | box-shadow: 0 2px 8px rgba(156, 39, 176, 0.15); |
| | | |
| | | &::before { |
| | | background: linear-gradient(180deg, #9c27b0 0%, #7b1fa2 100%); |
| | | } |
| | | |
| | | .message-title { |
| | | color: #7b1fa2; |
| | | } |
| | | |
| | | .message-title::before { |
| | | background: #7b1fa2; |
| | | } |
| | | |
| | | .message-view { |
| | | background: linear-gradient(135deg, #9c27b0 0%, #7b1fa2 100%); |
| | | box-shadow: 0 4rpx 12rpx rgba(156, 39, 176, 0.3); |
| | | } |
| | | } |
| | | |
| | | // 请假管理 - 青色 |
| | | .message-item.type-leave.unread { |
| | | background: linear-gradient(135deg, #ffffff 0%, #e0f2f1 100%); |
| | | border: 1px solid rgba(0, 150, 136, 0.2); |
| | | box-shadow: 0 2px 8px rgba(0, 150, 136, 0.15); |
| | | |
| | | &::before { |
| | | background: linear-gradient(180deg, #009688 0%, #00796b 100%); |
| | | } |
| | | |
| | | .message-title { |
| | | color: #00796b; |
| | | } |
| | | |
| | | .message-title::before { |
| | | background: #00796b; |
| | | } |
| | | |
| | | .message-view { |
| | | background: linear-gradient(135deg, #009688 0%, #00796b 100%); |
| | | box-shadow: 0 4rpx 12rpx rgba(0, 150, 136, 0.3); |
| | | } |
| | | } |
| | | |
| | | // 出差管理 - 红色 |
| | | .message-item.type-travel.unread { |
| | | background: linear-gradient(135deg, #ffffff 0%, #ffebee 100%); |
| | | border: 1px solid rgba(244, 67, 54, 0.2); |
| | | box-shadow: 0 2px 8px rgba(244, 67, 54, 0.15); |
| | | |
| | | &::before { |
| | | background: linear-gradient(180deg, #f44336 0%, #d32f2f 100%); |
| | | } |
| | | |
| | | .message-title { |
| | | color: #d32f2f; |
| | | } |
| | | |
| | | .message-title::before { |
| | | background: #d32f2f; |
| | | } |
| | | |
| | | .message-view { |
| | | background: linear-gradient(135deg, #f44336 0%, #d32f2f 100%); |
| | | box-shadow: 0 4rpx 12rpx rgba(244, 67, 54, 0.3); |
| | | } |
| | | } |
| | | |
| | | // 报销管理 - 粉色 |
| | | .message-item.type-reimbursement.unread { |
| | | background: linear-gradient(135deg, #ffffff 0%, #fce4ec 100%); |
| | | border: 1px solid rgba(233, 30, 99, 0.2); |
| | | box-shadow: 0 2px 8px rgba(233, 30, 99, 0.15); |
| | | |
| | | &::before { |
| | | background: linear-gradient(180deg, #e91e63 0%, #c2185b 100%); |
| | | } |
| | | |
| | | .message-title { |
| | | color: #c2185b; |
| | | } |
| | | |
| | | .message-title::before { |
| | | background: #c2185b; |
| | | } |
| | | |
| | | .message-view { |
| | | background: linear-gradient(135deg, #e91e63 0%, #c2185b 100%); |
| | | box-shadow: 0 4rpx 12rpx rgba(233, 30, 99, 0.3); |
| | | } |
| | | } |
| | | |
| | | // 危险作业 - 深红色 |
| | | .message-item.type-dangerous.unread { |
| | | background: linear-gradient(135deg, #ffffff 0%, #ffebee 100%); |
| | | border: 1px solid rgba(211, 47, 47, 0.3); |
| | | box-shadow: 0 2px 8px rgba(211, 47, 47, 0.2); |
| | | |
| | | &::before { |
| | | background: linear-gradient(180deg, #d32f2f 0%, #b71c1c 100%); |
| | | } |
| | | |
| | | .message-title { |
| | | color: #b71c1c; |
| | | } |
| | | |
| | | .message-title::before { |
| | | background: #b71c1c; |
| | | } |
| | | |
| | | .message-view { |
| | | background: linear-gradient(135deg, #d32f2f 0%, #b71c1c 100%); |
| | | box-shadow: 0 4rpx 12rpx rgba(211, 47, 47, 0.4); |
| | | } |
| | | } |
| | | |
| | | // 默认类型 - 蓝色(原色) |
| | | .message-item.type-default.unread { |
| | | background: linear-gradient(135deg, #ffffff 0%, #f0f7ff 100%); |
| | | border: 1px solid rgba(41, 121, 255, 0.15); |
| | | box-shadow: 0 2px 8px rgba(41, 121, 255, 0.1); |
| | | |
| | | &::before { |
| | | background: linear-gradient(180deg, $primary-color 0%, $primary-light 100%); |
| | | } |
| | | |
| | | .message-title { |
| | | color: $primary-color; |
| | | } |
| | | |
| | | .message-title::before { |
| | | background: $primary-color; |
| | | } |
| | | } |
| | | |
| | | @keyframes pulse { |
| | | 0%, 100% { |
| | | opacity: 1; |
| | | transform: scale(1); |
| | | } |
| | | 50% { |
| | | opacity: 0.6; |
| | | transform: scale(1.2); |
| | | } |
| | | } |
| | | |
| | | /* 消息内容 */ |
| | | .message-content { |
| | | flex: 1; |
| | | position: relative; |
| | | z-index: 1; |
| | | } |
| | | |
| | | /* 消息头部 */ |
| | | .message-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 12rpx; |
| | | align-items: flex-start; |
| | | margin-bottom: 16rpx; |
| | | gap: 16rpx; |
| | | } |
| | | |
| | | .message-title { |
| | | font-size: 16px; |
| | | font-size: 32rpx; |
| | | font-weight: 600; |
| | | color: $text-primary; |
| | | flex: 1; |
| | | margin-right: 20rpx; |
| | | line-height: 1.5; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | display: -webkit-box; |
| | | -webkit-line-clamp: 2; |
| | | -webkit-box-orient: vertical; |
| | | } |
| | | |
| | | .message-time { |
| | | font-size: 12px; |
| | | font-size: 24rpx; |
| | | color: $text-tertiary; |
| | | white-space: nowrap; |
| | | flex-shrink: 0; |
| | | padding: 4rpx 12rpx; |
| | | background: rgba(0, 0, 0, 0.03); |
| | | border-radius: 12rpx; |
| | | } |
| | | |
| | | /* 消息描述 */ |
| | | .message-desc { |
| | | font-size: 14px; |
| | | font-size: 28rpx; |
| | | color: $text-secondary; |
| | | line-height: 1.4; |
| | | margin-bottom: 16rpx; |
| | | line-height: 1.6; |
| | | margin-bottom: 20rpx; |
| | | display: -webkit-box; |
| | | -webkit-line-clamp: 2; |
| | | line-clamp: 2; |
| | | -webkit-box-orient: vertical; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | max-height: 2.4em; |
| | | } |
| | | |
| | | /* 消息底部 */ |
| | |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | align-items: center; |
| | | margin-top: 16rpx; |
| | | padding-top: 16rpx; |
| | | border-top: 1px solid rgba(0, 0, 0, 0.05); |
| | | } |
| | | |
| | | .message-creator { |
| | | font-size: 12px; |
| | | color: $text-tertiary; |
| | | .message-view { |
| | | padding: 12rpx 32rpx; |
| | | background: linear-gradient(135deg, $primary-color 0%, $primary-light 100%); |
| | | color: #ffffff; |
| | | border-radius: 24rpx; |
| | | font-size: 26rpx; |
| | | font-weight: 500; |
| | | box-shadow: 0 4rpx 12rpx rgba(41, 121, 255, 0.3); |
| | | transition: all 0.3s ease; |
| | | position: relative; |
| | | overflow: hidden; |
| | | |
| | | &::before { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | width: 0; |
| | | height: 0; |
| | | border-radius: 50%; |
| | | background: rgba(255, 255, 255, 0.3); |
| | | transform: translate(-50%, -50%); |
| | | transition: width 0.6s, height 0.6s; |
| | | } |
| | | |
| | | &:active { |
| | | transform: scale(0.95); |
| | | box-shadow: 0 2rpx 8rpx rgba(41, 121, 255, 0.4); |
| | | |
| | | &::before { |
| | | width: 300rpx; |
| | | height: 300rpx; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* 空状态 */ |
| | | .empty-state { |
| | | background-color: $card-bg; |
| | | border-radius: 16rpx; |
| | | background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%); |
| | | border-radius: 20rpx; |
| | | box-shadow: $shadow-sm; |
| | | text-align: center; |
| | | padding: 160rpx 0; |
| | | margin: 40rpx 0; |
| | | padding: 160rpx 40rpx; |
| | | margin: 60rpx 0 0 0; |
| | | border: 1px solid rgba(0, 0, 0, 0.05); |
| | | width: 100%; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .empty-text { |
| | | font-size: 14px; |
| | | font-size: 28rpx; |
| | | color: $text-tertiary; |
| | | margin-top: 24rpx; |
| | | font-weight: 500; |
| | |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | padding: 30rpx 0; |
| | | margin-top: 10rpx; |
| | | } |
| | | |
| | | .loading-more-text { |
| | | font-size: 14px; |
| | | color: $text-tertiary; |
| | | margin-left: 10rpx; |
| | | } |
| | | |
| | | /* 加载更多 */ |
| | | .load-more { |
| | | text-align: center; |
| | | padding: 30rpx 0; |
| | | font-size: 14px; |
| | | color: $primary-color; |
| | | font-weight: 500; |
| | | padding: 40rpx 0; |
| | | margin-top: 20rpx; |
| | | } |
| | | |
| | | .load-more-text { |
| | | display: inline-block; |
| | | padding: 10rpx 30rpx; |
| | | background-color: rgba($primary-color, 0.1); |
| | | border-radius: 20rpx; |
| | | transition: all 0.3s ease; |
| | | } |
| | | |
| | | .load-more-text:hover { |
| | | background-color: rgba($primary-color, 0.2); |
| | | transform: translateY(-2rpx); |
| | | .loading-more-text { |
| | | font-size: 26rpx; |
| | | color: $text-tertiary; |
| | | margin-left: 12rpx; |
| | | } |
| | | |
| | | /* 动画效果 */ |
| | | @keyframes fadeInUp { |
| | | from { |
| | | opacity: 0; |
| | | transform: translateY(20rpx); |
| | | transform: translateY(30rpx); |
| | | } |
| | | to { |
| | | opacity: 1; |
| | |
| | | } |
| | | |
| | | .message-item { |
| | | animation: fadeInUp 0.3s ease-out; |
| | | animation: fadeInUp 0.4s cubic-bezier(0.4, 0, 0.2, 1) backwards; |
| | | } |
| | | |
| | | .message-item:nth-child(1) { |
| | | animation-delay: 0.05s; |
| | | } |
| | | |
| | | .message-item:nth-child(2) { |
| | |
| | | } |
| | | |
| | | .message-item:nth-child(3) { |
| | | animation-delay: 0.2s; |
| | | animation-delay: 0.15s; |
| | | } |
| | | |
| | | .message-item:nth-child(4) { |
| | | animation-delay: 0.3s; |
| | | animation-delay: 0.2s; |
| | | } |
| | | |
| | | .message-item:nth-child(5) { |
| | | animation-delay: 0.4s; |
| | | animation-delay: 0.25s; |
| | | } |
| | | .message-view { |
| | | float: right; |
| | | color: $primary-color; |
| | | |
| | | /* 响应式优化 */ |
| | | @media (prefers-color-scheme: dark) { |
| | | .message-page { |
| | | background: linear-gradient(180deg, #1f2937 0%, #111827 100%); |
| | | } |
| | | |
| | | .tabs-container { |
| | | background-color: #1f2937; |
| | | border-bottom: 1px solid rgba(255, 255, 255, 0.1); |
| | | } |
| | | |
| | | .message-item { |
| | | background: linear-gradient(135deg, #1f2937 0%, #111827 100%); |
| | | border-color: rgba(255, 255, 255, 0.1); |
| | | } |
| | | |
| | | .message-item.unread { |
| | | background: linear-gradient(135deg, #1f2937 0%, #1e3a5f 100%); |
| | | border-color: rgba(41, 121, 255, 0.3); |
| | | } |
| | | |
| | | .message-title { |
| | | color: #f3f4f6; |
| | | } |
| | | |
| | | .message-desc { |
| | | color: #d1d5db; |
| | | } |
| | | |
| | | .message-time { |
| | | background: rgba(255, 255, 255, 0.1); |
| | | color: #9ca3af; |
| | | } |
| | | |
| | | .empty-state { |
| | | background: linear-gradient(135deg, #1f2937 0%, #111827 100%); |
| | | border-color: rgba(255, 255, 255, 0.1); |
| | | } |
| | | } |
| | | </style> |