gaoluyang
3 天以前 e6a899cbf6d9cdf709d0f1deef91ff4d3f36abe8
进销存升级app:
1.添加菜单权限
已添加1个文件
已修改7个文件
392 ■■■■ 文件已修改
src/api/menu.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/cooperativeOffice/collaborativeApproval/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/index.vue 301 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/indexItem.vue 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/login.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages_template/pages/login/index2.vue 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/modules/user.ts 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/menu.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,9 @@
import request from '@/utils/request'
// èŽ·å–è·¯ç”±
export const getRouters = () => {
  return request({
    url: '/getRouters',
    method: 'get'
  })
}
src/pages.json
@@ -312,7 +312,7 @@
    {
      "path": "pages/cooperativeOffice/collaborativeApproval/index7",
      "style": {
        "navigationBarTitleText": "出库管理",
        "navigationBarTitleText": "发货审批",
        "navigationStyle": "custom"
      }
    },
src/pages/cooperativeOffice/collaborativeApproval/index.vue
@@ -157,7 +157,7 @@
      4: "报销管理",
      5: "采购管理",
      6: "报价管理",
      7: "出库管理",
      7: "发货审批",
      8: "危险作业管理",
    };
    return titleMap[type] || "审批管理";
src/pages/index.vue
@@ -38,7 +38,7 @@
    <!--            </view>-->
    <!--        </view>-->
    <!-- è¥é”€ç®¡ç†æ¨¡å— -->
    <view class="common-module marketing-module">
    <view class="common-module marketing-module" v-if="hasMarketingItems">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">营销管理</text>
@@ -62,7 +62,7 @@
      </view>
    </view>
    <!--    &lt;!&ndash; é‡‡è´­ç®¡ç†æ¨¡å— &ndash;&gt;-->
    <view class="common-module purchase-module">
    <view class="common-module purchase-module" v-if="hasPurchaseItems">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">采购管理</text>
@@ -86,7 +86,7 @@
      </view>
    </view>
    <!-- &lt;!&ndash; ååŒåŠžå…¬æ¨¡å— &ndash;&gt; -->
    <view class="common-module collaboration-module">
    <view class="common-module collaboration-module" v-if="hasCollaborationItems">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">协同办公</text>
@@ -110,7 +110,7 @@
      </view>
    </view>
    <!-- å®‰å…¨ç”Ÿäº§æ¨¡å— -->
    <view class="common-module collaboration-module">
    <view class="common-module collaboration-module" v-if="hasSafetyItems">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">安全生产</text>
@@ -134,7 +134,7 @@
      </view>
    </view>
    <!-- äººåŠ›èµ„æºæ¨¡å— -->
    <view class="common-module collaboration-module">
    <view class="common-module collaboration-module" v-if="hasHumanResourcesItems">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">人力资源</text>
@@ -158,36 +158,7 @@
      </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>
@@ -211,7 +182,7 @@
      </view>
    </view>
    <!-- è®¾å¤‡ç®¡ç†æ¨¡å— -->
    <view class="common-module equipment-module">
    <view class="common-module equipment-module" v-if="hasEquipmentItems">
      <view class="module-header">
        <view class="module-title-container">
          <text class="module-title">设备管理</text>
@@ -238,7 +209,7 @@
</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";
@@ -369,12 +340,8 @@
  // ååŒåŠžå…¬åŠŸèƒ½æ•°æ®
  const collaborationItems = reactive([
    {
      icon: "/static/images/icon/gongchuguanli@2x.png",
      label: "考勤管理",
    },
    {
      icon: "/static/images/icon/baoxiaoguanli.png",
      label: "财务管理",
      label: "协同审批",
    },
    {
      icon: "/static/images/icon/huiyiliebiao@2x.png",
@@ -396,10 +363,6 @@
      icon: "/static/images/icon/guizhangzhidu@2x.png",
      label: "规章制度",
    },
    // {
    //   icon: "/static/images/icon/xietongshenpi@2x.png",
    //   label: "协同审批",
    // },
    {
      icon: "/static/images/icon/kehubaifang@2x.png",
      label: "客户拜访",
@@ -452,26 +415,6 @@
    {
      icon: "/static/images/icon/shbeibaoyang@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",
    },
    {
      icon: "/static/images/icon/xunjianshangchuan@2x.png",
@@ -563,19 +506,39 @@
          url: "/pages/cooperativeOffice/collaborativeApproval/index4",
        });
        break;
      case "考勤管理":
      case "协同审批":
        uni.navigateTo({
          url: "/pages/indexItem?label=考勤管理",
        });
        break;
      case "财务管理":
        uni.navigateTo({
          url: "/pages/indexItem?label=财务管理",
          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 "采购管理":
@@ -588,7 +551,7 @@
          url: "/pages/cooperativeOffice/collaborativeApproval/index6",
        });
        break;
      case "出库管理":
      case "发货审批":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index7",
        });
