index.vue 5.03 KB
<template>
  <!-- 外层容器:包含蓝色块 + 原始内容 -->
  <view class="workbench-container">
    <!-- 加载页:覆盖整个容器,渲染完成后隐藏 -->
    <up-loading-page
        v-if="loading"
        loading-text="加载中..."
        color="#577ee3"
        style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 9999;"
    ></up-loading-page>

    <!-- 蓝色装饰块:#577ee3 -->
    <view class="blue-decor-block"></view>

    <!-- 原始内容容器:仅添加定位和顶部偏移实现压边 -->
    <view class="content-wrap">
      <!-- uview-plus空状态组件 -->
      <u-empty
          v-if="!moduleList.length && !loading"
          mode="list"
          text="暂无菜单数据"
          color="#999"
          font-size="28rpx"
      ></u-empty>

      <!-- 菜单卡片列表(修复header插槽语法,恢复标题显示) -->
      <view v-else-if="!loading" class="menu-card-wrap">
        <up-card
            :title-size="18"
            v-for="(parentModule, index) in moduleList"
            :key="parentModule.id"
            :title="parentModule.name"
        >
          <template #body>
            <view>
              <up-grid
                  :border="false"
                  col="4"
              >
                <up-grid-item
                    v-for="(listItem,listIndex) in parentModule.children"
                    :key="listItem.id"
                    @click="handleMenuClick(listItem)"
                >
                  <u-image
                      :src="listItem.icon "
                      mode="aspectFit"
                      width="80rpx"
                      height="80rpx"
                      lazy-load
                      radius="16rpx"
                  ></u-image>
                  <text class="grid-text">{{ listItem.name }}</text>
                </up-grid-item>
              </up-grid>
              <up-toast ref="uToastRef"/>
            </view>
          </template>
        </up-card>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
// 原始代码完全保留,新增loading状态
import {ref, nextTick} from 'vue';
import { onShow } from '@dcloudio/uni-app';
import { useUserStore } from '@/pinia/user';
import globalConfig from '@/common/config/global';
import cache from '@/common/utils/cache';

interface MenuItem {
  id: number;
  name: string;
  subtitle?: string;
  type: number;
  sort: number;
  parentId: number;
  icon: string;
  jumpUrl: string;
  miniAppId?: string;
  badgeText?: string;
  badgeColor?: string;
  statisticCount: number | null;
  hasStatistic: boolean;
  extra: any;
  children: MenuItem[];
}

// 新增:加载状态(默认开启)
const loading = ref(true);
const userStore = useUserStore();
const moduleList = ref<MenuItem[]>([]);

// 无用变量(保留避免警告)
const subTitle = ref('');
const thumb = ref('');
const border = ref(true);
const click = () => {
};
const headClick = () => {
};

onShow(async () => {
  try {
    // 重置加载状态
    loading.value = true;

    const rawMenuData = userStore.moduleListInfo || cache.get(globalConfig.cache.moduleListKey);
    const menuData = rawMenuData || [];
    moduleList.value = menuData;

    // 关键:等待DOM完全渲染后再隐藏加载页
    await nextTick();
    // 额外延迟(可选,确保视觉更流畅)
    setTimeout(() => {
      loading.value = false;
    }, 300);

    console.log('菜单数据:', moduleList.value);
  } catch (error) {
    console.error('获取菜单数据失败:', error);
    moduleList.value = [];
    // 出错时也隐藏加载页
    await nextTick();
    loading.value = false;
  }
});

const handleMenuClick = (item: MenuItem) => {
  if (!item.jumpUrl) {
    uni.showToast({
      title: '暂无跳转链接',
      icon: 'none',
      duration: 2000
    });
    return;
  }
  console.log(item.jumpUrl)
  uni.navigateTo({
    url: item.jumpUrl,
    fail: (err) => {
      console.error('页面跳转失败:', err);
      uni.showToast({
        title: '页面路径错误',
        icon: 'none',
        duration: 2000
      });
    }
  });
};
</script>

<style scoped>
/* 仅新增/保留必要样式,不修改卡片核心样式 */
.workbench-container {
  width: 100%;
  min-height: 100vh;
  position: relative;
  background-color: #fff;
}

/* 蓝色块样式 */
.blue-decor-block {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 200px;
  background-color: #577ee3;
  z-index: 1;
}

/* 内容容器样式 */
.content-wrap {
  position: relative;
  z-index: 2;
  padding-top: 160px;
}

/* 第一张卡片层级 */
.first-card-position {
  position: relative;
  z-index: 3;
}

/* 仅补充标题文字基础样式(确保显示,不修改卡片其他样式) */
.card-title-text {
  font-size: 32rpx;
  color: #333;
  font-weight: 600;
}

/* 网格文字样式(保留原始) */
.grid-text {
  font-size: 24rpx;
  color: #333;
  text-align: center;
  margin-top: 10rpx;
}

/* 加载页样式优化(可选) */
:deep(.up-loading-page) {
  background-color: rgba(255, 255, 255, 0.9);
}
</style>