index.bak 5.81 KB
<template>
  <view class="h-page">
    <CustomNavbar
      title="Notification"
      :fixed="true"
      :isTab="false"
      bgColor="#3277fb"
      titleStyle="color: #FFFFFF;"
      @back="handleBack"
    >
      <template v-slot:right>
        <view class="navbar-right-button-container">
          <NavbarRightButton
            iconName="trash"
            @click="handleClearAll"
            :showBadge="hasUnread"
            :badgeText="unreadCount"
          />
          <NavbarRightButton iconName="trash" @click="handleSetting" />
        </view>
      </template>
    </CustomNavbar>
    <view class="content-container" :style="contentStyle">
      <scroll-view
        class="notification-list"
        scroll-y
        @scrolltolower="loadMore"
        @refresherrefresh="onRefresh"
        :refresher-triggered="refreshing"
      >
        <NotificationItem
          v-for="(item, index) in notificationList"
          :key="index"
          :type="item.type"
          :title="item.title"
          :message="item.message"
          :time="item.time"
          :unread="item.unread"
          :unreadCount="item.unreadCount"
          @click="handleNotificationClick(item, index)"
        ></NotificationItem>

        <view
          class="p-empty"
          v-if="notificationList.length == 0"
          style="margin-top: 40rpx; padding-bottom: 40rpx"
        >
          <image
            class="p-empty-img"
            src="/static/common/empty.png"
            mode=""
          ></image>
          <text class="p-empty-text chart-text">{{
            t("maintenance.monitor.project.empty.text")
          }}</text>
        </view>

        <view v-if="notificationList.length > 0" class="load-more">
          <uv-loading v-if="loading" mode="circle" :show="loading"></uv-loading>
          <text v-else-if="!hasMore">没有更多数据了</text>
          <text v-else @click="loadMore">点击加载更多</text>
        </view>
      </scroll-view>
    </view>
  </view>
</template>

<script setup>
import { onMounted, computed, ref } from "vue";
import NotificationItem from "./cmp/NotificationItem.vue";
import CustomNavbar from "./cmp/CustomNavbar.vue";
import NavbarRightButton from "./cmp/NavbarRightButton.vue";
import { useNotifications } from "./composables/useNotifications";
import { useSystemHeaderInfo } from "@/hooks/useSystemInfo";
import { t } from "@/plugins/index.js";

const height = ref(uni.getSystemInfoSync().statusBarHeight || 0);

// 获取系统导航栏信息
const { statusBarHeight, headerNavBarAllHeight, contentHeight } =
  useSystemHeaderInfo();

// 使用组合式API
const {
  notificationList,
  fetchNotifications,
  handleNotificationClick,
  markAllAsRead,
  loadMoreNotifications,
} = useNotifications();

// 内容区样式计算
const contentStyle = computed(() => {
  return {
    paddingTop: height.value + 44 + "px",
    height: "100vh",
    boxSizing: "border-box",
    position: "relative",
    overflow: "hidden",
  };
});

// 分页相关
const currentPage = ref(1);
const pageSize = ref(10);
const loading = ref(false);
const hasMore = ref(true);
const refreshing = ref(false);

// 计算属性:是否有未读通知
const hasUnread = computed(() => {
  return notificationList.value.some((item) => item.unread);
});

// 计算属性:未读通知数量
const unreadCount = computed(() => {
  return notificationList.value.filter((item) => item.unread).length;
});

// 返回按钮处理
const handleBack = () => {
  uni.navigateBack();
};

// 清空所有通知
const handleClearAll = () => {
  uni.showModal({
    title: "确认清空",
    content: "确定要清空所有通知吗?",
    success: (res) => {
      if (res.confirm) {
        // 实际应用中应调用API清空通知
        markAllAsRead();
        uni.showToast({
          title: "已清空所有通知",
          icon: "success",
        });
      }
    },
  });
};

// 设置
const handleSetting = () => {
  uni.navigateTo({
    url: "/subPackages/accountGroup/pages/settings/index",
  });
};

// 加载更多数据
const loadMore = () => {
  if (loading.value || !hasMore.value) return;

  loading.value = true;
  currentPage.value += 1;

  setTimeout(() => {
    loadMoreNotifications(currentPage.value, pageSize.value).then((newData) => {
      if (newData.length < pageSize.value) {
        hasMore.value = false;
      }
      loading.value = false;
    });
  }, 500);
};

// 下拉刷新
const onRefresh = () => {
  refreshing.value = true;
  currentPage.value = 1;
  hasMore.value = true;

  // 模拟网络请求延迟
  setTimeout(() => {
    fetchNotifications()
      .then(() => {
        refreshing.value = false;
        uni.showToast({
          title: "刷新成功",
          icon: "success",
        });
      })
      .catch(() => {
        refreshing.value = false;
      });
  }, 1000);
};

// 监听页面滚动到底部
const onReachBottom = () => {
  loadMore();
};

// 生命周期钩子
onMounted(() => {
  // 页面加载时获取通知数据
  fetchNotifications();
});
</script>

<style lang="scss" scoped>
.h-page {
  height: 100vh;
  overflow: hidden;
  position: relative;
}

.content-container {
  width: 100%;
}

.notification-list {
  height: 100%;
  width: 100%;
}

.load-more {
  padding: 20rpx 0;
  text-align: center;
  color: #999;
  font-size: 28rpx;
}

.navbar-right-button-container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20rpx;
}
.h-page {
  /* #ifdef H5 */
  min-height: calc(100vh - 44px);
  /* #endif */
  /* #ifndef H5 */
  min-height: 100vh;
  /* #endif */
  background-color: #f2f3f6;

  .h-c-container {
    padding: 0 20rpx 20rpx;
    flex: 1;
  }
}
.notification-list {
  /* 移除v-bind样式,改用动态style绑定 */
  padding-bottom: 40rpx;
}

.load-more {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 120rpx;
  color: #999;
  font-size: 28rpx;
}
</style>