feat 搭建架构骨架
This commit is contained in:
127
src/views/message/index.vue
Normal file
127
src/views/message/index.vue
Normal file
@@ -0,0 +1,127 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { AppButton, FilterPanel, PaginationBar } from '@/components'
|
||||
// 页面容器:只做组件引入、props 分发、事件中转,数据只经 store
|
||||
import { useMessageStore } from '@/stores/modules/message'
|
||||
import type { MessageType } from '@/types/business/message'
|
||||
import MessageTabs from './cpns/MessageTabs.vue'
|
||||
import MessageList from './cpns/MessageList.vue'
|
||||
|
||||
const router = useRouter()
|
||||
const messageStore = useMessageStore()
|
||||
const { query, list, total, unreadCount, tabCounts } = storeToRefs(messageStore)
|
||||
|
||||
const keyword = computed({
|
||||
get: () => query.value.keyword,
|
||||
set: (value: string) => messageStore.setQuery({ ...query.value, keyword: value }),
|
||||
})
|
||||
|
||||
function onSearch(): void {
|
||||
void messageStore.search()
|
||||
}
|
||||
|
||||
function onReset(): void {
|
||||
void messageStore.resetQuery()
|
||||
}
|
||||
|
||||
function onPageChange(page: number): void {
|
||||
void messageStore.changePage(page)
|
||||
}
|
||||
|
||||
function onTabChange(type: MessageType | 'all'): void {
|
||||
messageStore.setQuery({ ...query.value, type })
|
||||
void messageStore.search()
|
||||
}
|
||||
|
||||
function onView(id: string): void {
|
||||
void router.push(`/message/${id}`)
|
||||
}
|
||||
|
||||
function onMarkAllRead(): void {
|
||||
void messageStore.markAllRead()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void Promise.all([
|
||||
messageStore.fetchList(),
|
||||
messageStore.fetchUnreadCount(),
|
||||
messageStore.fetchTabCounts(),
|
||||
])
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="message">
|
||||
<header class="message__head">
|
||||
<div class="message__head-text">
|
||||
<h1 class="message__title">
|
||||
消息中心
|
||||
</h1>
|
||||
<p class="message__subtitle text-secondary">
|
||||
统一接收项目进度、售后工单、账单待办等站内消息,重要业务动态实时提醒
|
||||
</p>
|
||||
</div>
|
||||
<AppButton
|
||||
type="default"
|
||||
:disabled="unreadCount === 0"
|
||||
@click="onMarkAllRead"
|
||||
>
|
||||
全部已读
|
||||
</AppButton>
|
||||
</header>
|
||||
|
||||
<MessageTabs
|
||||
:active="query.type"
|
||||
:counts="tabCounts"
|
||||
@tab-change="onTabChange"
|
||||
/>
|
||||
|
||||
<FilterPanel
|
||||
v-model:keyword="keyword"
|
||||
keyword-placeholder="搜索消息标题、内容"
|
||||
@search="onSearch"
|
||||
@reset="onReset"
|
||||
/>
|
||||
|
||||
<MessageList :messages="list" @view="onView" />
|
||||
|
||||
<PaginationBar
|
||||
:page="query.page"
|
||||
:page-size="query.pageSize"
|
||||
:total="total"
|
||||
@page-change="onPageChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.message {
|
||||
.flex(column, flex-start);
|
||||
gap: @spacing-base;
|
||||
padding-top: @spacing-xl;
|
||||
padding-bottom: @spacing-xxl;
|
||||
|
||||
&__head {
|
||||
.flex(row, space-between);
|
||||
gap: @spacing-base;
|
||||
}
|
||||
|
||||
&__head-text {
|
||||
.flex(column, flex-start);
|
||||
gap: @spacing-xs;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: @font-size-xxl;
|
||||
font-weight: 600;
|
||||
color: @heading-color;
|
||||
}
|
||||
|
||||
&__subtitle {
|
||||
font-size: @font-size-base;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user