From 8d4a66c31aa0f6418403ade8a780f27c9fa9d921 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期二, 10 二月 2026 17:43:30 +0800
Subject: [PATCH] 消息列表

---
 src/pages/login.vue   |   59 +++++-
 src/api/login.js      |   19 ++
 src/pages.json        |   12 +
 src/pages/message.vue |  423 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 504 insertions(+), 9 deletions(-)

diff --git a/src/api/login.js b/src/api/login.js
index 7622fc4..180e192 100644
--- a/src/api/login.js
+++ b/src/api/login.js
@@ -57,4 +57,23 @@
     method: 'post',
     data: data
   })
+}
+
+
+// 鏌ヨ鍏憡鍒楄〃
+export function listNotice(query) {
+  return request({
+    url: '/system/notice/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 鑾峰彇鏈娑堟伅鏁伴噺
+export function getNoticeCount(consigneeId) {
+  return request({
+    url: '/system/notice/getCount',
+    method: 'get',
+    params: { consigneeId }
+  })
 }
\ No newline at end of file
diff --git a/src/pages.json b/src/pages.json
index e2560fd..0772b2e 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -884,6 +884,12 @@
         "navigationBarTitleText": "钖祫鍙拌处璇︽儏",
         "navigationStyle": "custom"
       }
+    },
+    {
+      "path": "pages/message",
+      "style": {
+        "navigationBarTitleText": "娑堟伅涓績"
+      }
     }
   ],
   "subPackages": [
@@ -1096,6 +1102,12 @@
         "text": "棣栭〉"
       },
       {
+        "pagePath": "pages/message",
+        "iconPath": "static/images/tabbar/work.png",
+        "selectedIconPath": "static/images/tabbar/work_.png",
+        "text": "娑堟伅"
+      },
+      {
         "pagePath": "pages/mine",
         "iconPath": "static/images/tabbar/mine.png",
         "selectedIconPath": "static/images/tabbar/mine_.png",
diff --git a/src/pages/login.vue b/src/pages/login.vue
index f717c26..d7e5953 100644
--- a/src/pages/login.vue
+++ b/src/pages/login.vue
@@ -48,7 +48,11 @@
       icon: "none",
     });
   };
-  import { userLoginFacotryList, updateClientId } from "@/api/login";
+  import {
+    userLoginFacotryList,
+    updateClientId,
+    getNoticeCount,
+  } from "@/api/login";
   import { ref, onMounted } from "vue";
   import useUserStore from "@/store/modules/user";
   import { getWxCode } from "@/utils/geek";
@@ -160,20 +164,57 @@
   function loginSuccess(result) {
     // 璁剧疆鐢ㄦ埛淇℃伅
     userStore.getInfo().then(res => {
+      const userId = res.user.userId;
       // 鑾峰彇璺敱鏉冮檺
-      userStore.getRouters().then(() => {
-        console.log("璺敱鏉冮檺鑾峰彇鎴愬姛");
-      }).catch(error => {
-        console.error("鑾峰彇璺敱鏉冮檺澶辫触:", error);
-      });
+      userStore
+        .getRouters()
+        .then(() => {
+          console.log("璺敱鏉冮檺鑾峰彇鎴愬姛");
+        })
+        .catch(error => {
+          console.error("鑾峰彇璺敱鏉冮檺澶辫触:", error);
+        });
       // 鐧诲綍鎴愬姛鍚庯紝灏嗗鎴风鎺ㄩ�佹爣璇嗗彂閫佸埌鏈嶅姟鍣�
       sendClientIdToServer();
-      uni.switchTab({
-        url: "/pages/index",
-      });
+      // 鍚姩瀹氭椂鑾峰彇鏈娑堟伅鏁伴噺鐨勫畾鏃跺櫒
+      startNoticeCountTimer(userId);
+      uni.switchTab({ url: "/pages/index" });
     });
   }
 