@@ -626,37 +589,6 @@
      case "会议看板":
        uni.navigateTo({
          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 "生产订单":
@@ -910,6 +842,14 @@
      });
  };
  function loginSuccess(result) {
    // èŽ·å–è·¯ç”±æƒé™
    userStore.getRouters().then(() => {
      console.log("路由权限获取成功");
      // è¿‡æ»¤èœå•项
      filterMenuItemsByRoutes();
    }).catch(error => {
      console.error("获取路由权限失败:", error);
    });
    uni.reLaunch({
      url: "/pages/index",
    });
@@ -922,9 +862,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();
src/pages/indexItem.vue
@@ -56,15 +56,46 @@
    },
    {
      icon: "/static/images/icon/caigouguanli.png",
      label: "采购管理",
      label: "采购审批",
    },
    {
      icon: "/static/images/icon/baojiaguanli.png",
      label: "报价管理",
      label: "报价审批",
    },
    {
      icon: "/static/images/icon/chukuguanli@2x.png",
      label: "出库管理",
      label: "发货审批",
    },
  ]);
  // è€ƒå‹¤è´¢åŠ¡åˆå¹¶èœå•ï¼ˆè€ƒå‹¤3个 + è´¢åŠ¡4个 = 7个)
  const kaoqinCaiwu = reactive([
    {
      icon: "/static/images/icon/gongchuguanli@2x.png",
      label: "公出管理",
    },
    {
      icon: "/static/images/icon/qingjiaguanli@2x.png",
      label: "请假管理",
    },
    {
      icon: "/static/images/icon/chuchaiguanli@2x.png",
      label: "出差管理",
    },
    {
      icon: "/static/images/icon/baoxiaoguanli.png",
      label: "报销管理",
    },
    {
      icon: "/static/images/icon/caigouguanli.png",
      label: "采购审批",
    },
    {
      icon: "/static/images/icon/baojiaguanli.png",
      label: "报价审批",
    },
    {
      icon: "/static/images/icon/chukuguanli@2x.png",
      label: "发货审批",
    },
  ]);
@@ -183,17 +214,17 @@
          url: "/pages/cooperativeOffice/collaborativeApproval/index4",
        });
        break;
      case "采购管理":
      case "采购审批":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index5",
        });
        break;
      case "报价管理":
      case "报价审批":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index6",
        });
        break;
      case "出库管理":
      case "发货审批":
        uni.navigateTo({
          url: "/pages/cooperativeOffice/collaborativeApproval/index7",
        });
@@ -350,6 +381,9 @@
        commonItems.value = huiyi;
      } else if (operationType.value === "财务管理") {
        commonItems.value = caiwu;
      } else if (operationType.value === "协同审批") {
        commonItems.value = kaoqinCaiwu;
        operationType.value = "协同审批";
      }
    }
    console.log(operationType.value);
src/pages/login.vue
@@ -160,6 +160,12 @@
  function loginSuccess(result) {
    // è®¾ç½®ç”¨æˆ·ä¿¡æ¯
    userStore.getInfo().then(res => {
      // èŽ·å–è·¯ç”±æƒé™
      userStore.getRouters().then(() => {
        console.log("路由权限获取成功");
      }).catch(error => {
        console.error("获取路由权限失败:", error);
      });
      // ç™»å½•成功后,将客户端推送标识发送到服务器
      sendClientIdToServer();
      uni.switchTab({
src/pages_template/pages/login/index2.vue
@@ -199,9 +199,16 @@
  // ç™»å½•成功后,处理函数
  const loginSuccess = result => {
    // è®¾ç½®ç”¨æˆ·ä¿¡æ¯
    useUserStore()
    const userStore = useUserStore();
    userStore
      .getInfo()
      .then(res => {
        // èŽ·å–è·¯ç”±æƒé™
        userStore.getRouters().then(() => {
          console.log("路由权限获取成功");
        }).catch(error => {
          console.error("获取路由权限失败:", error);
        });
        // ç™»å½•成功后,将客户端推送标识发送到服务器
        sendClientIdToServer();
        tab.reLaunch("/pages/index");
src/store/modules/user.ts
@@ -1,4 +1,5 @@
import {logout, getInfo, loginCheckFactory} from "@/api/login";
import { getRouters as getRoutersApi } from "@/api/menu";
import { getToken, setToken, removeToken } from "@/utils/auth";
import defAva from "@/static/images/profile.jpg";
import { defineStore } from "pinia";
@@ -22,6 +23,7 @@
    currentLoginTime: "",
    roles: Array(),
    permissions: [],
    routers: [], // è·¯ç”±æƒé™æ•°æ®
  }),
  actions: {
    // éƒ¨é—¨ç™»å½•
@@ -75,6 +77,7 @@
            this.token = "";
            this.roles = [];
            this.permissions = [];
            this.routers = [];
            this.name = "";
            this.avatar = "";
            removeToken();
@@ -95,6 +98,20 @@
      const seconds = String(now.getSeconds()).padStart(2, '0');  // ç§’数补零
      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
    },
    // èŽ·å–è·¯ç”±æƒé™
    getRouters() {
      return new Promise((resolve, reject) => {
        getRoutersApi()
          .then((res: any) => {
            // å­˜å‚¨è·¯ç”±æƒé™æ•°æ®
            this.routers = res.data || [];
            resolve(res);
          })
          .catch((error) => {
            reject(error);
          });
      });
    },
  },
});