gaoluyang
3 天以前 919e8a4773ce188a6f91991837fd0bbd3f3c52e6
src/pages/index.vue
@@ -1,24 +1,24 @@
<template>
  <view class="content">
    <view class="header-section">
      <view class="currentFactory">
        <up-text type="primary"
                 :text="userStore.currentFactoryName"
                 @click="show = true"
                 size="18"
                 class="factoryName"
                 suffixIcon="arrow-right"
                 :iconStyle="iconStyle"></up-text>
      </view>
      <up-picker :show="show"
                 :columns="factoryList"
                 @confirm="changeFactory"
                 @cancel="show = false"></up-picker>
    </view>
    <!--    <view class="header-section">-->
    <!--      <view class="currentFactory">-->
    <!--        <up-text type="primary"-->
    <!--                 :text="userStore.currentFactoryName"-->
    <!--                 @click="show = true"-->
    <!--                 size="18"-->
    <!--                 class="factoryName"-->
    <!--                 suffixIcon="arrow-right"-->
    <!--                 :iconStyle="iconStyle"></up-text>-->
    <!--      </view>-->
    <!--      <up-picker :show="show"-->
    <!--                 :columns="factoryList"-->
    <!--                 @confirm="changeFactory"-->
    <!--                 @cancel="show = false"></up-picker>-->
    <!--    </view>-->
    <view class="hero-section">
      <view class="bg-img">
        <view class="hero-content">
          <text class="hero-title">军泰伟业</text>
          <!-- 预留:如后续需要可在此放 logo 或简短提示 -->
        </view>
        <view class="hero-wave"></view>
      </view>
@@ -38,55 +38,55 @@
    <!--         </view>-->
    <!--      </view>-->
    <!-- 营销管理模块 -->
    <!--    <view class="common-module marketing-module">-->
    <!--      <view class="module-header">-->
    <!--        <view class="module-title-container">-->
    <!--          <text class="module-title">营销管理</text>-->
    <!--        </view>-->
    <!--      </view>-->
    <!--      <view class="module-content">-->
    <!--        <up-grid :border="false"-->
    <!--                 col="4">-->
    <!--          <up-grid-item v-for="(item, index) in marketingItems"-->
    <!--                        :key="index"-->
    <!--                        @click="handleCommonItemClick(item)">-->
    <!--            <view class="icon-container"-->
    <!--                  :style="{ background: item.bgColor }">-->
    <!--              <up-icon :name="item.icon"-->
    <!--                       :size="58"-->
    <!--                       color="#ffffff"></up-icon>-->
    <!--            </view>-->
    <!--            <text class="item-label">{{item.label}}</text>-->
    <!--          </up-grid-item>-->
    <!--        </up-grid>-->
    <!--      </view>-->
    <!--    </view>-->
    <view class="common-module marketing-module" v-if="hasMarketingItems">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">营销管理</text>
        </view>
      </view>
      <view class="module-content">
        <up-grid :border="false"
                 col="4">
          <up-grid-item v-for="(item, index) in marketingItems"
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container"
                  :style="{ background: item.bgColor }">
              <up-icon :name="item.icon"
                       :size="58"
                       color="#ffffff"></up-icon>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
        </up-grid>
      </view>
    </view>
    <!--    &lt;!&ndash; 采购管理模块 &ndash;&gt;-->
    <!--    <view class="common-module purchase-module">-->
    <!--      <view class="module-header">-->
    <!--        <view class="module-title-container">-->
    <!--          <text class="module-title">采购管理</text>-->
    <!--        </view>-->
    <!--      </view>-->
    <!--      <view class="module-content">-->
    <!--        <up-grid :border="false"-->
    <!--                 col="4">-->
    <!--          <up-grid-item v-for="(item, index) in purchaseItems"-->
    <!--                        :key="index"-->
    <!--                        @click="handleCommonItemClick(item)">-->
    <!--            <view class="icon-container"-->
    <!--                  :style="{ background: item.bgColor }">-->
    <!--              <up-icon :name="item.icon"-->
    <!--                       :size="58"-->
    <!--                       color="#ffffff"></up-icon>-->
    <!--            </view>-->
    <!--            <text class="item-label">{{item.label}}</text>-->
    <!--          </up-grid-item>-->
    <!--        </up-grid>-->
    <!--      </view>-->
    <!--    </view>-->
    <!--    &lt;!&ndash; 协同办公模块 &ndash;&gt;-->
    <view class="common-module collaboration-module">
    <view class="common-module purchase-module" v-if="hasPurchaseItems">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">采购管理</text>
        </view>
      </view>
      <view class="module-content">
        <up-grid :border="false"
                 col="4">
          <up-grid-item v-for="(item, index) in purchaseItems"
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container"
                  :style="{ background: item.bgColor }">
              <up-icon :name="item.icon"
                       :size="58"
                       color="#ffffff"></up-icon>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
        </up-grid>
      </view>
    </view>
    <!-- &lt;!&ndash; 协同办公模块 &ndash;&gt; -->
    <view class="common-module collaboration-module" v-if="hasCollaborationItems">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">协同办公</text>
