新增统一导航栏组件YjyfNavBar,替换各页面原生导航 新增服务选择抽屉组件GoodsPickerDrawer,实现分类选品流程 新增tabbar图标矢量资源,优化底部导航样式 新增后端运力统计接口与多商品下单逻辑 修复页面跳转逻辑,统一使用switchTab/redirectTo 优化订单创建与评价页的UI组件化,提升一致性
98 行
3.7 KiB
Vue
98 行
3.7 KiB
Vue
<template>
|
||
<view class="page">
|
||
<!-- 统一顶部导航栏(安全距离自适应) -->
|
||
<YjyfNavBar theme="white" title="消息中心" :border="true" />
|
||
<view class="head">
|
||
<view class="cats">
|
||
<view v-for="c in cats" :key="c.key" class="cat" :class="{ on: category === c.key }" @tap="switchCat(c.key)">{{ c.name }}</view>
|
||
</view>
|
||
<text class="read-all" @tap="readAll">全部已读</text>
|
||
</view>
|
||
|
||
<view class="list">
|
||
<view class="msg" :class="{ unread: !m.is_read }" v-for="m in list" :key="m.id" @tap="open(m)">
|
||
<view class="msg-top">
|
||
<view class="dot" v-if="!m.is_read"></view>
|
||
<text class="title">{{ m.title }}</text>
|
||
<text class="time">{{ m.time_text }}</text>
|
||
</view>
|
||
<text class="content">{{ m.content }}</text>
|
||
<text class="go" v-if="m.order_id">查看订单 ›</text>
|
||
</view>
|
||
<view class="empty" v-if="!loading && !list.length">暂无消息</view>
|
||
</view>
|
||
<YjyfTabBar :current="2" />
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref } from 'vue';
|
||
import YjyfTabBar from '@/components/YjyfTabBar.vue';
|
||
import { onShow, onPullDownRefresh } from '@dcloudio/uni-app';
|
||
import api from '@/utils/api.js';
|
||
import { isLogin, toLogin } from '@/utils/request.js';
|
||
|
||
const list = ref([]);
|
||
const loading = ref(false);
|
||
const category = ref('all');
|
||
const cats = [
|
||
{ key: 'all', name: '全部' },
|
||
{ key: 'order', name: '订单' },
|
||
{ key: 'system', name: '系统' },
|
||
{ key: 'remind', name: '提醒' }
|
||
];
|
||
|
||
async function load() {
|
||
if (!isLogin()) { toLogin(); return; }
|
||
loading.value = true;
|
||
try {
|
||
const res = await api.messageList({ category: category.value, limit: 30 });
|
||
list.value = res.list || [];
|
||
} catch (e) {
|
||
} finally {
|
||
loading.value = false;
|
||
}
|
||
}
|
||
|
||
function switchCat(k) { category.value = k; load(); }
|
||
|
||
async function open(m) {
|
||
if (!m.is_read) {
|
||
try { await api.messageRead({ id: m.id }); m.is_read = 1; } catch (e) {}
|
||
}
|
||
if (m.order_id) {
|
||
uni.navigateTo({ url: '/pages/order/detail?id=' + m.order_id });
|
||
}
|
||
}
|
||
|
||
async function readAll() {
|
||
try {
|
||
const res = await api.messageReadAll({});
|
||
uni.showToast({ title: '已全部标记已读(' + res.count + ' 条)', icon: 'none' });
|
||
load();
|
||
} catch (e) {}
|
||
}
|
||
|
||
onShow(() => load());
|
||
onPullDownRefresh(() => { load().then(() => uni.stopPullDownRefresh()); });
|
||
</script>
|
||
|
||
<style scoped>
|
||
.page { min-height: 100vh; background: #F5F6F8; padding-bottom: 40rpx; }
|
||
.head { display: flex; align-items: center; background: #fff; padding: 20rpx 24rpx; box-shadow: 0 4rpx 12rpx rgba(0,0,0,.03); }
|
||
.cats { flex: 1; display: flex; }
|
||
.cat { margin-right: 14rpx; padding: 0 22rpx; line-height: 54rpx; border-radius: 27rpx; background: #F5F5F5; font-size: 24rpx; color: #666; }
|
||
.cat.on { background: #FFF3E6; color: #E36B0C; font-weight: 600; }
|
||
.read-all { font-size: 24rpx; color: #F0710D; }
|
||
.list { padding: 22rpx 28rpx; }
|
||
.msg { background: #fff; border-radius: 20rpx; padding: 22rpx 24rpx; margin-bottom: 18rpx; box-shadow: 0 6rpx 20rpx rgba(240,129,31,.06); }
|
||
.msg.unread { border-left: 6rpx solid #F0710D; }
|
||
.msg-top { display: flex; align-items: center; }
|
||
.dot { width: 12rpx; height: 12rpx; border-radius: 50%; background: #F0710D; margin-right: 10rpx; }
|
||
.title { flex: 1; min-width: 0; font-size: 28rpx; font-weight: 600; color: #1F1F1F; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
|
||
.time { flex-shrink: 0; margin-left: 12rpx; font-size: 22rpx; color: #AAAAAA; }
|
||
.content { display: block; margin-top: 10rpx; font-size: 24rpx; color: #666; line-height: 34rpx; }
|
||
.go { display: block; margin-top: 10rpx; font-size: 22rpx; color: #4A7CFF; }
|
||
.empty { padding: 110rpx 0; text-align: center; font-size: 24rpx; color: #9A9A9A; }
|
||
</style>
|