mirror of
https://github.com/LifeArchiveProject/WeChatDataAnalysis.git
synced 2026-02-02 22:10:50 +08:00
feat(chat): 聊天页支持可选 username 路由
- 将聊天页迁移为 pages/chat/[[username]].vue(/chat 与 /chat/:username) - 选中会话时同步 URL,支持路由直达指定会话 - 文件消息卡片补充文件类型图标与 WeChat PC 标识资源
This commit is contained in:
1
frontend/assets/images/wechat/WeChat-Icon-Logo.wine.svg
Normal file
1
frontend/assets/images/wechat/WeChat-Icon-Logo.wine.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-1 -1 52 43"><defs><linearGradient gradientUnits="userSpaceOnUse" gradientTransform="scale(1.06228 .94137)" id="a" y2=".1504" x2="17.2422" y1="32.4312" x1="17.2422"><stop offset="0%" stop-color="#78D431"/><stop offset="100%" stop-color="#9EEE69"/><stop offset="100%" stop-color="#9EEE69"/></linearGradient><linearGradient gradientUnits="userSpaceOnUse" gradientTransform="scale(1.05667 .94637)" id="b" y2="14.6966" x2="33.4727" y1="41.634" x1="33.4727"><stop offset="0%" stop-color="#E4E6E6"/><stop offset="100%" stop-color="#F5F5FF"/></linearGradient></defs><g fill="none"><path fill="url(#a)" d="M0 15.3063c0 4.5919 2.4846 8.787 6.3245 11.5648.3388.2267.5082.5669.5082 1.0204 0 .1134-.0565.2835-.0565.3968-.2823 1.1338-.7906 3.0046-.847 3.0613-.0565.17-.113.2834-.113.4535 0 .3402.2824.6236.6212.6236.113 0 .2259-.0567.3388-.1134l4.0093-2.3243c.2823-.17.6211-.2834.96-.2834.1693 0 .3952 0 .5646.0567 1.8635.5669 3.8963.8503 5.9857.8503 10.1078 0 18.2957-6.8595 18.2957-15.3063S28.4035 0 18.2958 0C8.1879 0 0 6.8595 0 15.3063"/><path fill="url(#b)" d="M35.3424 39.6205c1.7463 0 3.4363-.2284 4.9572-.6854.1127-.057.2817-.057.4507-.057.2817 0 .5633.1142.7887.2284l3.3236 1.942c.1126.057.169.1142.2816.1142.2817 0 .507-.2285.507-.514 0-.1143-.0563-.2285-.0563-.3999 0-.0571-.4507-1.5992-.676-2.5702-.0563-.1142-.0563-.2285-.0563-.3427 0-.3427.169-.6283.4506-.8568 3.211-2.3417 5.239-5.8258 5.239-9.7097 0-7.0824-6.8163-12.851-15.2098-12.851s-15.2097 5.7115-15.2097 12.851c0 7.0824 6.8162 12.8511 15.2097 12.8511z"/><path fill="#187E28" d="M14.5484 10.3647c0 1.3223-1.0389 2.369-2.3512 2.369-1.3124 0-2.3513-1.0467-2.3513-2.369 0-1.3223 1.039-2.369 2.3513-2.369 1.3123 0 2.3512 1.0467 2.3512 2.369m12.1972 0c0 1.3223-1.039 2.369-2.3513 2.369-1.3123 0-2.3512-1.0467-2.3512-2.369 0-1.3223 1.039-2.369 2.3512-2.369 1.3124 0 2.3513 1.0467 2.3513 2.369"/><path fill="#858C8C" d="M38.502 22.8023c0 1.1517.9143 2.073 2.0573 2.073 1.143 0 2.0573-.9213 2.0573-2.073 0-1.1516-.9144-2.0729-2.0573-2.0729-1.143 0-2.0574.9213-2.0574 2.073m-10.1398 0c0 1.1516.9144 2.0729 2.0573 2.0729 1.143 0 2.0574-.9213 2.0574-2.073 0-1.1516-.9144-2.0729-2.0574-2.0729-1.143 0-2.0573.9213-2.0573 2.073"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
BIN
frontend/assets/images/wechat/excel.png
Normal file
BIN
frontend/assets/images/wechat/excel.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
frontend/assets/images/wechat/pdf.png
Normal file
BIN
frontend/assets/images/wechat/pdf.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1010 B |
BIN
frontend/assets/images/wechat/word.png
Normal file
BIN
frontend/assets/images/wechat/word.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
frontend/assets/images/wechat/zip.png
Normal file
BIN
frontend/assets/images/wechat/zip.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 829 B |
@@ -201,16 +201,20 @@
|
|||||||
:from="message.from"
|
:from="message.from"
|
||||||
/>
|
/>
|
||||||
<div v-else-if="message.renderType === 'file'"
|
<div v-else-if="message.renderType === 'file'"
|
||||||
class="max-w-80 py-2.5 pr-2 pl-4 flex items-start bg-white space-x-2.5 msg-radius cursor-pointer border border-neutral-200 hover:bg-gray-50 transition-colors"
|
class="wechat-redpacket-card wechat-special-card wechat-file-card msg-radius"
|
||||||
|
:class="message.isSent ? 'wechat-special-sent-side' : ''"
|
||||||
@click="onFileClick(message)"
|
@click="onFileClick(message)"
|
||||||
@contextmenu="openMediaContextMenu($event, message, 'file')">
|
@contextmenu="openMediaContextMenu($event, message, 'file')">
|
||||||
<div class="flex-1 min-w-0">
|
<div class="wechat-redpacket-content">
|
||||||
<h4 class="break-words font-medium text-sm text-gray-900">{{ message.title || message.content }}</h4>
|
<div class="wechat-redpacket-info wechat-file-info">
|
||||||
<small class="text-neutral-500 text-xs" v-if="message.fileSize">{{ formatFileSize(message.fileSize) }}</small>
|
<span class="wechat-file-name">{{ message.title || message.content || '文件' }}</span>
|
||||||
|
<span class="wechat-file-size" v-if="message.fileSize">{{ formatFileSize(message.fileSize) }}</span>
|
||||||
|
</div>
|
||||||
|
<img :src="getFileIconUrl(message.title)" alt="" class="wechat-file-icon" />
|
||||||
</div>
|
</div>
|
||||||
<div class="shrink-0 w-10 h-10 flex items-center justify-center">
|
<div class="wechat-redpacket-bottom wechat-file-bottom">
|
||||||
<!-- 根据文件类型显示图标 -->
|
<img :src="wechatPcLogoUrl" alt="" class="wechat-file-logo" />
|
||||||
<component :is="getFileIcon(message.title || message.content)" class="w-8 h-8" />
|
<span>微信电脑版</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="message.renderType === 'image'"
|
<div v-else-if="message.renderType === 'image'"
|
||||||
@@ -333,13 +337,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 红包消息 - 微信风格橙色卡片 -->
|
<!-- 红包消息 - 微信风格橙色卡片 -->
|
||||||
<div v-else-if="message.renderType === 'redPacket'" class="wechat-redpacket-card msg-radius"
|
<div v-else-if="message.renderType === 'redPacket'" class="wechat-redpacket-card wechat-special-card msg-radius"
|
||||||
:class="{ 'wechat-redpacket-received': message.redPacketReceived }">
|
:class="[{ 'wechat-redpacket-received': message.redPacketReceived }, message.isSent ? 'wechat-special-sent-side' : '']">
|
||||||
<div class="wechat-redpacket-content">
|
<div class="wechat-redpacket-content">
|
||||||
<img src="/assets/images/wechat/wechat-trans-icon3.png" v-if="!message.redPacketReceived" class="wechat-redpacket-icon" alt="">
|
<img src="/assets/images/wechat/wechat-trans-icon3.png" v-if="!message.redPacketReceived" class="wechat-redpacket-icon" alt="">
|
||||||
<img src="/assets/images/wechat/wechat-trans-icon4.png" v-else class="wechat-redpacket-icon" alt="">
|
<img src="/assets/images/wechat/wechat-trans-icon4.png" v-else class="wechat-redpacket-icon" alt="">
|
||||||
<div class="wechat-redpacket-info">
|
<div class="wechat-redpacket-info">
|
||||||
<span class="wechat-redpacket-text">{{ message.content || '恭喜发财,大吉大利' }}</span>
|
<span class="wechat-redpacket-text">{{ getRedPacketText(message) }}</span>
|
||||||
<span class="wechat-redpacket-status" v-if="message.redPacketReceived">已领取</span>
|
<span class="wechat-redpacket-status" v-if="message.redPacketReceived">已领取</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -419,16 +423,60 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted, onUnmounted, nextTick, defineComponent, h } from 'vue'
|
import { ref, computed, watch, onMounted, onUnmounted, nextTick, defineComponent, h } from 'vue'
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
key: 'chat'
|
||||||
|
})
|
||||||
|
|
||||||
import { useApi } from '~/composables/useApi'
|
import { useApi } from '~/composables/useApi'
|
||||||
import { parseTextWithEmoji } from '~/utils/wechat-emojis'
|
import { parseTextWithEmoji } from '~/utils/wechat-emojis'
|
||||||
|
import wechatPcLogoUrl from '~/assets/images/wechat/WeChat-Icon-Logo.wine.svg'
|
||||||
|
import zipIconUrl from '~/assets/images/wechat/zip.png'
|
||||||
|
import pdfIconUrl from '~/assets/images/wechat/pdf.png'
|
||||||
|
import wordIconUrl from '~/assets/images/wechat/word.png'
|
||||||
|
import excelIconUrl from '~/assets/images/wechat/excel.png'
|
||||||
|
|
||||||
|
// 根据文件名获取对应的图标URL
|
||||||
|
const getFileIconUrl = (fileName) => {
|
||||||
|
if (!fileName) return zipIconUrl
|
||||||
|
const ext = String(fileName).split('.').pop()?.toLowerCase() || ''
|
||||||
|
switch (ext) {
|
||||||
|
case 'pdf':
|
||||||
|
return pdfIconUrl
|
||||||
|
case 'doc':
|
||||||
|
case 'docx':
|
||||||
|
return wordIconUrl
|
||||||
|
case 'xls':
|
||||||
|
case 'xlsx':
|
||||||
|
case 'csv':
|
||||||
|
return excelIconUrl
|
||||||
|
case 'zip':
|
||||||
|
case 'rar':
|
||||||
|
case '7z':
|
||||||
|
case 'tar':
|
||||||
|
case 'gz':
|
||||||
|
default:
|
||||||
|
return zipIconUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 设置页面标题
|
// 设置页面标题
|
||||||
useHead({
|
useHead({
|
||||||
title: '聊天记录查看器 - 微信数据分析助手'
|
title: '聊天记录查看器 - 微信数据分析助手'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
const routeUsername = computed(() => {
|
||||||
|
const raw = route.params.username
|
||||||
|
return (Array.isArray(raw) ? raw[0] : raw) || ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const buildChatPath = (username) => {
|
||||||
|
return username ? `/chat/${encodeURIComponent(username)}` : '/chat'
|
||||||
|
}
|
||||||
|
|
||||||
// 响应式数据
|
// 响应式数据
|
||||||
const selectedContact = ref(null)
|
const selectedContact = ref(null)
|
||||||
|
|
||||||
@@ -611,23 +659,55 @@ const messages = computed(() => {
|
|||||||
return allMessages.value[selectedContact.value.username] || []
|
return allMessages.value[selectedContact.value.username] || []
|
||||||
})
|
})
|
||||||
|
|
||||||
const formatTimeDivider = (ts) => {
|
// 智能时间格式化:今天显示时间,昨天显示"昨天 HH:MM",本周显示"星期X HH:MM",本年显示"MM月DD日 HH:MM",跨年显示"YYYY年MM月DD日 HH:MM"
|
||||||
|
const formatSmartTime = (ts) => {
|
||||||
if (!ts) return ''
|
if (!ts) return ''
|
||||||
try {
|
try {
|
||||||
const d = new Date(Number(ts) * 1000)
|
const d = new Date(Number(ts) * 1000)
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
const hh = String(d.getHours()).padStart(2, '0')
|
const hh = String(d.getHours()).padStart(2, '0')
|
||||||
const mm = String(d.getMinutes()).padStart(2, '0')
|
const mm = String(d.getMinutes()).padStart(2, '0')
|
||||||
const sameDay = d.getFullYear() === now.getFullYear() && d.getMonth() === now.getMonth() && d.getDate() === now.getDate()
|
const timeStr = `${hh}:${mm}`
|
||||||
if (sameDay) return `${hh}:${mm}`
|
|
||||||
const m = String(d.getMonth() + 1).padStart(2, '0')
|
// 计算日期差异(基于日历日期,而非24小时)
|
||||||
const dd = String(d.getDate()).padStart(2, '0')
|
const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate())
|
||||||
return `${m}-${dd} ${hh}:${mm}`
|
const targetStart = new Date(d.getFullYear(), d.getMonth(), d.getDate())
|
||||||
|
const dayDiff = Math.floor((todayStart - targetStart) / (1000 * 60 * 60 * 24))
|
||||||
|
|
||||||
|
// 今天
|
||||||
|
if (dayDiff === 0) {
|
||||||
|
return timeStr
|
||||||
|
}
|
||||||
|
|
||||||
|
// 昨天
|
||||||
|
if (dayDiff === 1) {
|
||||||
|
return `昨天 ${timeStr}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 本周内(2-6天前,显示星期)
|
||||||
|
if (dayDiff >= 2 && dayDiff <= 6) {
|
||||||
|
const weekDays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
|
||||||
|
return `${weekDays[d.getDay()]} ${timeStr}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 本年内
|
||||||
|
const month = d.getMonth() + 1
|
||||||
|
const day = d.getDate()
|
||||||
|
if (d.getFullYear() === now.getFullYear()) {
|
||||||
|
return `${month}月${day}日 ${timeStr}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跨年
|
||||||
|
return `${d.getFullYear()}年${month}月${day}日 ${timeStr}`
|
||||||
} catch {
|
} catch {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formatTimeDivider = (ts) => {
|
||||||
|
return formatSmartTime(ts)
|
||||||
|
}
|
||||||
|
|
||||||
const formatMessageTime = (ts) => {
|
const formatMessageTime = (ts) => {
|
||||||
if (!ts) return ''
|
if (!ts) return ''
|
||||||
try {
|
try {
|
||||||
@@ -672,6 +752,12 @@ const formatTransferAmount = (amount) => {
|
|||||||
return s.replace(/[¥¥]/g, '').trim()
|
return s.replace(/[¥¥]/g, '').trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getRedPacketText = (message) => {
|
||||||
|
const text = String(message?.content ?? '').trim()
|
||||||
|
if (!text || text === '[Red Packet]') return '恭喜发财,大吉大利'
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
|
||||||
// 文件类型图标组件
|
// 文件类型图标组件
|
||||||
const FileIconPdf = defineComponent({
|
const FileIconPdf = defineComponent({
|
||||||
render() {
|
render() {
|
||||||
@@ -845,9 +931,38 @@ const hasMoreMessages = computed(() => {
|
|||||||
// 已移除切换标签逻辑
|
// 已移除切换标签逻辑
|
||||||
|
|
||||||
// 选择联系人
|
// 选择联系人
|
||||||
const selectContact = (contact) => {
|
const selectContact = async (contact, options = {}) => {
|
||||||
|
if (!contact) return
|
||||||
selectedContact.value = contact
|
selectedContact.value = contact
|
||||||
loadMessages({ username: contact.username, reset: true })
|
const username = contact?.username || ''
|
||||||
|
if (!username) return
|
||||||
|
if (options.syncRoute !== false && username) {
|
||||||
|
const current = routeUsername.value || ''
|
||||||
|
if (current !== username) {
|
||||||
|
await navigateTo(buildChatPath(username), { replace: options.replaceRoute !== false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loadMessages({ username, reset: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
const applyRouteSelection = async () => {
|
||||||
|
if (!contacts.value || contacts.value.length === 0) {
|
||||||
|
selectedContact.value = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const requested = routeUsername.value || ''
|
||||||
|
if (requested) {
|
||||||
|
const matched = contacts.value.find((c) => c.username === requested)
|
||||||
|
if (matched) {
|
||||||
|
if (selectedContact.value?.username !== matched.username) {
|
||||||
|
await selectContact(matched, { syncRoute: false })
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await selectContact(contacts.value[0], { syncRoute: true, replaceRoute: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 已移除样式选择逻辑
|
// 已移除样式选择逻辑
|
||||||
@@ -918,9 +1033,7 @@ const loadSessionsForSelectedAccount = async () => {
|
|||||||
messagesError.value = ''
|
messagesError.value = ''
|
||||||
selectedContact.value = null
|
selectedContact.value = null
|
||||||
|
|
||||||
if (contacts.value.length > 0) {
|
await applyRouteSelection()
|
||||||
selectContact(contacts.value[0])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const onAccountChange = async () => {
|
const onAccountChange = async () => {
|
||||||
@@ -1163,6 +1276,15 @@ const refreshSelectedMessages = async () => {
|
|||||||
await loadMessages({ username: selectedContact.value.username, reset: true })
|
await loadMessages({ username: selectedContact.value.username, reset: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
routeUsername,
|
||||||
|
async () => {
|
||||||
|
if (isLoadingContacts.value) return
|
||||||
|
await applyRouteSelection()
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
const autoLoadReady = ref(true)
|
const autoLoadReady = ref(true)
|
||||||
|
|
||||||
const onMessageScroll = async () => {
|
const onMessageScroll = async () => {
|
||||||
@@ -1516,9 +1638,32 @@ const LinkCard = defineComponent({
|
|||||||
color: #1a1a1a;
|
color: #1a1a1a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 统一特殊消息尾巴(红包 / 文件等) */
|
||||||
|
.wechat-special-card {
|
||||||
|
position: relative;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-special-card::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 16px;
|
||||||
|
left: -4px;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background-color: inherit;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-special-sent-side::after {
|
||||||
|
left: auto;
|
||||||
|
right: -4px;
|
||||||
|
}
|
||||||
|
|
||||||
/* 转账消息样式 - 微信风格 */
|
/* 转账消息样式 - 微信风格 */
|
||||||
.wechat-transfer-card {
|
.wechat-transfer-card {
|
||||||
width: 240px;
|
width: 210px;
|
||||||
background: #f79c46;
|
background: #f79c46;
|
||||||
border-radius: var(--message-radius);
|
border-radius: var(--message-radius);
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
@@ -1545,8 +1690,8 @@ const LinkCard = defineComponent({
|
|||||||
.wechat-transfer-content {
|
.wechat-transfer-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 12px 14px;
|
padding: 10px 12px;
|
||||||
min-height: 56px;
|
min-height: 58px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wechat-transfer-icon {
|
.wechat-transfer-icon {
|
||||||
@@ -1583,11 +1728,22 @@ const LinkCard = defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
.wechat-transfer-bottom {
|
.wechat-transfer-bottom {
|
||||||
height: 24px;
|
height: 27px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 14px;
|
padding: 0 12px;
|
||||||
border-top: 1px solid rgba(255,255,255,0.2);
|
border-top: none;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-transfer-bottom::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 13px;
|
||||||
|
right: 13px;
|
||||||
|
height: 1px;
|
||||||
|
background: rgba(255,255,255,0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.wechat-transfer-bottom span {
|
.wechat-transfer-bottom span {
|
||||||
@@ -1633,30 +1789,18 @@ const LinkCard = defineComponent({
|
|||||||
|
|
||||||
/* 红包消息样式 - 微信风格 */
|
/* 红包消息样式 - 微信风格 */
|
||||||
.wechat-redpacket-card {
|
.wechat-redpacket-card {
|
||||||
width: 240px;
|
width: 210px;
|
||||||
background: #fa9d3b;
|
background: #fa9d3b;
|
||||||
border-radius: var(--message-radius);
|
border-radius: var(--message-radius);
|
||||||
overflow: hidden;
|
overflow: visible;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wechat-redpacket-card::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 16px;
|
|
||||||
left: -4px;
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
background: #fa9d3b;
|
|
||||||
transform: rotate(45deg);
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wechat-redpacket-content {
|
.wechat-redpacket-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 12px 14px;
|
padding: 10px 12px;
|
||||||
min-height: 56px;
|
min-height: 58px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wechat-redpacket-icon {
|
.wechat-redpacket-icon {
|
||||||
@@ -1689,11 +1833,22 @@ const LinkCard = defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
.wechat-redpacket-bottom {
|
.wechat-redpacket-bottom {
|
||||||
height: 24px;
|
height: 27px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 14px;
|
padding: 0 12px;
|
||||||
border-top: 1px solid rgba(255,255,255,0.2);
|
border-top: none;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-redpacket-bottom::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 13px;
|
||||||
|
right: 13px;
|
||||||
|
height: 1px;
|
||||||
|
background: rgba(255,255,255,0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.wechat-redpacket-bottom span {
|
.wechat-redpacket-bottom span {
|
||||||
@@ -1706,10 +1861,6 @@ const LinkCard = defineComponent({
|
|||||||
background: #f8e2c6;
|
background: #f8e2c6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wechat-redpacket-received::after {
|
|
||||||
background: #f8e2c6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wechat-redpacket-received .wechat-redpacket-text,
|
.wechat-redpacket-received .wechat-redpacket-text,
|
||||||
.wechat-redpacket-received .wechat-redpacket-status {
|
.wechat-redpacket-received .wechat-redpacket-status {
|
||||||
color: #b88550;
|
color: #b88550;
|
||||||
@@ -1719,6 +1870,85 @@ const LinkCard = defineComponent({
|
|||||||
color: #c9a67a;
|
color: #c9a67a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 文件消息样式 - 基于红包样式覆盖 */
|
||||||
|
.wechat-file-card {
|
||||||
|
width: 210px;
|
||||||
|
background: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-file-card .wechat-redpacket-content {
|
||||||
|
padding: 10px 12px;
|
||||||
|
min-height: 58px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-file-card .wechat-redpacket-bottom {
|
||||||
|
height: 27px;
|
||||||
|
padding: 0 12px;
|
||||||
|
border-top: none;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-file-card .wechat-redpacket-bottom::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 13px;
|
||||||
|
right: 13px;
|
||||||
|
height: 1.5px;
|
||||||
|
background: #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-file-card:hover {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-file-card .wechat-file-info {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-file-name {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #1a1a1a;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
word-break: break-all;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-file-size {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #b2b2b2;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-file-icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-file-bottom {
|
||||||
|
border-top: 1px solid #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-file-bottom span {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #b2b2b2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-file-logo {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
object-fit: contain;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
/* 隐私模式模糊效果 */
|
/* 隐私模式模糊效果 */
|
||||||
.privacy-blur {
|
.privacy-blur {
|
||||||
filter: blur(9px);
|
filter: blur(9px);
|
||||||
Reference in New Issue
Block a user