@@ -109,37 +109,56 @@
        </up-grid>
      </view>
    </view>
    <!-- 安全生产模块 -->
    <view class="common-module collaboration-module" v-if="hasSafetyItems">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">安全生产</text>
        </view>
      </view>
      <view class="module-content">
        <up-grid :border="false"
                 col="4">
          <up-grid-item v-for="(item, index) in safetyItems"
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container"
                  :style="{ background: item.bgColor }">
              <up-icon :name="item.icon"
                       :size="58"
                       color="#ffffff"></up-icon>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
        </up-grid>
      </view>
    </view>
    <!-- 人力资源模块 -->
    <view class="common-module collaboration-module" v-if="hasHumanResourcesItems">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">人力资源</text>
        </view>
      </view>
      <view class="module-content">
        <up-grid :border="false"
                 col="4">
          <up-grid-item v-for="(item, index) in humanResourcesItems"
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container"
                  :style="{ background: item.bgColor }">
              <up-icon :name="item.icon"
                       :size="58"
                       color="#ffffff"></up-icon>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
        </up-grid>
      </view>
    </view>
    <!-- 生产管控模块 -->
    <!--      <view class="common-module production-module">-->
    <!--         <view class="module-header">-->
    <!--            <view class="module-title-container">-->
    <!--               <text class="module-title">生产管控</text>-->
    <!--            </view>-->
    <!--         </view>-->
    <!--         <view class="module-content">-->
    <!--            <up-grid-->
    <!--               :border="false"-->
    <!--               col="4"-->
    <!--            >-->
    <!--               <up-grid-item-->
    <!--                  v-for="(item, index) in productionItems"-->
    <!--                  :key="index"-->
    <!--                  @click="handleCommonItemClick(item)"-->
    <!--               >-->
    <!--                  <view class="icon-container" :style="{ background: item.bgColor }">-->
    <!--                     <up-icon-->
    <!--                        :name="item.icon"-->
    <!--                        :size="58"-->
    <!--                        color="#ffffff"-->
    <!--                     ></up-icon>-->
    <!--                  </view>-->
    <!--                  <text class="item-label">{{item.label}}</text>-->
    <!--               </up-grid-item>-->
    <!--            </up-grid>-->
    <!--         </view>-->
    <!--      </view>-->
    <!-- 生产管控模块 -->
    <view class="common-module equipment-module">
    <view class="common-module equipment-module" v-if="hasProductionItems">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">生产管控</text>
@@ -163,41 +182,40 @@
      </view>
    </view>
    <!-- 设备管理模块 -->
    <!--    <view class="common-module equipment-module">-->
    <!--      <view class="module-header">-->
    <!--        <view class="module-title-container">-->
    <!--          <text class="module-title">设备管理</text>-->
    <!--        </view>-->
    <!--      </view>-->
    <!--      <view class="module-content">-->
    <!--        <up-grid :border="false"-->
    <!--                 col="4">-->
    <!--          <up-grid-item v-for="(item, index) in equipmentItems"-->
    <!--                        :key="index"-->
    <!--                        @click="handleCommonItemClick(item)">-->
    <!--            <view class="icon-container"-->
    <!--                  :style="{ background: item.bgColor }">-->
    <!--              <up-icon :name="item.icon"-->
    <!--                       :size="58"-->
    <!--                       color="#ffffff"></up-icon>-->
    <!--            </view>-->
    <!--            <text class="item-label">{{item.label}}</text>-->
    <!--          </up-grid-item>-->
    <!--        </up-grid>-->
    <!--      </view>-->
    <!--    </view>-->
    <view class="common-module equipment-module" v-if="hasEquipmentItems">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">设备管理</text>
        </view>
      </view>
      <view class="module-content">
        <up-grid :border="false"
                 col="4">
          <up-grid-item v-for="(item, index) in equipmentItems"
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container"
                  :style="{ background: item.bgColor }">
              <up-icon :name="item.icon"
                       :size="58"
                       color="#ffffff"></up-icon>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
        </up-grid>
      </view>
    </view>
  </view>