+  // 鍚姩瀹氭椂鑾峰彇鏈娑堟伅鏁伴噺鐨勫畾鏃跺櫒
+  function startNoticeCountTimer(userId) {
+    // 绔嬪嵆鑾峰彇涓�娆℃湭璇绘秷鎭暟閲�
+    updateNoticeCount(userId);
+    // 璁剧疆瀹氭椂鍣紝姣�30绉掕幏鍙栦竴娆�
+    setInterval(() => {
+      updateNoticeCount(userId);
+    }, 30000);
+  }
+
+  // 鏇存柊鏈娑堟伅鏁伴噺
+  function updateNoticeCount(userId) {
+    getNoticeCount(userId)
+      .then(res => {
+        const count = res.data || 0;
+        console.log("鏈娑堟伅鏁伴噺:", count);
+        // 鏇存柊tabbar鐨勮鏍�
+        if (count > 0) {
+          uni.setTabBarBadge({
+            index: 1, // 娑堟伅鏍囩椤电殑绱㈠紩
+            text: count.toString(),
+          });
+        } else {
+          uni.removeTabBarBadge({
+            index: 1,
+          });
+        }
+      })
+      .catch(error => {
+        console.error("鑾峰彇鏈娑堟伅鏁伴噺澶辫触:", error);
+      });
+  }
+
   // 灏嗗鎴风鎺ㄩ�佹爣璇嗗彂閫佸埌鏈嶅姟鍣�
   function sendClientIdToServer() {
     // 鑾峰彇鏈湴瀛樺偍鐨勫鎴风鏍囪瘑
diff --git a/src/pages/message.vue b/src/pages/message.vue
new file mode 100644
index 0000000..4c57f53
--- /dev/null
+++ b/src/pages/message.vue
@@ -0,0 +1,423 @@
+<template>
+  <view class="message-page">
+    <!-- 椤甸潰澶撮儴 -->
+    <!-- <PageHeader title="娑堟伅涓績"
+                :showBack="false" /> -->
+    <!-- 绛涢�夋爣绛� -->
+    <view class="tabs-container">
+      <up-tabs v-model="activeTab"
+               @change="handleTabChange"
+               :list="tabList"
+               :current="activeTab"
+               itemStyle="width: 50%;height: 80rpx;"></up-tabs>
+    </view>
+    <!-- 娑堟伅鍒楄〃 -->
+    <scroll-view class="message-list"
+                 scroll-y="true"
+                 refresher-enabled="true"
+                 :refresher-triggered="triggered"
+                 :refresher-threshold="100"
+                 refresher-background="#f5f7fa"
+                 @refresherrefresh="onRefresh"
+                 @scrolltolower="loadMore">
+      <!-- 鍔犺浇鐘舵�� -->
+      <view v-if="loading"
+            class="loading-state">
+        <text class="loading-text">鍔犺浇涓�...</text>
+      </view>
+      <!-- 娑堟伅鍒楄〃 -->
+      <view v-else
+            v-for="(item) in messageList"
+            :key="item.id"
+            class="message-item"
+            :class="{ 'unread': !item.read }">
+        <view class="message-content">
+          <view class="message-header">
+            <text class="message-title">{{ item.noticeTitle }}</text>
+            <text class="message-time">{{ formatTime(item.createTime) }}</text>
+          </view>
+          <text class="message-desc">{{ item.noticeContent }}</text>
+          <view class="message-footer">
+            <text class="message-view"
+                  @click="goToDetail(item)">
+              鍘绘煡鐪� >
+            </text>
+          </view>
+        </view>
+      </view>
+      <!-- 绌虹姸鎬� -->
+      <view v-if="!loading && messageList.length === 0"
+            class="empty-state">
+        <text class="empty-text">鏆傛棤娑堟伅</text>
+      </view>
+      <!-- 鍔犺浇鏇村鐘舵�� -->
+      <view v-if="loadingMore"
+            class="loading-more-state">
+        <text class="loading-more-text">鍔犺浇鏇村...</text>
+      </view>
+    </scroll-view>
+  </view>
+</template>
+
+<script setup>
+  import { ref, reactive, onMounted } from "vue";
+  import { listNotice } from "@/api/login.js";
+  import useUserStore from "@/store/modules/user";
+
+  // 鏍囩椤垫暟鎹�
+  const tabList = [
+    { name: "鏈", id: 0 },
+    { name: "宸茶", id: 1 },
+  ];
+
+  // 褰撳墠婵�娲荤殑鏍囩
+  const activeTab = ref(0);
+
+  // 娑堟伅鍒楄〃鏁版嵁
+  const messageList = ref([]);
+  const loading = ref(false);
+  const loadingMore = ref(false);
+  const total = ref(0);
+  const triggered = ref(false);
+
+  // 鍒嗛〉鍙傛暟
+  const page = reactive({
+    current: 1,
+    size: 10,
+  });
+
+  // 鏍煎紡鍖栨椂闂�
+  const formatTime = time => {
+    if (!time) return "";
+    const date = new Date(time);
+    const Y = date.getFullYear();
+    const M = String(date.getMonth() + 1).padStart(2, "0");
+    const D = String(date.getDate()).padStart(2, "0");
+    const h = String(date.getHours()).padStart(2, "0");
+    const m = String(date.getMinutes()).padStart(2, "0");
+    return `${Y}-${M}-${D} ${h}:${m}`;
+  };
+
+  // 璺宠浆鍒拌鎯呴〉
+  const goToDetail = item => {
+    if (item.jumpPath.indexOf("/") === 0) {
+      uni.navigateTo({
+        url: item.jumpPath,
+      });
+    } else {
+      uni.navigateTo({
+        url: "/" + item.jumpPath,
+      });
+    }
+  };
+  const userStore = useUserStore();
+  const userId = ref("");
+  const getUserId = () => {
+    return userStore.getInfo().then(res => {
+      console.log(res.user.userId, "res@@@@@@@@@@@2");
+      userId.value = res.user.userId;
+    });
+  };
+
+  // 澶勭悊鏍囩椤靛垏鎹�
+  const handleTabChange = val => {
+    console.log(val);
+    activeTab.value = val.id;
+    page.current = 1;
+    loadMessages(false);
+  };
+
+  // 鍔犺浇娑堟伅鍒楄〃
+  const loadMessages = (append = false) => {
+    if (append) {
+      loadingMore.value = true;
+    } else {
+      loading.value = true;
+    }
+
+    // 鏋勫缓鏌ヨ鍙傛暟
+    const params = {
+      consigneeId: userId.value,
+      current: page.current,
+      size: page.size,
+      status: activeTab.value,
+    };
+    console.log(params, "===========");
+    return listNotice(params)
+      .then(res => {
+        const records = res?.data?.records || [];
+        total.value = res?.data?.total || 0;
+
+        if (append) {
+          messageList.value = [...messageList.value, ...records];
+        } else {
+          messageList.value = records;
+        }
+      })
+      .catch(error => {
+        console.error("鑾峰彇娑堟伅澶辫触:", error);
+        uni.showToast({ title: "鑾峰彇娑堟伅澶辫触锛岃閲嶈瘯", icon: "none" });
+      })
+      .finally(() => {
+        loading.value = false;
+        loadingMore.value = false;
+      });
+  };
+
+  // 鍔犺浇鏇村
+  const loadMore = () => {
+    console.log("===========");
+    if (loading.value || loadingMore.value) return;
+    if (messageList.value.length >= total.value) return;
+
+    page.current++;
+    loadMessages(true);
+  };
+
+  // 涓嬫媺鍒锋柊
+  const onRefresh = () => {
+    triggered.value = true;
+    // 閲嶇疆椤电爜
+    page.current = 1;
+    // 閲嶆柊鍔犺浇娑堟伅
+    loadMessages(false).finally(() => {
+      // 鍏抽棴鍒锋柊鐘舵��
+      setTimeout(() => {
+        triggered.value = false;
+      }, 500);
+    });
+  };
+
+  // 椤甸潰鍔犺浇鏃惰幏鍙栨秷鎭垪琛�
+  onMounted(() => {
+    getUserId().then(() => {
+      loadMessages();
+    });
+  });
+</script>
+
+<style scoped lang="scss">
+  // 鍏ㄥ眬鍙橀噺
+  $primary-color: #2c7be5;
+  $primary-light: #4a90e2;
+  $success-color: #4cd964;
+  $warning-color: #ff9500;
+  $danger-color: #ff3b30;
+  $text-primary: #333333;
+  $text-secondary: #666666;
+  $text-tertiary: #999999;
+  $bg-color: #f5f7fa;
+  $card-bg: #ffffff;
+  $border-color: #e8e8e8;
+  $shadow-sm: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
+
+  .message-page {
+    min-height: 100vh;
+    background-color: $bg-color;
+    padding-bottom: 30rpx;
+  }
+
+  /* 鏍囩椤靛鍣� */
+  .tabs-container {
+    background-color: #ffffff;
+    margin-bottom: 20rpx;
+    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
+  }
+
+  /* 娑堟伅鍒楄〃 */
+  .message-list {
+    margin: 0 20rpx 20rpx;
+    min-height: 600rpx;
+    height: calc(100vh - 200rpx);
+  }
+
+  /* 鍔犺浇鐘舵�� */
+  .loading-state {
+    background-color: $card-bg;
+    border-radius: 16rpx;
+    box-shadow: $shadow-sm;
+    text-align: center;
+    padding: 120rpx 0;
+    margin-bottom: 20rpx;
+  }
+
+  .loading-text {
+    font-size: 14px;
+    color: $text-tertiary;
+    margin-top: 24rpx;
+    font-weight: 500;
+  }
+
+  /* 娑堟伅椤� */
+  .message-item {
+    display: flex;
+    align-items: flex-start;
+    background-color: $card-bg;
+    border-radius: 16rpx;
+    box-shadow: $shadow-sm;
+    padding: 24rpx;
+    margin-bottom: 20rpx;
+    margin-right: 40rpx;
+    transition: all 0.3s ease;
+  }
+
+  .message-item:hover {
+    box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.12);
+    transform: translateY(-2rpx);
+  }
+
+  .message-item.unread {
+    border-left: 4rpx solid $primary-color;
+  }
+
+  /* 娑堟伅鍥炬爣 */
+  .message-icon {
+    margin-right: 20rpx;
+    margin-top: 4rpx;
+  }
+
+  /* 娑堟伅鍐呭 */
+  .message-content {
+    flex: 1;
+  }
+
+  /* 娑堟伅澶撮儴 */
+  .message-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 12rpx;
+  }
+
+  .message-title {
+    font-size: 16px;
+    font-weight: 600;
+    color: $text-primary;
+    flex: 1;
+    margin-right: 20rpx;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+
+  .message-time {
+    font-size: 12px;
+    color: $text-tertiary;
+  }
+
+  /* 娑堟伅鎻忚堪 */
+  .message-desc {
+    font-size: 14px;
+    color: $text-secondary;
+    line-height: 1.4;
+    margin-bottom: 16rpx;
+    display: -webkit-box;
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
+
+  /* 娑堟伅搴曢儴 */
+  .message-footer {
+    display: flex;
+    justify-content: flex-end;
+    align-items: center;
+  }
+
+  .message-creator {
+    font-size: 12px;
+    color: $text-tertiary;
+  }
+
+  /* 绌虹姸鎬� */
+  .empty-state {
+    background-color: $card-bg;
+    border-radius: 16rpx;
+    box-shadow: $shadow-sm;
+    text-align: center;
+    padding: 160rpx 0;
+    margin: 40rpx 0;
+  }
+
+  .empty-text {
+    font-size: 14px;
+    color: $text-tertiary;
+    margin-top: 24rpx;
+    font-weight: 500;
+  }
+
+  /* 鍔犺浇鏇村鐘舵�� */
+  .loading-more-state {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    padding: 30rpx 0;
+    margin-top: 10rpx;
+  }
+
+  .loading-more-text {
+    font-size: 14px;
+    color: $text-tertiary;
+    margin-left: 10rpx;
+  }
+
+  /* 鍔犺浇鏇村 */
+  .load-more {
+    text-align: center;
+    padding: 30rpx 0;
+    font-size: 14px;
+    color: $primary-color;
+    font-weight: 500;
+    margin-top: 20rpx;
+  }
+
+  .load-more-text {
+    display: inline-block;
+    padding: 10rpx 30rpx;
+    background-color: rgba($primary-color, 0.1);
+    border-radius: 20rpx;
+    transition: all 0.3s ease;
+  }
+
+  .load-more-text:hover {
+    background-color: rgba($primary-color, 0.2);
+    transform: translateY(-2rpx);
+  }
+
+  /* 鍔ㄧ敾鏁堟灉 */
+  @keyframes fadeInUp {
+    from {
+      opacity: 0;
+      transform: translateY(20rpx);
+    }
+    to {
+      opacity: 1;
+      transform: translateY(0);
+    }
+  }
+
+  .message-item {
+    animation: fadeInUp 0.3s ease-out;
+  }
+
+  .message-item:nth-child(2) {
+    animation-delay: 0.1s;
+  }
+
+  .message-item:nth-child(3) {
+    animation-delay: 0.2s;
+  }
+
+  .message-item:nth-child(4) {
+    animation-delay: 0.3s;
+  }
+
+  .message-item:nth-child(5) {
+    animation-delay: 0.4s;
+  }
+  .message-view {
+    float: right;
+    color: $primary-color;
+  }
+</style>
\ No newline at end of file

--
Gitblit v1.9.3