Pārlūkot izejas kodu

feat: 通知接口对接、商详收藏字段

liangan 1 mēnesi atpakaļ
vecāks
revīzija
4b8bef825b

+ 12 - 0
.promptx/memory/assistant/declarative.dpml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<memory>
+  <item id="mem_1756273976557_1eurk9qxm" time="2025/08/27 13:52">
+    <content>
+      项目开发规范补充:
+      1. 电商功能架构:基于拼团模式,无购物车功能,产品详情页直接开团/参团,然后进入结账页面
+      2. 开发要求:不需要创建测试用例和单元测试
+      3. TypeScript规范:简化写法,直接使用any类型,不需要严格的类型定义
+    </content>
+    <tags>#其他</tags>
+  </item>
+</memory>

+ 23 - 12
.promptx/pouch.json

@@ -4,10 +4,10 @@
     {
       "from": "initial",
       "command": "init",
-      "timestamp": "2025-08-14T02:17:01.631Z",
+      "timestamp": "2025-08-27T05:49:54.759Z",
       "args": [
         {
-          "workingDirectory": "/Users/liangan/Documents/work_files/code/BandhuBuyUniBest",
+          "workingDirectory": "/Users/liangan/Documents/work/code/uni/bandhuBuy-uniapp",
           "ideType": "cursor"
         }
       ]
@@ -15,16 +15,27 @@
     {
       "from": "initialized",
       "command": "welcome",
-      "timestamp": "2025-08-14T02:17:05.173Z",
+      "timestamp": "2025-08-27T05:49:58.143Z",
       "args": []
     },
     {
       "from": "service_discovery",
       "command": "init",
-      "timestamp": "2025-08-14T02:18:02.896Z",
+      "timestamp": "2025-08-27T05:50:48.267Z",
       "args": [
         {
-          "workingDirectory": "/Users/liangan/Documents/work_files/code/BandhuBuyUniBest",
+          "workingDirectory": "/Users/liangan/Documents/work/code/uni/bandhuBuy-uniapp",
+          "ideType": "cursor"
+        }
+      ]
+    },
+    {
+      "from": "initialized",
+      "command": "init",
+      "timestamp": "2025-08-27T05:51:55.399Z",
+      "args": [
+        {
+          "workingDirectory": "/Users/liangan/Documents/work/code/uni/bandhuBuy-uniapp",
           "ideType": "cursor"
         }
       ]
@@ -32,28 +43,28 @@
     {
       "from": "initialized",
       "command": "welcome",
-      "timestamp": "2025-08-14T02:18:06.816Z",
+      "timestamp": "2025-08-27T05:51:59.597Z",
       "args": []
     },
     {
       "from": "service_discovery",
       "command": "action",
-      "timestamp": "2025-08-14T02:19:10.079Z",
+      "timestamp": "2025-08-27T05:52:47.871Z",
       "args": [
-        "noface"
+        "assistant"
       ]
     },
     {
       "from": "role_activated_with_memory",
       "command": "remember",
-      "timestamp": "2025-08-14T02:21:59.115Z",
+      "timestamp": "2025-08-27T05:52:56.554Z",
       "args": [
-        "noface",
+        "assistant",
         "项目开发规范补充:\n1. 电商功能架构:基于拼团模式,无购物车功能,产品详情页直接开团/参团,然后进入结账页面\n2. 开发要求:不需要创建测试用例和单元测试\n3. TypeScript规范:简化写法,直接使用any类型,不需要严格的类型定义",
         "--tags",
-        "开发规范 电商架构 TypeScript"
+        "项目规范 电商架构 拼团模式 开发要求 TypeScript"
       ]
     }
   ],
-  "lastUpdated": "2025-08-14T02:21:59.122Z"
+  "lastUpdated": "2025-08-27T05:52:56.562Z"
 }

+ 2 - 2
.promptx/resource/project.registry.json

