|
@@ -1,6 +1,7 @@
|
|
|
<route lang="json5" type="page">
|
|
|
{
|
|
|
layout: 'default',
|
|
|
+ needLogin: true,
|
|
|
style: {
|
|
|
navigationBarTitleText: '%notifications.title%',
|
|
|
navigationBarBackgroundColor: '#fff',
|
|
@@ -9,10 +10,14 @@
|
|
|
</route>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-// 必须导入需要用到的页面生命周期(即使在当前页面上没有直接使用到)
|
|
|
// eslint-disable-next-line unused-imports/no-unused-imports
|
|
|
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
|
|
|
import useZPaging from 'z-paging/components/z-paging/js/hooks/useZPaging.js'
|
|
|
+// 必须导入需要用到的页面生命周期(即使在当前页面上没有直接使用到)
|
|
|
+
|
|
|
+import { noticeDel, noticeList, noticeRead } from '@/api/common'
|
|
|
+import { t } from '@/locale'
|
|
|
+import { toPage } from '@/utils/page'
|
|
|
|
|
|
defineOptions({
|
|
|
name: 'Notifications', // 通知
|
|
@@ -22,125 +27,254 @@ const paging = ref(null)
|
|
|
// 类似mixins,如果是页面滚动务必要写这一行,并传入当前ref绑定的paging,注意此处是paging,而非paging.value
|
|
|
useZPaging(paging)
|
|
|
|
|
|
-const tab = ref<number>(0)
|
|
|
+const tab = ref<string>('ALL')
|
|
|
+const tabs = [
|
|
|
+ { title: t('notifications.tabs.all'), value: 'ALL' },
|
|
|
+ { title: t('notifications.tabs.orders'), value: 'ORDER' },
|
|
|
+ { title: t('notifications.tabs.revenue'), value: 'REWARD' },
|
|
|
+ { title: t('notifications.tabs.account'), value: 'MONEY' },
|
|
|
+ { title: t('notifications.tabs.promos'), value: 'OTHER' },
|
|
|
+]
|
|
|
+
|
|
|
+const typeMap = {
|
|
|
+ order: ['ORDER_GROUP_BUY_PAYMENT_SUCCESS', 'ORDER_GROUP_BUY_SUCCESS_WIN', 'ORDER_GROUP_BUY_SUCCESS_LOSE', 'ORDER_PROVIDE_SHIPPING_ADDRESS', 'ORDER_GROUP_BUY_FAIL', 'ORDER_SHIPPED_SUCCESS'],
|
|
|
+ income: ['REWARD_REFER_FRIENDS', 'REWARD_GROUP_BUY', 'REWARD_DIRECT_REFERRAL', 'REWARD_CHECKIN'],
|
|
|
+ wallet: ['MONEY_RECHARGE_SUCCESS', 'MONEY_WITHDRAWAL_ACCOUNT_SUCCESS', 'MONEY_WITHDRAWAL_WALLET_SUCCESS', 'MONEY_WITHDRAWAL_FAIL'],
|
|
|
+ other: ['OTHER'],
|
|
|
+}
|
|
|
+
|
|
|
+const contentTypeMap = {
|
|
|
+ ORDER_GROUP_BUY_PAYMENT_SUCCESS: {
|
|
|
+ titleKey: 'notifications.order.paymentSuccess.title',
|
|
|
+ contentKey: 'notifications.order.paymentSuccess.content',
|
|
|
+ link: '/pages/myOrders/orderDetail',
|
|
|
+ },
|
|
|
+ ORDER_GROUP_BUY_SUCCESS_WIN: {
|
|
|
+ titleKey: 'notifications.order.groupBuyWin.title',
|
|
|
+ contentKey: 'notifications.order.groupBuyWin.content',
|
|
|
+ link: '/pages/myOrders/orderDetail',
|
|
|
+ },
|
|
|
+ ORDER_GROUP_BUY_SUCCESS_LOSE: {
|
|
|
+ titleKey: 'notifications.order.groupBuyLose.title',
|
|
|
+ contentKey: 'notifications.order.groupBuyLose.content',
|
|
|
+ link: '/pages/myOrders/orderDetail',
|
|
|
+ },
|
|
|
+ ORDER_PROVIDE_SHIPPING_ADDRESS: {
|
|
|
+ titleKey: 'notifications.order.provideAddress.title',
|
|
|
+ contentKey: 'notifications.order.provideAddress.content',
|
|
|
+ link: '/pages/myOrders/orderDetail',
|
|
|
+ },
|
|
|
+ ORDER_GROUP_BUY_FAIL: {
|
|
|
+ titleKey: 'notifications.order.groupBuyFail.title',
|
|
|
+ contentKey: 'notifications.order.groupBuyFail.content',
|
|
|
+ link: '/pages/myOrders/orderDetail',
|
|
|
+ },
|
|
|
+ ORDER_SHIPPED_SUCCESS: {
|
|
|
+ titleKey: 'notifications.order.shipped.title',
|
|
|
+ contentKey: 'notifications.order.shipped.content',
|
|
|
+ link: '/pages/myOrders/orderDetail',
|
|
|
+ },
|
|
|
+ REWARD_REFER_FRIENDS: {
|
|
|
+ titleKey: 'notifications.reward.referFriends.title',
|
|
|
+ contentKey: 'notifications.reward.referFriends.content',
|
|
|
+ link: '/pages/income/income',
|
|
|
+ },
|
|
|
+ REWARD_GROUP_BUY: {
|
|
|
+ titleKey: 'notifications.reward.groupBuy.title',
|
|
|
+ contentKey: 'notifications.reward.groupBuy.content',
|
|
|
+ link: '/pages/income/income',
|
|
|
+ },
|
|
|
+ REWARD_DIRECT_REFERRAL: {
|
|
|
+ titleKey: 'notifications.reward.directReferral.title',
|
|
|
+ contentKey: 'notifications.reward.directReferral.content',
|
|
|
+ link: '/pages/income/income',
|
|
|
+ },
|
|
|
+ REWARD_CHECKIN: {
|
|
|
+ titleKey: 'notifications.reward.checkin.title',
|
|
|
+ contentKey: 'notifications.reward.checkin.content',
|
|
|
+ link: '/pages/income/income',
|
|
|
+ },
|
|
|
+ MONEY_RECHARGE_SUCCESS: {
|
|
|
+ titleKey: 'notifications.money.rechargeSuccess.title',
|
|
|
+ contentKey: 'notifications.money.rechargeSuccess.content',
|
|
|
+ link: '/pages/wallet/myWallet',
|
|
|
+ },
|
|
|
+ MONEY_WITHDRAWAL_ACCOUNT_SUCCESS: {
|
|
|
+ titleKey: 'notifications.money.withdrawalAccountSuccess.title',
|
|
|
+ contentKey: 'notifications.money.withdrawalAccountSuccess.content',
|
|
|
+ link: '/pages/wallet/withdrawRecord?params=%257B%2522type%2522%253A2%257D',
|
|
|
+ },
|
|
|
+ MONEY_WITHDRAWAL_WALLET_SUCCESS: {
|
|
|
+ titleKey: 'notifications.money.withdrawalWalletSuccess.title',
|
|
|
+ contentKey: 'notifications.money.withdrawalWalletSuccess.content',
|
|
|
+ link: '/pages/wallet/withdrawRecord?params=%257B%2522type%2522%253A2%257D',
|
|
|
+ },
|
|
|
+ MONEY_WITHDRAWAL_FAIL: {
|
|
|
+ titleKey: 'notifications.money.withdrawalFail.title',
|
|
|
+ contentKey: 'notifications.money.withdrawalFail.content',
|
|
|
+ link: '/pages/wallet/withdrawRecord?params=%257B%2522type%2522%253A2%257D',
|
|
|
+ },
|
|
|
+}
|
|
|
+
|
|
|
+// 获取通知标题
|
|
|
+function getNoticeTitle(item: any) {
|
|
|
+ if (item.noticeType === 'OTHER') {
|
|
|
+ return item.noticeTitle
|
|
|
+ }
|
|
|
+ const config = contentTypeMap[item.noticeType]
|
|
|
+ if (config) {
|
|
|
+ return t(config.titleKey)
|
|
|
+ }
|
|
|
+ return item.noticeTitle || ''
|
|
|
+}
|
|
|
+
|
|
|
+// 获取通知内容
|
|
|
+function getNoticeContent(item: any) {
|
|
|
+ if (item.noticeType === 'OTHER') {
|
|
|
+ return item.noticeMessage
|
|
|
+ }
|
|
|
+ const config = contentTypeMap[item.noticeType]
|
|
|
+ if (config) {
|
|
|
+ // 如果有订单号等动态数据,从item中提取
|
|
|
+ const dynamicData = item.noticeMessage
|
|
|
+ return t(config.contentKey, { orderId: dynamicData })
|
|
|
+ }
|
|
|
+ return item.noticeMessage || ''
|
|
|
+}
|
|
|
+
|
|
|
+// 根据通知类型获取对应图标
|
|
|
+function getNoticeIcon(type: string) {
|
|
|
+ for (const [key, types] of Object.entries(typeMap)) {
|
|
|
+ if (types.includes(type))
|
|
|
+ return `/static/icons/msg-${key}.png`
|
|
|
+ }
|
|
|
+ return '/static/icons/msg-other.png'
|
|
|
+}
|
|
|
|
|
|
-// 搜索结果
|
|
|
const dataList = ref([])
|
|
|
-function queryList(pageNo, pageSize) {
|
|
|
- // 此处请求仅为演示,请替换为自己项目中的请求
|
|
|
- setTimeout(() => {
|
|
|
- dataList.value = [
|
|
|
- { title: '123' },
|
|
|
- { title: '123' },
|
|
|
- { title: '123' },
|
|
|
- { title: '12345' },
|
|
|
- ]
|
|
|
- paging.value.complete(dataList.value)
|
|
|
- }, 1000)
|
|
|
+async function queryList(pageNo: number, pageSize: number) {
|
|
|
+ try {
|
|
|
+ const res = await noticeList({
|
|
|
+ page: pageNo,
|
|
|
+ size: pageSize,
|
|
|
+ type: tab.value === 'ALL' ? null : tab.value,
|
|
|
+ })
|
|
|
+ if (res.code === '200') {
|
|
|
+ paging.value.complete(res.data.records)
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ paging.value.complete(false)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch {
|
|
|
+ paging.value.complete(false)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 处理通知点击
|
|
|
+function handleNoticeClick(item: any) {
|
|
|
+ item.readFlag = true
|
|
|
+ noticeRead(item.id)
|
|
|
+ if (item.noticeType === 'OTHER') {
|
|
|
+ // OTHER 类型使用 page 字段和 toPage 方法跳转
|
|
|
+ const page = item.pages
|
|
|
+ if (page) {
|
|
|
+ toPage(page)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // 其他类型使用 contentTypeMap 中的 link 字段,也使用 toPage 方法
|
|
|
+ const config = contentTypeMap[item.noticeType]
|
|
|
+ const link = config?.link
|
|
|
+ if (link) {
|
|
|
+ toPage(link, typeMap.order.includes(item.noticeType) ? { id: item.noticeMessage } : {})
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 处理滑动操作
|
|
|
+async function handleAction(action: string, item: any) {
|
|
|
+ if (action === 'del') {
|
|
|
+ // 删除通知
|
|
|
+ const res = await noticeDel(item.id)
|
|
|
+ if (res.code === '200') {
|
|
|
+ paging.value.reload()
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
- <wd-tabs v-model="tab" swipeable sticky custom-class="bg-transparent!">
|
|
|
- <wd-tab :title="$t('notifications.tab1')">
|
|
|
- <z-paging ref="paging" use-page-scroll refresher-only @query="queryList">
|
|
|
- <view class="py-20rpx">
|
|
|
- <view class="bg-white px-22rpx py-18rpx">
|
|
|
- <view class="mb-8rpx flex items-center justify-between">
|
|
|
- <view class="flex items-center">
|
|
|
- <wd-icon name="view-module" size="36rpx" />
|
|
|
- <text class="ml-8rpx text-24rpx font-bold">
|
|
|
- {{ $t('notifications.orderPayment.title') }}
|
|
|
- </text>
|
|
|
- </view>
|
|
|
- <text class="text-22rpx text-#3A444C">
|
|
|
- 12:30
|
|
|
+ <z-paging ref="paging" v-model="dataList" use-page-scroll @query="queryList">
|
|
|
+ <template #top>
|
|
|
+ <wd-tabs v-model="tab" custom-class="bg-transparent!" @click="() => queryList(1, 20)">
|
|
|
+ <wd-tab v-for="tabItem in tabs" :key="tabItem.value" :name="tabItem.value" :title="tabItem.title" />
|
|
|
+ </wd-tabs>
|
|
|
+ </template>
|
|
|
+ <view class="py-20rpx">
|
|
|
+ <wd-swipe-action v-for="item in dataList" :key="item.id" class="mb-20rpx">
|
|
|
+ <view
|
|
|
+ class="bg-white px-22rpx py-18rpx"
|
|
|
+ :class="{ 'notification-read': item.readFlag }"
|
|
|
+ @click="handleNoticeClick(item)"
|
|
|
+ >
|
|
|
+ <view class="mb-8rpx flex items-center justify-between">
|
|
|
+ <view class="flex items-center">
|
|
|
+ <image
|
|
|
+ :src="getNoticeIcon(item.noticeType)"
|
|
|
+ class="h-36rpx w-36rpx"
|
|
|
+ :class="{ 'opacity-60': item.readFlag }"
|
|
|
+ />
|
|
|
+ <text
|
|
|
+ class="ml-8rpx text-24rpx font-bold"
|
|
|
+ :class="item.readFlag ? 'text-#999999' : 'text-#333333'"
|
|
|
+ >
|
|
|
+ {{ getNoticeTitle(item) }}
|
|
|
</text>
|
|
|
</view>
|
|
|
- <view class="flex items-center text-22rpx text-#3A444C">
|
|
|
- <view class="truncate">
|
|
|
- {{ $t('notifications.orderPayment.content', ['20250505123030120']) }}
|
|
|
- </view>
|
|
|
- </view>
|
|
|
+ <text
|
|
|
+ class="text-22rpx"
|
|
|
+ :class="item.readFlag ? 'text-#CCCCCC' : 'text-#3A444C'"
|
|
|
+ >
|
|
|
+ {{ item.createTime }}
|
|
|
+ </text>
|
|
|
</view>
|
|
|
- </view>
|
|
|
- </z-paging>
|
|
|
- </wd-tab>
|
|
|
- <wd-tab :title="$t('notifications.tab2')">
|
|
|
- <z-paging ref="paging" refresher-only use-page-scroll @query="queryList">
|
|
|
- <view class="py-20rpx">
|
|
|
- <view class="bg-white px-22rpx py-18rpx">
|
|
|
- <view class="mb-8rpx flex items-center justify-between">
|
|
|
- <view class="flex items-center">
|
|
|
- <wd-icon name="view-module" size="36rpx" />
|
|
|
- <text class="ml-8rpx text-24rpx font-bold">
|
|
|
- {{ $t('notifications.orderPayment.title') }}
|
|
|
- </text>
|
|
|
- </view>
|
|
|
- <text class="text-22rpx text-#3A444C">
|
|
|
- 12:30
|
|
|
- </text>
|
|
|
- </view>
|
|
|
- <view class="flex items-center text-22rpx text-#3A444C">
|
|
|
- <view class="truncate">
|
|
|
- {{ $t('notifications.orderPayment.content', ['20250505123030120']) }}
|
|
|
- </view>
|
|
|
+ <view class="flex items-center text-22rpx">
|
|
|
+ <view
|
|
|
+ class="truncate"
|
|
|
+ :class="item.readFlag ? 'text-#BBBBBB' : 'text-#3A444C'"
|
|
|
+ >
|
|
|
+ {{ getNoticeContent(item) }}
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
- </z-paging>
|
|
|
- </wd-tab>
|
|
|
- <wd-tab :title="$t('notifications.tab3')">
|
|
|
- <z-paging ref="paging" refresher-only use-page-scroll @query="queryList">
|
|
|
- <view class="py-20rpx">
|
|
|
- <view class="bg-white px-22rpx py-18rpx">
|
|
|
- <view class="mb-8rpx flex items-center justify-between">
|
|
|
- <view class="flex items-center">
|
|
|
- <wd-icon name="view-module" size="36rpx" />
|
|
|
- <text class="ml-8rpx text-24rpx font-bold">
|
|
|
- {{ $t('notifications.orderPayment.title') }}
|
|
|
- </text>
|
|
|
- </view>
|
|
|
- <text class="text-22rpx text-#3A444C">
|
|
|
- 12:30
|
|
|
- </text>
|
|
|
- </view>
|
|
|
- <view class="flex items-center text-22rpx text-#3A444C">
|
|
|
- <view class="truncate">
|
|
|
- {{ $t('notifications.orderPayment.content', ['20250505123030120']) }}
|
|
|
- </view>
|
|
|
+ <template #right>
|
|
|
+ <view class="action">
|
|
|
+ <view class="button" style="background:var(--wot-color-theme);" @click="handleAction('del', item)">
|
|
|
+ {{ t('addressBook.delete.button') }}
|
|
|
</view>
|
|
|
</view>
|
|
|
- </view>
|
|
|
- </z-paging>
|
|
|
- </wd-tab>
|
|
|
- <wd-tab :title="$t('notifications.tab4')">
|
|
|
- <z-paging ref="paging" refresher-only use-page-scroll @query="queryList">
|
|
|
- <view class="py-20rpx">
|
|
|
- <view class="bg-white px-22rpx py-18rpx">
|
|
|
- <view class="mb-8rpx flex items-center justify-between">
|
|
|
- <view class="flex items-center">
|
|
|
- <wd-icon name="view-module" size="36rpx" />
|
|
|
- <text class="ml-8rpx text-24rpx font-bold">
|
|
|
- {{ $t('notifications.orderPayment.title') }}
|
|
|
- </text>
|
|
|
- </view>
|
|
|
- <text class="text-22rpx text-#3A444C">
|
|
|
- 12:30
|
|
|
- </text>
|
|
|
- </view>
|
|
|
- <view class="flex items-center text-22rpx text-#3A444C">
|
|
|
- <view class="truncate">
|
|
|
- {{ $t('notifications.orderPayment.content', ['20250505123030120']) }}
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </z-paging>
|
|
|
- </wd-tab>
|
|
|
- </wd-tabs>
|
|
|
+ </template>
|
|
|
+ </wd-swipe-action>
|
|
|
+ </view>
|
|
|
+ </z-paging>
|
|
|
</template>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-//
|
|
|
+.action {
|
|
|
+ height: 100%;
|
|
|
+ .button {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 0 24rpx;
|
|
|
+ height: 100%;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 已读通知样式
|
|
|
+.notification-read {
|
|
|
+ background-color: #fafafa !important;
|
|
|
+ opacity: 0.95;
|
|
|
+}
|
|
|
</style>
|