Files
airz-uniapp/packages/account/messages/messages.uvue
T
hujun 4a69357606 feat: add account profile, search, help and security features
1. add default avatar and multiple notification icons
2. update finance archive note and add form styles
3. add new pages: edit-profile, security, password, change-phone, search, help
4. refactor navigation action layout to support multiple actions
5. add search button to home page
6. add security code component and account service APIs
7. add help and search content services
8. update message notice to use svg icons
9. update asset section in finance assessment
10. update manifest appid and pack options
2026-09-21 15:04:59 +08:00

86 lines
6.9 KiB
Plaintext

<template>
<view class="page" :style="pageStyle()">
<AppHeader title="消息中心" :back="false" />
<view class="message-tabs"><view v-for="item in tabs" :key="item" :class="tab == item ? 'message-tab active-tab' : 'message-tab'" @click="tab = item"><text :class="tab == item ? 'tab-text active-text' : 'tab-text'">{{ item }}</text></view></view>
<scroll-view scroll-y :style="contentStyle(314, false)">
<view class="messages-content">
<view class="message-summary"><text class="summary-text">{{ unreadCount > 0 ? unreadCount + ' 条未读消息' : '消息已全部阅读' }}</text><view class="read-all" @click="markAllRead"><text class="read-all-text">全部已读</text></view></view>
<view class="notice-list">
<view class="notice" v-for="(item, index) in filteredNotices" :key="item.id" :class="index == filteredNotices.length - 1 ? 'last-notice' : ''" @click="openNotice(item)">
<view class="notice-icon" :class="'notice-icon-' + item.icon"><view class="notice-icon-surface"><image class="notice-symbol" :src="'/packages/account/static/notifications/' + item.icon + '.svg'" mode="aspectFit" /></view><view v-if="item.unread" class="unread"></view></view>
<view class="notice-copy"><view class="notice-head"><text class="notice-title">{{ item.title }}</text><text class="notice-time">{{ item.time }}</text></view><text class="notice-desc">{{ item.desc }}</text><text class="notice-category">{{ item.category }}</text></view>
</view>
</view>
<text class="message-footer">点击消息查看完整内容</text>
</view>
</scroll-view>
<BottomNav active="message" />
</view>
</template>
<script setup lang="uts">
import { usePageLayout } from '@/services/layout.uts'
import AppHeader from '@/components/AppHeader.uvue'
import BottomNav from '@/components/BottomNav.uvue'
const { contentStyle, pageStyle } = usePageLayout()
const tabs: string[] = ['全部', '系统通知', '服务通知', '活动消息']
const tab = ref('全部')
type Notice = { id: string, icon: string, category: string, title: string, desc: string, body: string, time: string, unread: boolean }
const notices = ref<Notice[]>([
{ id: 'assessment-guide', icon: 'approval', category: '服务通知', title: '融资评估使用指南', desc: '完成资料填写,了解自己的融资需求。', body: '从首页选择个人或企业融资入口,按步骤填写基本信息、经营或收入、资产与负债情况。提交前请核对资料,评估结果仅供参考,具体申请条件以机构审核为准。', time: '10:30', unread: true },
{ id: 'repayment-guide', icon: 'payout', category: '服务通知', title: '还款安排提醒', desc: '申请前,记得核对每期应还金额与日期。', body: '比较融资方案时,除利率外还应核对还款方式、每期应还金额与到期本金。正式签约后,请以机构提供的合同和还款计划为准,通过官方渠道查询账户状态。', time: '09:15', unread: false },
{ id: 'invite-guide', icon: 'gift', category: '活动消息', title: '邀请积分说明', desc: '邀请前先了解积分规则与适用范围。', body: '可在积分中心查看邀请入口与积分说明。积分发放条件、有效期及可用权益以活动页面公布的规则为准,请勿向他人承诺固定收益或贷款结果。', time: '08:42', unread: false },
{ id: 'privacy-guide', icon: 'system-bell', category: '系统通知', title: '个人信息保护提醒', desc: '留意授权范围,保护账号与验证码。', body: '提交资料或授权数据前,请阅读相应说明,确认使用目的、数据范围和授权期限。不要向他人泄露账户密码、短信验证码或银行支付信息。', time: '昨天', unread: false }
])
const filteredNotices = computed((): Notice[] => tab.value == '全部' ? notices.value : notices.value.filter((item: Notice): boolean => item.category == tab.value))
const unreadCount = computed((): number => notices.value.filter((item: Notice): boolean => item.unread).length)
onShow(() => {
notices.value.forEach((item: Notice): void => {
if (uni.getStorageSync('finance.notice.read.' + item.id) == true) item.unread = false
})
})
const markRead = (id: string): void => {
const item = notices.value.find((value: Notice): boolean => value.id == id)
if (item == null) return
item.unread = false
uni.setStorageSync('finance.notice.read.' + id, true)
}
const openNotice = (item: Notice): void => {
markRead(item.id)
uni.showModal({ title: item.title, content: item.body, showCancel: false, confirmText: '知道了' })
}
const markAllRead = (): void => {
notices.value.forEach((item: Notice): void => { markRead(item.id) })
}
</script>
<style>
.message-tabs { height: 88rpx; flex-direction: row; background-color: #ffffff; border-bottom: 1rpx solid #e8eef6; padding: 0 18rpx; }
.message-tab { flex: 1; align-items: center; justify-content: center; border-bottom: 4rpx solid transparent; }
.active-tab { border-bottom-color: #0868f7; }
.tab-text { color: #66758a; font-size: 25rpx; }
.active-text { color: #0868f7; font-weight: 700; }
.messages-content { padding: 14rpx 28rpx 90rpx; }
.message-summary { flex-direction: row; align-items: center; justify-content: space-between; min-height: 66rpx; }
.summary-text { color: #66758a; font-size: 23rpx; }
.read-all { padding: 14rpx 0 14rpx 24rpx; }
.read-all-text { color: #0868f7; font-size: 23rpx; }
.notice-list { background-color: #ffffff; border-radius: 18rpx; padding: 0 20rpx; }
.notice { padding: 26rpx 0; border-bottom: 1rpx solid #e8eef6; flex-direction: row; align-items: center; }
.last-notice { border-bottom-width: 0; }
.notice-icon { width: 76rpx; height: 76rpx; margin-right: 20rpx; position: relative; flex-shrink: 0; }
.notice-icon-surface { width: 100%; height: 100%; border-radius: 20rpx; background-color: #edf5ff; align-items: center; justify-content: center; }
.notice-icon-payout .notice-icon-surface { background-color: #eaf7f3; }
.notice-icon-gift .notice-icon-surface { background-color: #fff3e8; }
.notice-symbol { width: 46rpx; height: 46rpx; flex-shrink: 0; }
.notice-copy { flex: 1; min-width: 0; }
.notice-head { flex-direction: row; justify-content: space-between; align-items: flex-start; }
.notice-title { color: #172640; font-size: 28rpx; line-height: 40rpx; font-weight: 600; flex: 1; }
.notice-time { color: #66758a; font-size: 22rpx; line-height: 40rpx; margin-left: 12rpx; flex-shrink: 0; }
.notice-desc { color: #66758a; font-size: 25rpx; line-height: 38rpx; margin-top: 10rpx; }
.notice-category { color: #66758a; font-size: 22rpx; line-height: 32rpx; margin-top: 10rpx; }
/* 红点独立于圆角背景,避免跨端圆角裁切。 */
.unread { position: absolute; width: 15rpx; height: 15rpx; border-radius: 8rpx; background-color: #f04452; border: 2rpx solid #ffffff; right: -3rpx; top: -3rpx; z-index: 1; }
.message-footer { color: #66758a; font-size: 22rpx; text-align: center; margin-top: 28rpx; }
</style>