@@ -4,8 +4,8 @@
   "metadata": {
     "version": "2.0.0",
     "description": "project 级资源注册表",
-    "createdAt": "2025-08-14T02:18:02.907Z",
-    "updatedAt": "2025-08-14T02:18:02.908Z",
+    "createdAt": "2025-08-27T05:51:55.408Z",
+    "updatedAt": "2025-08-27T05:51:55.408Z",
     "resourceCount": 0
   },
   "resources": [],

+ 37 - 0
src/api/common.ts

@@ -46,3 +46,40 @@ export function bannerList(data: any) {
 export function getConfigByCode(data: any) {
   return http.get<any>(`${pre2}/config/getConfigByCode`, data)
 }
+
+// 获取通知公告列表
+/**
+说明                          名称                                      枚举值
+订单通知_拼团支付成功            ORDER_GROUP_BUY_PAYMENT_SUCCESS          ORDER_GROUP_BUY_PAYMENT_SUCCESS
+订单通知_订单拼团成功&抽中        ORDER_GROUP_BUY_SUCCESS_WIN              ORDER_GROUP_BUY_SUCCESS_WIN
+订单通知_订单拼团成功&未抽中      ORDER_GROUP_BUY_SUCCESS_LOSE             ORDER_GROUP_BUY_SUCCESS_LOSE
+订单通知_订单补充收货地址         ORDER_PROVIDE_SHIPPING_ADDRESS           ORDER_PROVIDE_SHIPPING_ADDRESS
+订单通知_订单拼团失败            ORDER_GROUP_BUY_FAIL                     ORDER_GROUP_BUY_FAIL
+订单通知_订单发货               ORDER_SHIPPED_SUCCESS                    ORDER_SHIPPED_SUCCESS
+收益通知_邀请好友奖励            REWARD_REFER_FRIENDS                     REWARD_REFER_FRIENDS
+收益通知_拼团/开团奖励           REWARD_GROUP_BUY                         REWARD_GROUP_BUY
+收益通知_邀请好友奖励            REWARD_DIRECT_REFERRAL                   REWARD_DIRECT_REFERRAL
+收益通知_签到奖励               REWARD_CHECKIN                           REWARD_CHECKIN
+充值/提现通知_充值成功           MONEY_RECHARGE_SUCCESS                   MONEY_RECHARGE_SUCCESS
+充值/提现通知_提现成功-收益       MONEY_WITHDRAWAL_ACCOUNT_SUCCESS         MONEY_WITHDRAWAL_ACCOUNT_SUCCESS
+充值/提现通知_提现成功-钱包       MONEY_WITHDRAWAL_WALLET_SUCCESS          MONEY_WITHDRAWAL_WALLET_SUCCESS
+充值/提现通知_提现失败           MONEY_WITHDRAWAL_FAIL                    MONEY_WITHDRAWAL_FAIL
+其他                          OTHER                                    OTHER
+ */
+export function noticeList(data: any) {
+  return http.get<any>(`${pre}/app/notice/page`, data)
+}
+// 获取通知公告未读条数
+export function noticeUnread() {
+  return http.get<any>(`${pre}/app/notice/unread`)
+}
+
+// 已读通知
+export function noticeRead(id: number) {
+  return http.put<any>(`${pre}/app/notice/read/${id}`)
+}
+
+// 删除通知
+export function noticeDel(id: number) {
+  return http.delete<any>(`${pre}/app/notice/delete/${id}`)
+}

+ 33 - 6
src/locale/bn.json

@@ -223,12 +223,39 @@
   "referEarn.title": "রেফার এবং আয়",
   "vipMembership.title": "ভিআইপি সদস্যতা",
   "notifications.title": "বিজ্ঞপ্তি",
-  "notifications.tab1": "সিস্টেম",
-  "notifications.tab2": "অর্ডার",
-  "notifications.tab3": "কার্যকলাপ",
-  "notifications.tab4": "অন্যান্য",
-  "notifications.orderPayment.title": "অর্ডার পেমেন্ট সফল",
-  "notifications.orderPayment.content": "আপনার কেনা পণ্য [{0}] পেমেন্ট সফল হয়েছে..",
+  "notifications.tabs.all": "সব",
+  "notifications.tabs.orders": "অর্ডার",
+  "notifications.tabs.revenue": "রাজস্ব",
+  "notifications.tabs.account": "অ্যাকাউন্ট",
+  "notifications.tabs.promos": "প্রচার",
+  "notifications.order.paymentSuccess.title": "গ্রুপ বাই পেমেন্ট সফল",
+  "notifications.order.paymentSuccess.content": "আপনার অংশগ্রহণ করা গ্রুপ অর্ডার [{orderId}] সফলভাবে পেমেন্ট হয়েছে",
+  "notifications.order.groupBuyWin.title": "গ্রুপ বাই সফল",
+  "notifications.order.groupBuyWin.content": "আপনার অংশগ্রহণ করা গ্রুপ অর্ডার [{orderId}] নির্বাচিত হয়েছে",
+  "notifications.order.groupBuyLose.title": "গ্রুপ বাই সফল",
+  "notifications.order.groupBuyLose.content": "আপনার অংশগ্রহণ করা গ্রুপ অর্ডার [{orderId}] নির্বাচিত হয়নি",
+  "notifications.order.provideAddress.title": "অর্ডার শিপিং ঠিকানা প্রদান",
+  "notifications.order.provideAddress.content": "আপনার অংশগ্রহণ করা গ্রুপ অর্ডার [{orderId}] অনুগ্রহ করে আপনার শিপিং ঠিকানা প্রদান করুন",
+  "notifications.order.groupBuyFail.title": "গ্রুপ বাই ব্যর্থ",
+  "notifications.order.groupBuyFail.content": "আপনার অংশগ্রহণ করা গ্রুপ অর্ডার [{orderId}] ব্যর্থ হয়েছে",
+  "notifications.order.shipped.title": "অর্ডার সফলভাবে শিপ হয়েছে",
+  "notifications.order.shipped.content": "আপনার অংশগ্রহণ করা গ্রুপ অর্ডার [{orderId}] সফলভাবে শিপ হয়েছে",
+  "notifications.reward.referFriends.title": "বন্ধু রেফার পুরস্কার",
+  "notifications.reward.referFriends.content": "আপনি বন্ধু রেফারের জন্য পুরস্কার পেয়েছেন",
+  "notifications.reward.groupBuy.title": "গ্রুপ বাইং পুরস্কার",
+  "notifications.reward.groupBuy.content": "আপনি একটি পুরস্কার পেয়েছেন, অর্ডার আইডি [{orderId}]",
+  "notifications.reward.directReferral.title": "সরাসরি রেফারেল পুরস্কার",
+  "notifications.reward.directReferral.content": "আপনি সরাসরি রেফারেলের জন্য পুরস্কার পেয়েছেন",
+  "notifications.reward.checkin.title": "চেক-ইন পুরস্কার",
+  "notifications.reward.checkin.content": "আপনি চেক-ইনের জন্য পুরস্কার পেয়েছেন",
+  "notifications.money.rechargeSuccess.title": "রিচার্জ সফল",
+  "notifications.money.rechargeSuccess.content": "আপনার KLICKওয়ালেট সফলভাবে রিচার্জ হয়েছে",
+  "notifications.money.withdrawalAccountSuccess.title": "উত্তোলন সফল",
+  "notifications.money.withdrawalAccountSuccess.content": "আপনার রাজস্ব অ্যাকাউন্ট উত্তোলনের অনুরোধ প্রক্রিয়া করা হয়েছে",
+  "notifications.money.withdrawalWalletSuccess.title": "উত্তোলন সফল",
+  "notifications.money.withdrawalWalletSuccess.content": "আপনার KLICK ওয়ালেট উত্তোলনের অনুরোধ প্রক্রিয়া করা হয়েছে",
+  "notifications.money.withdrawalFail.title": "উত্তোলন ব্যর্থ",
+  "notifications.money.withdrawalFail.content": "আপনার উত্তোলনের অনুরোধ ব্যর্থ হয়েছে",
   "productDetail.title": "পণ্যের বিবরণ",
   "webLink.title": "ওয়েব লিঙ্ক",
   "missionCenter.signIn.title": "ক্রমাগত সাইন ইন করে পুরস্কার পান",

+ 33 - 6
src/locale/en.json

@@ -224,12 +224,39 @@
   "referEarn.title": "Refer & Earn",
   "vipMembership.title": "VIP Membership",
   "notifications.title": "Notifications",
-  "notifications.tab1": "System",
-  "notifications.tab2": "Order",
-  "notifications.tab3": "Activity",
-  "notifications.tab4": "Other",
-  "notifications.orderPayment.title": "Order Payment Successful",
-  "notifications.orderPayment.content": "The product you purchased [{0}] has been paid..",
+  "notifications.tabs.all": "All",
+  "notifications.tabs.orders": "Orders",
+  "notifications.tabs.revenue": "Revenue",
+  "notifications.tabs.account": "Account",
+  "notifications.tabs.promos": "Promos",
+  "notifications.order.paymentSuccess.title": "Group Buy Payment Successful",
+  "notifications.order.paymentSuccess.content": "The group order you participated in [{orderId}] has been successfully paid",
+  "notifications.order.groupBuyWin.title": "Group Buy Successful",
+  "notifications.order.groupBuyWin.content": "The group order you participated in [{orderId}] has been selected",
+  "notifications.order.groupBuyLose.title": "Group Buy Successful",
+  "notifications.order.groupBuyLose.content": "The group order you participated in [{orderId}] was not selected",
+  "notifications.order.provideAddress.title": "Order provide shipping address",
+  "notifications.order.provideAddress.content": "The group order you participated in [{orderId}] Please provide your shipping address",
+  "notifications.order.groupBuyFail.title": "Group Buy Failed",
+  "notifications.order.groupBuyFail.content": "The group order you participated in [{orderId}] has failed",
+  "notifications.order.shipped.title": "Order shipped successfully",
+  "notifications.order.shipped.content": "The group order you participated in [{orderId}] has been successfully shipped",
+  "notifications.reward.referFriends.title": "Refer Friends Reward",
+  "notifications.reward.referFriends.content": "You have received the reward for refer friends",
+  "notifications.reward.groupBuy.title": "Group Buying Reward",
+  "notifications.reward.groupBuy.content": "You have received a reward, order ID [{orderId}]",
+  "notifications.reward.directReferral.title": "Direct Referral Reward",
+  "notifications.reward.directReferral.content": "You have received the reward for Direct Referral",
+  "notifications.reward.checkin.title": "Check-in Reward",
+  "notifications.reward.checkin.content": "You have received the reward for Check-in",
+  "notifications.money.rechargeSuccess.title": "Recharge Successful",
+  "notifications.money.rechargeSuccess.content": "Your KLICKwallet has been successfully recharged",
+  "notifications.money.withdrawalAccountSuccess.title": "Withdrawal Successful",
+  "notifications.money.withdrawalAccountSuccess.content": "Your Revenue Account withdrawal request has been processed",
+  "notifications.money.withdrawalWalletSuccess.title": "Withdrawal Successful",
+  "notifications.money.withdrawalWalletSuccess.content": "Your KLICK wallet withdrawal request has been processed",
+  "notifications.money.withdrawalFail.title": "Withdrawal Failed",
+  "notifications.money.withdrawalFail.content": "Your withdrawal request has been failed",
   "productDetail.title": "Product Detail",
   "webLink.title": "Web Link",
   "missionCenter.signIn.title": "Continuous sign in to receive rewards",

+ 33 - 6
src/locale/zh-Hans.json

@@ -223,12 +223,39 @@
   "referEarn.title": "推荐赚钱",
   "vipMembership.title": "VIP会员",
   "notifications.title": "通知",
-  "notifications.tab1": "系统",
-  "notifications.tab2": "订单",
-  "notifications.tab3": "活动",
-  "notifications.tab4": "其他",
-  "notifications.orderPayment.title": "订单支付成功",
-  "notifications.orderPayment.content": "您购买的商品[{0}]已支付成功..",
+  "notifications.tabs.all": "全部",
+  "notifications.tabs.orders": "订单",
+  "notifications.tabs.revenue": "收益",
+  "notifications.tabs.account": "账户",
+  "notifications.tabs.promos": "活动",
+  "notifications.order.paymentSuccess.title": "团购支付成功",
+  "notifications.order.paymentSuccess.content": "您参与的团购订单[{orderId}]已支付成功",
+  "notifications.order.groupBuyWin.title": "团购成功",
+  "notifications.order.groupBuyWin.content": "您参与的团购订单[{orderId}]已中选",
+  "notifications.order.groupBuyLose.title": "团购成功",
+  "notifications.order.groupBuyLose.content": "您参与的团购订单[{orderId}]未中选",
+  "notifications.order.provideAddress.title": "订单提供收货地址",
+  "notifications.order.provideAddress.content": "您参与的团购订单[{orderId}]请提供收货地址",
+  "notifications.order.groupBuyFail.title": "团购失败",
+  "notifications.order.groupBuyFail.content": "您参与的团购订单[{orderId}]已失败",
+  "notifications.order.shipped.title": "订单发货成功",
+  "notifications.order.shipped.content": "您参与的团购订单[{orderId}]已成功发货",
+  "notifications.reward.referFriends.title": "推荐好友奖励",
+  "notifications.reward.referFriends.content": "您已获得推荐好友奖励",
+  "notifications.reward.groupBuy.title": "团购奖励",
+  "notifications.reward.groupBuy.content": "您已获得奖励,订单号[{orderId}]",
+  "notifications.reward.directReferral.title": "直接推荐奖励",
+  "notifications.reward.directReferral.content": "您已获得直接推荐奖励",
+  "notifications.reward.checkin.title": "签到奖励",
+  "notifications.reward.checkin.content": "您已获得签到奖励",
+  "notifications.money.rechargeSuccess.title": "充值成功",
+  "notifications.money.rechargeSuccess.content": "您的KLICK钱包已成功充值",
+  "notifications.money.withdrawalAccountSuccess.title": "提现成功",
+  "notifications.money.withdrawalAccountSuccess.content": "您的收益账户提现请求已处理",
+  "notifications.money.withdrawalWalletSuccess.title": "提现成功",
+  "notifications.money.withdrawalWalletSuccess.content": "您的KLICK钱包提现请求已处理",
+  "notifications.money.withdrawalFail.title": "提现失败",
+  "notifications.money.withdrawalFail.content": "您的提现请求已失败",
   "productDetail.title": "产品详情",
   "webLink.title": "网页链接",
   "missionCenter.signIn.title": "连续签到获得奖励",

+ 1 - 0
src/pages.json

@@ -181,6 +181,7 @@
       "path": "pages/notifications/notifications",
       "type": "page",
       "layout": "default",
+      "needLogin": true,
       "style": {
         "navigationBarTitleText": "%notifications.title%",
         "navigationBarBackgroundColor": "#fff"

+ 20 - 6
src/pages/index/index.vue

@@ -15,7 +15,7 @@
 import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
 import useZPaging from 'z-paging/components/z-paging/js/hooks/useZPaging.js'
 
-import { bannerList } from '@/api/common'
+import { bannerList, noticeUnread } from '@/api/common'
 import { getList } from '@/api/product'
 import { parseQs } from '@/utils'
 import { toPage } from '@/utils/page'
@@ -140,7 +140,6 @@ async function queryList(pageNo: number, pageSize: number) {
 
 async function getBannerList() {
   const res = await bannerList({ page: 1, size: 20 })
-  console.log(res)
   swiperList.value = res.data.list
 }
 
@@ -148,8 +147,21 @@ async function getBannerList() {
 function onPriceTabChange() {
   paging.value.reload()
 }
+const unread = ref(0)
+async function getUnread() {
+  try {
+    const res = await noticeUnread()
+    if (res.code === '200') {
+      unread.value = Number(res.data) || 0
+    }
+  }
+  catch {
+
+  }
+}
 
-onLoad(() => {
+onShow(() => {
+  getUnread()
   getNewList()
   getBannerList()
 })
@@ -165,7 +177,9 @@ onLoad(() => {
         <image src="/static/header-logo.png" class="h-44rpx w-275rpx" />
         <view class="flex items-center">
           <image src="/static/icons/search.png" class="mr-20rpx h-36rpx w-36rpx" @click="toPage('/pages/search/search')" />
-          <image src="/static/icons/notifications.png" class="h-36rpx w-36rpx" @click="toPage('/pages/notifications/notifications')" />
+          <wd-badge :model-value="unread" :max="99">
+            <image src="/static/icons/notifications.png" class="h-36rpx w-36rpx" @click="toPage('/pages/notifications/notifications')" />
+          </wd-badge>
         </view>
       </view>
     </template>
@@ -193,7 +207,7 @@ onLoad(() => {
         </view>
         <scroll-view scroll-x>
           <view class="flex items-center gap-22rpx pb-24rpx">
-            <product v-for="(item, index) in newProducts" :key="index" :item="item" @item-click="toPage('/pages/productDetail/productDetail', { productId: item.productId, id: item.id })" />
+            <product v-for="(item, index) in newProducts" :key="index" :item="item" @item-click="toPage('/pages/productDetail/productDetail', { productId: item.productId })" />
           </view>
         </scroll-view>
       </view>
@@ -204,7 +218,7 @@ onLoad(() => {
           </template>
         </wd-tabs>
         <view class="grid grid-cols-2 gap-22rpx">
-          <product v-for="(item, index) in dataList" :key="index" width="100%" :height="340" :item="item" @item-click="toPage('/pages/productDetail/productDetail', { productId: item.productId, id: item.id })" />
+          <product v-for="(item, index) in dataList" :key="index" width="100%" :height="340" :item="item" @item-click="toPage('/pages/productDetail/productDetail', { productId: item.productId })" />
         </view>
       </view>
     </view>

+ 1 - 1
src/pages/mine/myFavorite.vue

@@ -47,7 +47,7 @@ async function queryList(pageNo: number, pageSize: number) {
     <template v-if="dataList.length">
       <view class="px-24rpx py-24rpx">
         <view class="grid grid-cols-2 gap-22rpx">
-          <product v-for="(item, index) in dataList" :key="index" :height="340" :item="item" @item-click="toPage('/pages/productDetail/productDetail', { productId: item.productId, id: item.id })" />
+          <product v-for="(item, index) in dataList" :key="index" :height="340" :item="item" @item-click="toPage('/pages/productDetail/productDetail', { productId: item.productId })" />
         </view>
       </view>
     </template>

+ 239 - 105
src/pages/notifications/notifications.vue

@@ -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>

+ 12 - 16
src/pages/productDetail/productDetail.vue

@@ -15,7 +15,7 @@ import useZPaging from 'z-paging/components/z-paging/js/hooks/useZPaging.js'
 import { myFavoriteAdd, myFavoriteDel } from '@/api/mine'
 import { preOrder as _preOrder } from '@/api/order'
 import { getDetail, pinkList } from '@/api/product'
-import { getUserInfoHook, requireLogin } from '@/hooks/usePageAuth'
+import { requireLogin } from '@/hooks/usePageAuth'
 import { t } from '@/locale'
 import { formatNumber } from '@/utils/index'
 import { getPageParams, goBack, toPage } from '@/utils/page'
@@ -26,9 +26,7 @@ import NotificationCarousel from './components/NotificationCarousel.vue'
 defineOptions({
   name: 'ProductDetail', // 商品详情
 })
-const userInfo = computed(() => {
-  return getUserInfoHook()
-})
+
 // 获取屏幕边界到安全区域距离
 const systemInfo = uni.getSystemInfoSync()
 const safeAreaInsets = systemInfo.safeAreaInsets
@@ -58,7 +56,6 @@ onPageScroll((e) => {
   }
 })
 const productId = ref('') // 商品id
-const id = ref('') // 数据id
 const detail = ref<any>({
   sliderImage: '',
   flatPattern: '',
@@ -211,7 +208,7 @@ async function queryDetail() {
 
 // 查询商品拼团信息
 async function queryPinkInfo() {
-  const res = await pinkList({ cid: id.value })
+  const res = await pinkList({ cid: detail.value.cid })
   console.log(res)
   pinkInfo.value = res.data.list
 }
@@ -256,11 +253,11 @@ async function toggleFavorite() {
   }
 
   try {
-    if (detail.value.isFavorite) {
+    if (detail.value.favoriteFlag) {
       // 取消收藏
       const res = await myFavoriteDel({ id: productId.value })
       if (res.code === '200') {
-        detail.value.isFavorite = false
+        detail.value.favoriteFlag = false
         toast.success(t('productDetail.unfavoriteSuccess'))
       }
     }
@@ -268,7 +265,7 @@ async function toggleFavorite() {
       // 添加收藏
       const res = await myFavoriteAdd({ productIdList: [productId.value] })
       if (res.code === '200') {
-        detail.value.isFavorite = true
+        detail.value.favoriteFlag = true
         toast.success(t('productDetail.favoriteSuccess'))
       }
     }
@@ -287,7 +284,7 @@ async function preOrder() {
     orderDetails: {
       attrValueId: matchedAttrValue.value.id,
       productId: productId.value,
-      cid: id.value,
+      cid: detail.value.cid,
       productNum: formData.value.productNum,
     },
     preOrderType: 'buyNow',
@@ -301,7 +298,7 @@ async function preOrder() {
         preOrderId: res.data,
         joinOrderId: joinOrderId.value,
         pinkId: pinkId.value,
-        cid: id.value,
+        cid: detail.value.cid,
         groupType: groupType.value,
       },
     )
@@ -312,12 +309,11 @@ async function preOrder() {
 onLoad((options) => {
   console.log(options)
   const params = getPageParams(options)
-  id.value = params.id
   productId.value = params.productId
 })
-onShow(() => {
-  queryDetail()
-  queryPinkInfo()
+onShow(async () => {
+  await queryDetail()
+  await queryPinkInfo()
 })
 </script>
 
@@ -476,7 +472,7 @@ onShow(() => {
           </view>
           <view class="flex flex-col items-center justify-center" @click="toggleFavorite">
             <image
-              v-if="detail.isFavorite"
+              v-if="detail.favoriteFlag"
               src="/static/icons/favorite-active.png"
               class="h-40rpx w-40rpx"
             />

BIN
src/static/icons/msg-income.png


BIN
src/static/icons/msg-order.png


BIN
src/static/icons/msg-other.png


BIN
src/static/icons/msg-wallet.png


+ 1 - 1
src/utils/page.ts

@@ -11,7 +11,7 @@ export function toPage(url: string, params?: Record<string, any>, isRedirect = f
   let targetUrl = url
   const tabBarPages = ['/pages/index/index', '/pages/income/income', '/pages/mine/mine']
 
-  if (params) {
+  if (params && Object.keys(params).length > 0) {
     const data = JSON.stringify(params)
     targetUrl = `${url}?params=${encodeURIComponent(data)}`
   }