</template>
<script setup>
  import { ref, onMounted, nextTick, reactive } from "vue";
  import { ref, onMounted, nextTick, reactive, computed } from "vue";
  import { userLoginFacotryList } from "@/api/login";
  import { getProductWorkOrderById } from "@/api/productionManagement/productionReporting";
  import modal from "@/plugins/modal";
  import useUserStore from "@/store/modules/user";
  const userStore = useUserStore();
  const factoryId = ref("");
  const show = ref(false);
  const factoryList = ref([]);
  const factoryListTem = ref([]);
@@ -275,85 +293,76 @@
      label: "供应商往来",
    },
  ]);
  const humanResourcesItems = reactive([
    {
      icon: "/static/images/icon/caigoutaizhang@2x.png",
      label: "打卡签到",
    },
    {
      icon: "/static/images/icon/caigoutaizhang@2x.png",
      label: "人员薪资",
    },
  ]);
  const safetyItems = reactive([
    {
      icon: "/static/images/icon/caigoutaizhang@2x.png",
      label: "规程资质",
    },
    {
      icon: "/static/images/icon/caigoutaizhang@2x.png",
      label: "危险源台账",
    },
    {
      icon: "/static/images/icon/caigoutaizhang@2x.png",
      label: "危险作业",
    },
    {
      icon: "/static/images/icon/guzhangfenxi@2x.png",
      label: "隐患排查",
    },
    {
      icon: "/static/images/icon/guzhangfenxi@2x.png",
      label: "危险物料",
    },
    {
      icon: "/static/images/icon/guzhangfenxi@2x.png",
      label: "应急预案",
    },
    {
      icon: "/static/images/icon/guzhangfenxi@2x.png",
      label: "事故上报",
    },
    {
      icon: "/static/images/icon/guzhangfenxi@2x.png",
      label: "安全培训",
    },
  ]);
  // 协同办公功能数据
  const collaborationItems = reactive([
    {
      icon: "/static/images/icon/gongchuguanli@2x.png",
      label: "公出管理",
      icon: "/static/images/icon/baoxiaoguanli.png",
      label: "协同审批",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      label: "请假管理",
      icon: "/static/images/icon/huiyiliebiao@2x.png",
      label: "会议管理",
    },
    {
      icon: "/static/images/icon/chuchaiguanli@2x.png",
      label: "出差管理",
    },
    {
      icon: "/static/images/icon/chuchaiguanli@2x.png",
      label: "报销管理",
    },
    {
      icon: "/static/images/icon/chuchaiguanli@2x.png",
      label: "采购管理",
    },
    {
      icon: "/static/images/icon/chuchaiguanli@2x.png",
      label: "报价管理",
    },
    {
      icon: "/static/images/icon/chuchaiguanli@2x.png",
      label: "出库管理",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      label: "会议设置",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      label: "会议列表",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      label: "会议申请",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      label: "会议审批",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      label: "会议发布",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      label: "会议总结",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      label: "会议看板",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      icon: "/static/images/icon/tongzhigonggao@2x.png",
      label: "通知公告",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      icon: "/static/images/icon/zhishiku@2x.png",
      label: "知识库",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      icon: "/static/images/icon/yongyinguanli@2x.png",
      label: "用印管理",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      icon: "/static/images/icon/guizhangzhidu@2x.png",
      label: "规章制度",
    },
    // {
    //   icon: "/static/images/icon/xietongshenpi@2x.png",
    //   label: "协同审批",
    // },
    {
      icon: "/static/images/icon/kehubaifang@2x.png",
      label: "客户拜访",
@@ -397,6 +406,10 @@
    // },
    {
      icon: "/static/images/icon/shbeibaoxiu@2x.png",
      label: "运行管理",
    },
    {
      icon: "/static/images/icon/shbeibaoxiu@2x.png",
      label: "设备报修",
    },
    {
@@ -406,26 +419,6 @@
    {
      icon: "/static/images/icon/xunjianshangchuan@2x.png",
      label: "巡检上传",
    },
    {
      icon: "/static/images/icon/guzhangfenxi@2x.png",
      label: "分析追溯",
      bgColor: "#ff9800",
    },
    {
      icon: "/static/images/icon/zhinengpaidan@2x.png",
      label: "智能派单",
      bgColor: "#ff6b35",
    },
    {
      icon: "/static/images/icon/zuoyezhidao@2x.png",
      label: "作业指导",
      bgColor: "#4caf50",
    },
    {
      icon: "/static/images/icon/jieguoyanzheng@2x.png",
      label: "结果验证",
      bgColor: "#9c27b0",
    },
  ]);
@@ -513,6 +506,41 @@
          url: "/pages/cooperativeOffice/collaborativeApproval/index4",
        });
        break;
      case "协同审批":
        uni.navigateTo({
          url: "/pages/indexItem?label=协同审批",
        });
        break;
      case "会议管理":
        uni.navigateTo({
          url: "/pages/indexItem?label=会议管理",
        });
        break;
      case "通知公告":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/noticeManagement/index",
        });
        break;
      case "知识库":
        uni.navigateTo({
          url: "/pages/managementMeetings/knowledgeBase/index",
        });
        break;
      case "用印管理":
        uni.navigateTo({
          url: "/pages/managementMeetings/sealManagement/index",
        });
        break;
      case "规章制度":
        uni.navigateTo({
          url: "/pages/managementMeetings/rulesRegulationsManagement/index",
        });
        break;
      case "客户拜访":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/clientVisit/index",
        });
        break;
      case "采购管理":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index5",
