大量的代码格式化
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Failing after 1m10s
Docker Build & Deploy / Deploy to Production (push) Has been skipped
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s

This commit is contained in:
孙诚
2026-01-16 11:15:44 +08:00
parent 9069e3dbcf
commit 319f8f7d7b
54 changed files with 2973 additions and 2200 deletions

View File

@@ -1,18 +1,34 @@
<!-- eslint-disable vue/no-v-html -->
<template>
<div class="page-container-flex">
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<van-pull-refresh
v-model="refreshing"
@refresh="onRefresh"
>
<van-list
v-model:loading="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
>
<van-cell-group v-if="list.length" inset style="margin-top: 10px">
<van-swipe-cell v-for="item in list" :key="item.id">
<div class="message-card" @click="viewDetail(item)">
<van-cell-group
v-if="list.length"
inset
style="margin-top: 10px"
>
<van-swipe-cell
v-for="item in list"
:key="item.id"
>
<div
class="message-card"
@click="viewDetail(item)"
>
<div class="card-left">
<div class="message-title" :class="{ 'unread': !item.isRead }">
<div
class="message-title"
:class="{ unread: !item.isRead }"
>
{{ item.title }}
</div>
<div class="message-content">
@@ -23,16 +39,34 @@
</div>
</div>
<div class="card-right">
<van-tag v-if="!item.isRead" type="danger">未读</van-tag>
<van-icon name="arrow" size="16" class="arrow-icon" />
<van-tag
v-if="!item.isRead"
type="danger"
>
未读
</van-tag>
<van-icon
name="arrow"
size="16"
class="arrow-icon"
/>
</div>
</div>
<template #right>
<van-button square text="删除" type="danger" class="delete-button" @click="handleDelete(item)" />
<van-button
square
text="删除"
type="danger"
class="delete-button"
@click="handleDelete(item)"
/>
</template>
</van-swipe-cell>
</van-cell-group>
<van-empty v-else-if="!loading" description="暂无消息" />
<van-empty
v-else-if="!loading"
description="暂无消息"
/>
</van-list>
</van-pull-refresh>
@@ -44,16 +78,26 @@
height="75%"
>
<div
v-if="currentMessage.messageType === 2"
class="detail-content rich-html-content"
v-if="currentMessage.messageType === 2"
class="detail-content rich-html-content"
v-html="currentMessage.content"
/>
<div
v-else
class="detail-content"
>
</div>
<div v-else class="detail-content">
{{ currentMessage.content }}
</div>
<template v-if="currentMessage.url && currentMessage.messageType === 1" #footer>
<van-button type="primary" block round @click="handleUrlJump(currentMessage.url)">
<template
v-if="currentMessage.url && currentMessage.messageType === 1"
#footer
>
<van-button
type="primary"
block
round
@click="handleUrlJump(currentMessage.url)"
>
查看详情
</van-button>
</template>
@@ -62,164 +106,166 @@
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { showToast, showDialog } from 'vant';
import { getMessageList, markAsRead, deleteMessage, markAllAsRead } from '@/api/message';
import { useMessageStore } from '@/stores/message';
import PopupContainer from '@/components/PopupContainer.vue';
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { showToast, showDialog } from 'vant'
import { getMessageList, markAsRead, deleteMessage, markAllAsRead } from '@/api/message'
import { useMessageStore } from '@/stores/message'
import PopupContainer from '@/components/PopupContainer.vue'
const messageStore = useMessageStore();
const router = useRouter();
const list = ref([]);
const loading = ref(false);
const finished = ref(false);
const refreshing = ref(false);
const pageIndex = ref(1);
const pageSize = ref(20);
const messageStore = useMessageStore()
const router = useRouter()
const list = ref([])
const loading = ref(false)
const finished = ref(false)
const refreshing = ref(false)
const pageIndex = ref(1)
const pageSize = ref(20)
const detailVisible = ref(false);
const currentMessage = ref({});
const detailVisible = ref(false)
const currentMessage = ref({})
const onLoad = async () => {
if (refreshing.value) {
list.value = [];
pageIndex.value = 1;
refreshing.value = false;
list.value = []
pageIndex.value = 1
refreshing.value = false
}
try {
const res = await getMessageList({
pageIndex: pageIndex.value,
pageSize: pageSize.value
});
})
if (res.success) {
// 格式化时间
const data = res.data.map(item => ({
const data = res.data.map((item) => ({
...item,
createTime: new Date(item.createTime).toLocaleString()
}));
}))
if (pageIndex.value === 1) {
list.value = data;
list.value = data
} else {
list.value = [...list.value, ...data];
list.value = [...list.value, ...data]
}
// 判断是否加载完成
if (list.value.length >= res.total || data.length < pageSize.value) {
finished.value = true;
finished.value = true
} else {
pageIndex.value++;
pageIndex.value++
}
} else {
showToast(res.message || '加载失败');
finished.value = true;
showToast(res.message || '加载失败')
finished.value = true
}
} catch (error) {
console.error(error);
showToast('加载失败');
finished.value = true;
console.error(error)
showToast('加载失败')
finished.value = true
} finally {
loading.value = false;
loading.value = false
}
};
}
const onRefresh = () => {
finished.value = false;
loading.value = true;
onLoad();
};
finished.value = false
loading.value = true
onLoad()
}
const viewDetail = async (item) => {
if (!item.isRead) {
try {
await markAsRead(item.id);
item.isRead = true;
messageStore.updateUnreadCount();
await markAsRead(item.id)
item.isRead = true
messageStore.updateUnreadCount()
} catch (error) {
console.error('标记已读失败', error);
console.error('标记已读失败', error)
}
}
currentMessage.value = item;
detailVisible.value = true;
};
currentMessage.value = item
detailVisible.value = true
}
const handleUrlJump = (targetUrl) => {
if (!targetUrl) return;
if (targetUrl.startsWith('http')) {
window.open(targetUrl, '_blank');
} else if (targetUrl.startsWith('/')) {
router.push(targetUrl);
detailVisible.value = false;
} else {
showToast('无效的URL');
if (!targetUrl) {
return
}
};
if (targetUrl.startsWith('http')) {
window.open(targetUrl, '_blank')
} else if (targetUrl.startsWith('/')) {
router.push(targetUrl)
detailVisible.value = false
} else {
showToast('无效的URL')
}
}
const handleDelete = (item) => {
showDialog({
title: '提示',
message: '确定要删除这条消息吗?',
showCancelButton: true,
showCancelButton: true
}).then(async (action) => {
if (action === 'confirm') {
try {
const res = await deleteMessage(item.id);
const res = await deleteMessage(item.id)
if (res.success) {
showToast('删除成功');
const wasUnread = !item.isRead;
list.value = list.value.filter(i => i.id !== item.id);
showToast('删除成功')
const wasUnread = !item.isRead
list.value = list.value.filter((i) => i.id !== item.id)
if (wasUnread) {
messageStore.updateUnreadCount();
messageStore.updateUnreadCount()
}
} else {
showToast(res.message || '删除失败');
showToast(res.message || '删除失败')
}
} catch (error) {
console.error('删除消息失败', error);
showToast('删除失败');
console.error('删除消息失败', error)
showToast('删除失败')
}
}
});
};
})
}
const handleMarkAllRead = () => {
showDialog({
title: '提示',
message: '确定要将所有消息标记为已读吗?',
showCancelButton: true,
showCancelButton: true
}).then(async (action) => {
if (action === 'confirm') {
try {
const res = await markAllAsRead();
const res = await markAllAsRead()
if (res.success) {
showToast('操作成功');
showToast('操作成功')
// 刷新列表
onRefresh();
onRefresh()
// 更新未读计数
messageStore.updateUnreadCount();
messageStore.updateUnreadCount()
} else {
showToast(res.message || '操作失败');
showToast(res.message || '操作失败')
}
} catch (error) {
console.error('标记所有已读失败', error);
showToast('操作失败');
console.error('标记所有已读失败', error)
showToast('操作失败')
}
}
});
};
})
}
onMounted(() => {
// onLoad 会由 van-list 自动触发
});
})
defineExpose({
handleMarkAllRead
});
})
</script>
<style scoped>
@@ -257,7 +303,7 @@ defineExpose({
white-space: nowrap;
}
.message-content{
.message-content {
font-size: 14px;
color: var(--van-text-color-2);
margin-bottom: 6px;
@@ -305,4 +351,4 @@ defineExpose({
:deep(.van-nav-bar) {
background: transparent !important;
}
</style>
</style>