@@ -523,7 +551,7 @@
          url: "/pages/cooperativeOffice/collaborativeApproval/index6",
        });
        break;
      case "出库管理":
      case "发货审批":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index7",
        });
@@ -563,37 +591,6 @@
          url: "/pages/managementMeetings/meetingBoard/index",
        });
        break;
      case "通知公告":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/noticeManagement/index",
        });
        break;
      case "知识库":
        uni.navigateTo({
          url: "/pages/managementMeetings/knowledgeBase/index",
        });
        break;
      case "用印管理":
        uni.navigateTo({
          url: "/pages/managementMeetings/sealManagement/index",
        });
        break;
      case "规章制度":
        uni.navigateTo({
          url: "/pages/managementMeetings/rulesRegulationsManagement/index",
        });
        break;
      case "协同审批":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index",
        });
        break;
      case "客户拜访":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/clientVisit/index",
        });
        break;
      case "生产订单":
        uni.navigateTo({
          url: "/pages/productionManagement/productionOrder/index",
@@ -620,6 +617,11 @@
      case "设备台账":
        uni.navigateTo({
          url: "/pages/equipmentManagement/ledger/index",
        });
        break;
      case "运行管理":
        uni.navigateTo({
          url: "/pages/equipmentManagement/runManagement/index",
        });
        break;
      case "设备报修":
@@ -657,6 +659,56 @@
          url: "/pages/equipmentManagement/verification/index",
        });
        break;
      case "规程资质":
        uni.navigateTo({
          url: "/pages/safeProduction/safeQualifications/index",
        });
        break;
      case "危险源台账":
        uni.navigateTo({
          url: "/pages/safeProduction/hazardSourceLedger/index",
        });
        break;
      case "危险作业":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index8",
        });
        break;
      case "隐患排查":
        uni.navigateTo({
          url: "/pages/safeProduction/dangerInvestigation/index",
        });
        break;
      case "危险物料":
        uni.navigateTo({
          url: "/pages/safeProduction/hazardousMaterialsControl/index",
        });
        break;
      case "应急预案":
        uni.navigateTo({
          url: "/pages/safeProduction/emergencyPlanReview/index",
        });
        break;
      case "事故上报":
        uni.navigateTo({
          url: "/pages/safeProduction/accidentReportingRecord/index",
        });
        break;
      case "安全培训":
        uni.navigateTo({
          url: "/pages/safeProduction/safetyTrainingAssessment/index",
        });
        break;
      case "打卡签到":
        uni.navigateTo({
          url: "/pages/humanResources/attendance/checkin",
        });
        break;
      case "人员薪资":
        uni.navigateTo({
          url: "/pages/humanResources/monthlyStatistics/index",
        });
        break;
      default:
        uni.showToast({
          title: `点击了${item.label}`,
@@ -678,7 +730,6 @@
          res.data.forEach(item => {
            factoryList.value[0].push(item.deptName);
          });
          factoryId.value = userStore.currentDeptId;
        } else {
          // 如果res.data不是数组,设置为空数组
          factoryList.value = [];
@@ -781,7 +832,6 @@
    const loginForm = {
      username: userStore.name,
      password: uni.getStorageSync("remembered_password"),
      factoryId: factoryId,
    };
    modal.loading("刷新中,请耐心等待...");
    userStore
@@ -797,6 +847,14 @@
      });
  };
  function loginSuccess(result) {
    // 获取路由权限
    userStore.getRouters().then(() => {
      console.log("路由权限获取成功");
      // 过滤菜单项
      filterMenuItemsByRoutes();
    }).catch(error => {
      console.error("获取路由权限失败:", error);
    });
    uni.reLaunch({
      url: "/pages/index",
    });
@@ -809,9 +867,156 @@
    }
  };
  // 根据路由权限过滤菜单项
  const filterMenuItemsByRoutes = () => {
    const routers = userStore.routers || [];
    // 如果没有路由权限数据,不进行过滤(显示所有菜单)
    if (!routers || routers.length === 0) {
      console.log("暂无路由权限数据,显示所有菜单");
      return;
    }
    // 收集所有有权限的菜单标题(根据 meta.title)
    const allowedMenuTitles = new Set();
    const collectMenuTitles = (routes) => {
      if (!Array.isArray(routes)) return;
      routes.forEach(route => {
        // 收集当前路由的标题
        if (route.meta && route.meta.title) {
          allowedMenuTitles.add(route.meta.title);
        }
        // 递归处理子路由
        if (route.children && route.children.length > 0) {
          collectMenuTitles(route.children);
        }
      });
    };
    collectMenuTitles(routers);
    console.log("允许的菜单标题:", Array.from(allowedMenuTitles));
    console.log("过滤前 - 营销管理:", marketingItems.length, "采购管理:", purchaseItems.length, "协同办公:", collaborationItems.length);
    console.log("过滤前 - 安全生产:", safetyItems.length, "人力资源:", humanResourcesItems.length, "生产管控:", productionItems.length, "设备管理:", equipmentItems.length);
    // 过滤营销管理菜单
    const originalMarketing = [
      { icon: "/static/images/icon/xiaoshoutaizhang@2x.png", label: "销售台账" },
      { icon: "/static/images/icon/kaipiaodengji@2x.png", label: "开票登记" },
      { icon: "/static/images/icon/kaipiaotaizhang@2x.png", label: "开票台账" },
      { icon: "/static/images/icon/huikuandengji@2x.png", label: "回款登记" },
      { icon: "/static/images/icon/huikuanliushui@2x.png", label: "回款流水" },
      { icon: "/static/images/icon/kehuwanglai@2x.png", label: "客户往来" },
    ];
    const filteredMarketing = originalMarketing.filter(item => {
      return allowedMenuTitles.has(item.label);
    });
    marketingItems.splice(0, marketingItems.length, ...filteredMarketing);
    // 过滤协同办公菜单
    const originalCollaboration = [
      { icon: "/static/images/icon/baoxiaoguanli.png", label: "协同审批" },
      { icon: "/static/images/icon/huiyiliebiao@2x.png", label: "会议管理" },
      { icon: "/static/images/icon/tongzhigonggao@2x.png", label: "通知公告" },
      { icon: "/static/images/icon/zhishiku@2x.png", label: "知识库" },
      { icon: "/static/images/icon/yongyinguanli@2x.png", label: "用印管理" },
      { icon: "/static/images/icon/guizhangzhidu@2x.png", label: "规章制度" },
      { icon: "/static/images/icon/kehubaifang@2x.png", label: "客户拜访" },
    ];
    const filteredCollaboration = originalCollaboration.filter(item => {
      // 处理标题不完全匹配的情况
      let matched = allowedMenuTitles.has(item.label);
      // 特殊处理:规章制度 -> 规章制度管理
      if (!matched && item.label === "规章制度") {
        matched = allowedMenuTitles.has("规章制度管理");
      }
      return matched;
    });
    collaborationItems.splice(0, collaborationItems.length, ...filteredCollaboration);
    // 过滤采购管理菜单
    const originalPurchase = [
      { icon: "/static/images/icon/caigoutaizhang@2x.png", label: "采购台账" },
      { icon: "/static/images/icon/laipiaodengji@2x.png", label: "来票登记" },
      { icon: "/static/images/icon/laipiaotaizhang@2x.png", label: "来票台账" },
      { icon: "/static/images/icon/fukuanjingji@2x.png", label: "付款登记" },
      { icon: "/static/images/icon/fukuanliushui@2x.png", label: "付款流水" },
      { icon: "/static/images/icon/gongyingshangwanglai@2x.png", label: "供应商往来" },
    ];
    const filteredPurchase = originalPurchase.filter(item => {
      return allowedMenuTitles.has(item.label);
    });
    purchaseItems.splice(0, purchaseItems.length, ...filteredPurchase);
    // 过滤安全生产菜单
    const originalSafety = [
      { icon: "/static/images/icon/caigoutaizhang@2x.png", label: "规程资质" },
      { icon: "/static/images/icon/caigoutaizhang@2x.png", label: "危险源台账" },
      { icon: "/static/images/icon/caigoutaizhang@2x.png", label: "危险作业" },
      { icon: "/static/images/icon/guzhangfenxi@2x.png", label: "隐患排查" },
      { icon: "/static/images/icon/guzhangfenxi@2x.png", label: "危险物料" },
      { icon: "/static/images/icon/guzhangfenxi@2x.png", label: "应急预案" },
      { icon: "/static/images/icon/guzhangfenxi@2x.png", label: "事故上报" },
      { icon: "/static/images/icon/guzhangfenxi@2x.png", label: "安全培训" },
    ];
    const filteredSafety = originalSafety.filter(item => {
      return allowedMenuTitles.has(item.label);
    });
    safetyItems.splice(0, safetyItems.length, ...filteredSafety);
    // 过滤人力资源菜单
    const originalHumanResources = [
      { icon: "/static/images/icon/caigoutaizhang@2x.png", label: "打卡签到" },
      { icon: "/static/images/icon/caigoutaizhang@2x.png", label: "人员薪资" },
    ];
    const filteredHumanResources = originalHumanResources.filter(item => {
      return allowedMenuTitles.has(item.label);
    });
    humanResourcesItems.splice(0, humanResourcesItems.length, ...filteredHumanResources);
    // 过滤生产管控菜单
    const originalProduction = [
      { icon: "/static/images/icon/shengchanbaogong@2x.png", label: "生产报工", bgColor: "#673AB7" },
    ];
    const filteredProduction = originalProduction.filter(item => {
      return allowedMenuTitles.has(item.label);
    });
    productionItems.splice(0, productionItems.length, ...filteredProduction);
    // 过滤设备管理菜单
    const originalEquipment = [
      { icon: "/static/images/icon/shbeibaoxiu@2x.png", label: "运行管理" },
      { icon: "/static/images/icon/shbeibaoxiu@2x.png", label: "设备报修" },
      { icon: "/static/images/icon/shbeibaoyang@2x.png", label: "设备保养" },
      { icon: "/static/images/icon/xunjianshangchuan@2x.png", label: "巡检上传" },
    ];
    const filteredEquipment = originalEquipment.filter(item => {
      return allowedMenuTitles.has(item.label);
    });
    equipmentItems.splice(0, equipmentItems.length, ...filteredEquipment);
    console.log("过滤后 - 营销管理:", marketingItems.length, "采购管理:", purchaseItems.length, "协同办公:", collaborationItems.length);
    console.log("过滤后 - 安全生产:", safetyItems.length, "人力资源:", humanResourcesItems.length, "生产管控:", productionItems.length, "设备管理:", equipmentItems.length);
    console.log("生产管控菜单项:", productionItems.map(item => item.label));
  };
  // 检查模块是否有菜单项需要显示
  const hasMarketingItems = computed(() => marketingItems.length > 0);
  const hasPurchaseItems = computed(() => purchaseItems.length > 0);
  const hasCollaborationItems = computed(() => collaborationItems.length > 0);
  const hasSafetyItems = computed(() => safetyItems.length > 0);
  const hasHumanResourcesItems = computed(() => humanResourcesItems.length > 0);
  const hasProductionItems = computed(() => productionItems.length > 0);
  const hasEquipmentItems = computed(() => equipmentItems.length > 0);
  onMounted(() => {
    // 设置用户信息
    userStore.getInfo();
    // 每次进入首页都强制刷新用户信息和路由权限,不做本地缓存判断
    userStore.getInfo().then(() => {
      userStore.getRouters().then(() => {
        filterMenuItemsByRoutes();
      }).catch(error => {
        console.error("获取路由权限失败:", error);
      });
    });
    getUserLoginFacotryList();
    // 启动通知状态定时器
    startStatusTimer();
@@ -821,24 +1026,21 @@
<style scoped lang="scss">
  .content {
    background: linear-gradient(135deg, #f8f9fa 0%, #e3f2fd 100%);
    background: #f6f7fb;
    min-height: 100vh;
    padding: 1.25rem;
    /* 为所有设备设置基础padding-top */
    padding-top: 40px;
    padding: 12px;
    /* 为所有设备设置基础padding-top(包含安全区) */
    padding-top: calc(env(safe-area-inset-top) + 30px);
    position: relative;
    /* iOS设备使用env()函数处理安全区域 */
    padding-top: env(safe-area-inset-top);
    /* 为安卓设备设置更大的顶部内边距 */
    /* #ifdef APP-PLUS && !MP && !H5 */
    padding-top: 45px;
    padding-top: calc(env(safe-area-inset-top) + 45px);
    /* #endif */
    /* H5和小程序平台的通用样式 */
    /* #ifdef H5 || MP */
    padding-top: 30px;
    padding-top: calc(env(safe-area-inset-top) + 30px);
    /* #endif */
    &::before {
@@ -848,7 +1050,7 @@
      left: 0;
      right: 0;
      bottom: 0;
      background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="dots" width="20" height="20" patternUnits="userSpaceOnUse"><circle cx="10" cy="10" r="1" fill="rgba(41, 121, 255, 0.03)"/></pattern></defs><rect width="100" height="100" fill="url(%23dots)"/></svg>');
      background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="dots" width="24" height="24" patternUnits="userSpaceOnUse"><circle cx="12" cy="12" r="1" fill="rgba(41, 121, 255, 0.02)"/></pattern></defs><rect width="100" height="100" fill="url(%23dots)"/></svg>');
      pointer-events: none;
      z-index: -1;
    }
@@ -863,12 +1065,12 @@
      background: radial-gradient(
          circle at 20% 80%,
          rgba(41, 121, 255, 0.02) 0%,
          transparent 50%
          transparent 55%
        ),
        radial-gradient(
          circle at 80% 20%,
          rgba(156, 39, 176, 0.02) 0%,
          transparent 50%
          rgba(156, 39, 176, 0.015) 0%,
          transparent 55%
        );
      pointer-events: none;
      z-index: -1;
@@ -900,19 +1102,19 @@
  }
  .hero-section {
    margin-bottom: 1rem;
    margin-bottom: 12px;
    animation: fadeInUp 0.6s ease-out 0.1s both;
  }
  .bg-img {
    width: 100%;
    height: 8.75rem;
    height: 9.25rem;
    background-image: url("../static/images/banner/backview.png");
    background-size: cover;
    border-radius: 0.75rem;
    border-radius: 14px;
    position: relative;
    overflow: hidden;
    box-shadow: 0 0.25rem 1.25rem rgba(41, 121, 255, 0.15);
    box-shadow: 0 10px 26px rgba(17, 24, 39, 0.08);
    &::before {
      content: "";
@@ -952,35 +1154,11 @@
  .hero-content {
    position: relative;
    z-index: 1;
    padding: 1.25rem 1.25rem 1.6rem 1.25rem;
    padding: 14px 14px 18px 14px;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
  }
  .hero-title {
    color: #ffffff;
    font-size: 1.625rem;
    font-weight: 700;
    letter-spacing: 0.03125rem;
    text-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.5);
  }
  .hero-subtitle {
    font-size: 0.8125rem;
    margin-top: 0.375rem;
  }
  .hero-wave {
    height: 2.75rem;
  }
  .hero-subtitle {
    color: rgba(255, 255, 255, 0.9);
    font-size: 0.8125rem;
    margin-top: 0.375rem;
    font-weight: 400;
    text-shadow: 0 0.0625rem 0.125rem rgba(0, 0, 0, 0.5);
  }
  .hero-wave {
@@ -1150,11 +1328,11 @@
  /* 功能模块样式 */
  .common-module {
    margin-bottom: 1.5rem;
    background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%);
    border-radius: 1rem;
    padding: 1rem;
    box-shadow: 0 0.25rem 1.25rem rgba(0, 0, 0, 0.06);
    margin-bottom: 12px;
    background: linear-gradient(135deg, #ffffff 0%, #f9fbff 100%);
    border-radius: 14px;
    padding: 12px;
    box-shadow: 0 8px 22px rgba(17, 24, 39, 0.06);
    border: none;
    position: relative;
    overflow: hidden;
@@ -1198,7 +1376,7 @@
  }
  .module-header {
    margin-bottom: 1.5rem;
    margin-bottom: 10px;
    display: flex;
    align-items: center;
    justify-content: space-between;
@@ -1211,7 +1389,7 @@
  .module-title {
    color: #333333;
    font-size: 1.125rem;
    font-size: 16px;
    font-weight: 600;
    position: relative;
  }
@@ -1226,18 +1404,18 @@
  .module-content {
    width: 100%;
    display: grid;
    gap: 1rem;
    gap: 10px;
  }
  .icon-container {
    width: 3.25rem;
    height: 3.25rem;
    border-radius: 0.75rem;
    width: 46px;
    height: 46px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 0.375rem;
    box-shadow: 0 0.1875rem 0.75rem rgba(0, 0, 0, 0.12);
    box-shadow: 0 10px 20px rgba(17, 24, 39, 0.12);
    transition: all 0.2s ease;
    position: relative;
    overflow: hidden;
@@ -1295,14 +1473,22 @@
  }
  .item-label {
    font-size: 0.8125rem;
    font-size: 12px;
    color: #555555;
    text-align: center;
    display: block;
    line-height: 1.4;
    font-weight: 500;
    margin-top: 0.25rem;
    margin-bottom: 0.625rem;
    margin-top: 4px;
    margin-bottom: 6px;
  }
  /* grid-item 间距更紧凑且视觉更居中 */
  :deep(.up-grid-item) {
    padding: 6px 0;
  }
  :deep(.up-grid-item__content) {
    padding: 0;
  }
  .grid-text {
@@ -1420,30 +1606,34 @@
  }
  .common-module {
    margin-bottom: 1.5rem;
    background: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%);
    border-radius: 1rem;
    padding: 1rem;
    box-shadow: 0 0.25rem 1.25rem rgba(0, 0, 0, 0.06);
    border: none;
    margin-bottom: 12px;
    background: #ffffff;
    border-radius: 16px;
    padding: 12px;
    box-shadow: 0 10px 28px rgba(15, 23, 42, 0.06);
    border: 1px solid rgba(148, 163, 184, 0.18);
    position: relative;
    overflow: hidden;
    transition: all 0.3s ease;
    transition: all 0.22s ease;
    &::after {
      content: "";
      position: absolute;
      top: 0;
      right: 0;
      width: 3.75rem;
      height: 3.75rem;
      top: -40px;
      right: -40px;
      width: 90px;
      height: 90px;
      background: radial-gradient(
        circle,
        rgba(0, 0, 0, 0.02) 0%,
        rgba(148, 163, 184, 0.08) 0%,
        transparent 70%
      );
      border-radius: 50%;
      transform: translate(1.875rem, -1.875rem);
    }
    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 14px 32px rgba(15, 23, 42, 0.12);
    }
  }
@@ -1468,7 +1658,7 @@
  }
  .module-header {
    margin-bottom: 1.5rem;
    margin-bottom: 10px;
    display: flex;
    align-items: center;
    justify-content: space-between;
@@ -1480,54 +1670,70 @@
  }
  .module-title {
    color: #333333;
    font-size: 1.125rem;
    color: #1f2933;
    font-size: 16px;
    font-weight: 600;
    position: relative;
  }
  .module-subtitle {
    color: #666666;
    font-size: 0.75rem;
    font-weight: 400;
    margin-left: 0.5rem;
  }
  .module-content {
    width: 100%;
    display: grid;
    gap: 1rem;
    gap: 10px;
  }
  .icon-container {
    width: 3.25rem;
    height: 3.25rem;
    border-radius: 0.75rem;
    width: 52px;
    height: 52px;
    border-radius: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 0.375rem;
    box-shadow: 0 0.1875rem 0.75rem rgba(0, 0, 0, 0.12);
    transition: all 0.2s ease;
    margin-bottom: 4px;
    box-shadow: 0 10px 20px rgba(15, 23, 42, 0.18);
    transition: all 0.18s ease;
    position: relative;
    overflow: hidden;
    animation: fadeInScale 0.5s ease both;
    background: linear-gradient(135deg, #3b82f6, #2563eb);
  }
    &:hover {
      transform: translateY(-0.1875rem) scale(1.02);
      box-shadow: 0 0.5rem 1.5625rem rgba(0, 0, 0, 0.18);
    }
  .marketing-module .icon-container {
    background: linear-gradient(135deg, #3b82f6, #2563eb);
  }
  .purchase-module .icon-container {
    background: linear-gradient(135deg, #1d4ed8, #0f766e);
  }
  .collaboration-module .icon-container {
    background: linear-gradient(135deg, #22c55e, #16a34a);
  }
  .equipment-module .icon-container {
    background: linear-gradient(135deg, #a855f7, #7c3aed);
  }
    &:active {
      transform: scale(0.97);
      box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.18);
    }
  .icon-container::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: radial-gradient(
      circle at 20% 20%,
      rgba(255, 255, 255, 0.26),
      transparent 55%
    );
    opacity: 0.8;
    pointer-events: none;
  }
  .icon-container:active {
    transform: scale(0.94);
    box-shadow: 0 4px 14px rgba(15, 23, 42, 0.25);
  }
  .item-label {
    font-size: 0.8125rem;
    margin-top: 0.25rem;
    margin-bottom: 0.625rem;
    font-size: 12px;
    margin-top: 4px;
    margin-bottom: 6px;
  }
  .grid-text {
    font-size: 0.875rem;