gaoluyang
2026-06-16 a9d97b150701e634bdb751eab277696abd136cca
src/pages/works.vue
@@ -15,7 +15,8 @@
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container">
              <image :src="item.icon" class="item-icon"></image>
              <image :src="item.icon"
                     class="item-icon"></image>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
@@ -37,7 +38,31 @@
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container">
              <image :src="item.icon" class="item-icon"></image>
              <image :src="item.icon"
                     class="item-icon"></image>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
        </up-grid>
      </view>
    </view>
    <!-- 工艺设计 -->
    <view class="common-module design-module"
          v-if="hasDesignItems">
      <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 designItems"
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container">
              <image :src="item.icon"
                     class="item-icon"></image>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
@@ -59,7 +84,8 @@
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container">
              <image :src="item.icon" class="item-icon"></image>
              <image :src="item.icon"
                     class="item-icon"></image>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
@@ -81,7 +107,8 @@
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container">
              <image :src="item.icon" class="item-icon"></image>
              <image :src="item.icon"
                     class="item-icon"></image>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
@@ -103,7 +130,8 @@
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container">
              <image :src="item.icon" class="item-icon"></image>
              <image :src="item.icon"
                     class="item-icon"></image>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
@@ -125,7 +153,8 @@
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container">
              <image :src="item.icon" class="item-icon"></image>
              <image :src="item.icon"
                     class="item-icon"></image>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
@@ -147,7 +176,8 @@
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container">
              <image :src="item.icon" class="item-icon"></image>
              <image :src="item.icon"
                     class="item-icon"></image>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
@@ -169,7 +199,8 @@
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container">
              <image :src="item.icon" class="item-icon"></image>
              <image :src="item.icon"
                     class="item-icon"></image>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
@@ -191,7 +222,8 @@
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container">
              <image :src="item.icon" class="item-icon"></image>
              <image :src="item.icon"
                     class="item-icon"></image>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
@@ -213,7 +245,8 @@
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container">
              <image :src="item.icon" class="item-icon"></image>
              <image :src="item.icon"
                     class="item-icon"></image>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
@@ -235,7 +268,8 @@
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container">
              <image :src="item.icon" class="item-icon"></image>
              <image :src="item.icon"
                     class="item-icon"></image>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
@@ -257,20 +291,22 @@
                        :key="index"
                        @click="handleCommonItemClick(item)">
            <view class="icon-container">
              <image :src="item.icon" class="item-icon"></image>
              <image :src="item.icon"
                     class="item-icon"></image>
            </view>
            <text class="item-label">{{item.label}}</text>
          </up-grid-item>
        </up-grid>
      </view>
    </view>
    <DownloadProgressMask />
  </view>
</template>
<script setup>
  import { ref, onMounted, nextTick, reactive, computed } from "vue";
  import { userLoginFacotryList } from "@/api/login";
  import { getProductWorkOrderById } from "@/api/productionManagement/productionReporting";
  import DownloadProgressMask from "@/components/DownloadProgressMask.vue";
  import modal from "@/plugins/modal";
  import useUserStore from "@/store/modules/user";
@@ -296,6 +332,25 @@
      currentStatus.value = statusList[statusIndex];
    }, 3000);
  };
  // 工艺设计功能数据
  const designItems = reactive([
    {
      icon: "/static/images/icon/jichucanshu.svg",
      label: "基础参数",
    },
    {
      icon: "/static/images/icon/gongxuguanli.svg",
      label: "工序管理",
    },
    // {
    //   icon: "/static/images/icon/bom.svg",
    //   label: "BOM",
    // },
    {
      icon: "/static/images/icon/gongyiluxian.svg",
      label: "工艺路线",
    },
  ]);
  // 营销管理功能数据
  const marketingItems = reactive([
@@ -303,10 +358,10 @@
      icon: "/static/images/icon/kehudangan.svg",
      label: "客户档案",
    },
    {
      icon: "/static/images/icon/xiaoshoubaojia.svg",
      label: "销售报价",
    },
    // {
    //   icon: "/static/images/icon/xiaoshoubaojia.svg",
    //   label: "销售报价",
    // },
    {
      icon: "/static/images/icon/xiaoshoutaizhang.svg",
      label: "销售台账",
@@ -330,6 +385,10 @@
    {
      icon: "/static/images/icon/caigouguanli.svg",
      label: "采购退货",
    },
    {
      icon: "/static/images/icon/gongyingshangdangan.svg",
      label: "供应商档案",
    },
  ]);
@@ -384,8 +443,12 @@
  // 档案管理功能数据
  const archiveManagementItems = reactive([
    {
      icon: "/static/images/icon/gongyingshangdangan.svg",
      label: "供应商档案",
      icon: "/static/images/icon/jieyuedengji.svg",
      label: "借阅登记",
    },
    {
      icon: "/static/images/icon/guihuandengji.svg",
      label: "归还登记",
    },
  ]);
@@ -404,7 +467,7 @@
  // 仓储物流功能数据
  const warehouseLogisticsItems = reactive([
    {
      icon: "/static/images/icon/xiaoshoutaizhang.svg",
      icon: "/static/images/icon/kucunguanli.svg",
      label: "库存管理",
    },
  ]);
@@ -421,6 +484,21 @@
    {
      icon: "/static/images/icon/hetongguanli.svg",
      label: "合同管理",
    },
    {
      icon: "/static/images/icon/hetongguanli.svg",
      label: "转正申请",
      path: "/pages/oa/HrManage/regular-apply/index",
    },
    {
      icon: "/static/images/icon/renyuanxinzi.svg",
      label: "调动申请",
      path: "/pages/oa/HrManage/transfer-apply/index",
    },
    {
      icon: "/static/images/icon/gongchuguanli.svg",
      label: "工作交接",
      path: "/pages/oa/HrManage/work-handover/index",
    },
  ]);
  const qualityItems = reactive([
@@ -473,10 +551,20 @@
  ]);
  // 协同办公功能数据
  const collaborationItems = reactive([
    {
      icon: "/static/images/icon/xietongshenpi.svg",
      label: "协同审批",
    },
    // {
    //   icon: "/static/images/icon/xietongshenpi.svg",
    //   label: "协同审批",
    // },
      {
         icon: "/static/images/icon/guizhangzhidu.svg",
         label: "审批管理",
         path: "/pages/oa/ApproveManage/approve-template/index",
      },
      {
         icon: "/static/images/icon/xietongshenpi.svg",
         label: "协同审批",
         path: "/pages/oa/ApproveManage/approve-list/index",
      },
    {
      icon: "/static/images/icon/huiyiguanli.svg",
      label: "会议管理",
@@ -501,34 +589,63 @@
      icon: "/static/images/icon/kehubaifang.svg",
      label: "客户拜访",
    },
    {
      icon: "/static/images/icon/qingjiaguanli.svg",
      label: "请假申请",
      path: "/pages/oa/AttendManage/leave-apply/index",
    },
    {
      icon: "/static/images/icon/dakaqiandao.svg",
      label: "加班申请",
      path: "/pages/oa/AttendManage/overtime-apply/index",
    },
    {
      icon: "/static/images/icon/chuchaiguanli.svg",
      label: "差旅报销",
      path: "/pages/oa/ReimburseManage/travel-reimburse/index",
    },
    {
      icon: "/static/images/icon/baoxiaoguanli.svg",
      label: "费用报销",
      path: "/pages/oa/ReimburseManage/cost-reimburse/index",
    },
  ]);
  // 生产管控功能数据
  const productionItems = reactive([
    // {
    //   icon: "/static/images/icon/shengchandingdan@2x.svg",
    //   label: "生产订单",
    // },
    // {
    //   icon: "/static/images/icon/shengchanpaigong@2x.svg",
    //   label: "生产派工",
    // },
    // {
    //   icon: "/static/images/icon/shengchanpaichan@2x.svg",
    //   label: "工序排产",
    // },
    {
      icon: "/static/images/icon/shengchanjihua.svg",
      label: "主生产计划",
    },
    {
      icon: "/static/images/icon/shengchandingdan.svg",
      label: "生产订单",
    },
    {
      icon: "/static/images/icon/shengchanzhuisu.svg",
      label: "生产追溯",
    },
    {
      icon: "/static/images/icon/shengchanshikuang.svg",
      label: "工序生产实况",
    },
    {
      icon: "/static/images/icon/shengchanpaichan.svg",
      label: "生产排产",
    },
    {
      icon: "/static/images/icon/shengchanbaogong.svg",
      label: "生产报工",
    },
    {
      icon: "/static/images/icon/shengchanbaogong.svg",
      label: "生产工单",
      icon: "/static/images/icon/baogongtaizhang.svg",
      label: "报工台账",
    },
    // {
    //   icon: "/static/images/icon/shengchanhesuan@2x.svg",
    //   label: "生产核算",
    // },
    {
      icon: "/static/images/icon/shengchanhesuan.svg",
      label: "生产核算",
    },
  ]);
  // 设备管理功能数据
@@ -557,6 +674,10 @@
  // 处理常用功能点击
  const handleCommonItemClick = item => {
    if (item.path) {
      uni.navigateTo({ url: item.path });
      return;
    }
    // 根据不同的功能项进行跳转
    switch (item.label) {
      case "客户档案":
@@ -769,9 +890,9 @@
          url: "/pages/productionManagement/productionDispatching/index",
        });
        break;
      case "工序排产":
      case "工艺路线":
        uni.navigateTo({
          url: "/pages/productionManagement/processScheduling/index",
          url: "/pages/productionManagement/processRoute/index",
        });
        break;
      case "生产工单":
@@ -779,12 +900,39 @@
          url: "/pages/productionManagement/workOrder/index",
        });
        break;
      case "主生产计划":
        uni.navigateTo({
          url: "/pages/productionManagement/mainProductionPlan/index",
        });
        break;
      case "生产排产":
        uni.navigateTo({
          url: "/pages/productionManagement/productionScheduling/index",
        });
        break;
      case "生产报工":
        getcode();
        uni.navigateTo({
          url: "/pages/productionManagement/workOrder/index",
        });
        break;
      case "报工台账":
        uni.navigateTo({
          url: "/pages/productionManagement/productionReporting/ledger",
        });
        break;
      case "生产核算":
        uni.navigateTo({
          url: "/pages/productionManagement/productionAccounting/index",
        });
        break;
      case "生产追溯":
        uni.navigateTo({
          url: "/pages/productionManagement/productionTraceability/index",
        });
        break;
      case "工序生产实况":
        uni.navigateTo({
          url: "/pages/productionManagement/processStatistics/index",
        });
        break;
      case "设备台账":
@@ -917,6 +1065,31 @@
          url: "/pages/customerService/afterSalesHandling/index",
        });
        break;
      case "借阅登记":
        uni.navigateTo({
          url: "/pages/fileManagement/borrow/index",
        });
        break;
      case "归还登记":
        uni.navigateTo({
          url: "/pages/fileManagement/return/index",
        });
        break;
      case "基础参数":
        uni.navigateTo({
          url: "/pages/productionDesign/basicParameters/index",
        });
        break;
      case "工序管理":
        uni.navigateTo({
          url: "/pages/productionDesign/processManagement/index",
        });
        break;
      case "BOM":
        uni.navigateTo({
          url: "/pages/productionDesign/bom/index",
        });
        break;
      default:
        uni.showToast({
          title: `点击了${item.label}`,
@@ -948,90 +1121,6 @@
        factoryList.value = [];
      });
  }
  const getcode = () => {
    uni.scanCode({
      success: async res => {
        // 解析二维码内容
        const scanResult = res.result;
        let orderRow = "";
        // 判断扫描结果是否为纯数字(id)
        const isNumericId = /^\d+$/.test(scanResult.trim());
        if (isNumericId) {
          // 如果是纯数字,根据 id 获取工单数据
          const workOrderId = scanResult.trim();
          modal.loading("正在获取工单信息...");
          try {
            const workRes = await getProductWorkOrderById({ id: workOrderId });
            modal.closeLoading();
            console.log("工单查询结果:", workRes);
            if (workRes.code === 200 && workRes.data) {
              // 新接口返回的是单个对象,不是数组
              const workData = workRes.data;
              console.log("工单数据:", workData);
              orderRow = JSON.stringify({
                id: workData.id || workOrderId,
                planQuantity: workData.planQuantity - workData.completeQuantity,
                productProcessRouteItemId:
                  workData.productProcessRouteItemId ||
                  workData.产品工艺路线项ID ||
                  "",
              });
              console.log("构造的orderRow:", orderRow);
            } else {
              modal.msgError("未找到对应的工单信息");
              return;
            }
          } catch (error) {
            modal.closeLoading();
            console.error("获取工单信息失败:", error);
            modal.msgError("获取工单信息失败: " + (error.message || "未知错误"));
            return;
          }
        } else {
          // 如果不是纯数字,尝试从扫码结果中提取orderRow参数
          try {
            // 处理混合格式: http://...?orderRow={...}
            const orderRowStart = scanResult.indexOf("orderRow={");
            if (orderRowStart !== -1) {
              // 提取从orderRow={开始的JSON内容
              const jsonPart = scanResult.substring(orderRowStart + 9); // 9是"orderRow=".length
              orderRow = jsonPart;
            } else {
              // 如果直接是JSON字符串,尝试解析
              orderRow = scanResult;
            }
          } catch (e) {
            console.error(e, "解析失败====????=====");
            orderRow = "";
          }
          // 验证是否为有效的JSON
          try {
            JSON.parse(orderRow);
          } catch (error) {
            modal.msgError("订单解析失败,请检查二维码格式");
            return;
          }
        }
        // 扫码成功后跳转到生产报工页面,并传递orderRow参数
        uni.navigateTo({
          url: `/pages/productionManagement/productionReport/index?orderRow=${orderRow}`,
        });
      },
      fail: err => {
        uni.showToast({
          title: "扫码失败",
          icon: "none",
        });
      },
    });
  };
  const changeFactory = async arr => {
    show.value = false;
    const factoryId = factoryListTem.value[arr.indexs[0]].deptId;
@@ -1104,10 +1193,13 @@
    // 定义菜单配置映射
    const menuMapping = {
      collaboration: { target: collaborationItems, specialMapping: { "规章制度": "规章制度管理" } },
      archiveManagement: { target: archiveManagementItems, specialMapping: { "供应商档案": "供应商管理" } },
      collaboration: {
        target: collaborationItems,
        specialMapping: { 规章制度: "规章制度管理" },
      },
      purchase: { specialMapping: { 供应商档案: "供应商管理" } },
    };
    console.log(allowedMenuTitles)
    console.log(allowedMenuTitles);
    // 通用过滤函数
    const filterArray = (targetArray, specialMapping) => {
      const filtered = targetArray.filter(item => {
@@ -1122,9 +1214,9 @@
    // 过滤各个模块
    filterArray(marketingItems);
    filterArray(purchaseItems);
    filterArray(designItems);
    filterArray(purchaseItems, menuMapping.purchase.specialMapping);
    filterArray(financeManagementItems);
    filterArray(archiveManagementItems, menuMapping.archiveManagement.specialMapping);
    filterArray(collaborationItems, menuMapping.collaboration.specialMapping);
    filterArray(safetyItems);
    filterArray(humanResourcesItems);
@@ -1132,21 +1224,32 @@
    filterArray(qualityItems);
    filterArray(productionItems);
    filterArray(equipmentItems);
    filterArray(archiveManagementItems);
    filterArray(afterSalesServiceItems);
  };
  // 检查模块是否有菜单项需要显示
  const hasMarketingItems = computed(() => marketingItems.length > 0);
  const hasDesignItems = computed(() => designItems.length > 0);
  const hasPurchaseItems = computed(() => purchaseItems.length > 0);
  const hasFinanceManagementItems = computed(() => financeManagementItems.length > 0);
  const hasArchiveManagementItems = computed(() => archiveManagementItems.length > 0);
  const hasAfterSalesServiceItems = computed(() => afterSalesServiceItems.length > 0);
  const hasFinanceManagementItems = computed(
    () => financeManagementItems.length > 0
  );
  const hasAfterSalesServiceItems = computed(
    () => afterSalesServiceItems.length > 0
  );
  const hasCollaborationItems = computed(() => collaborationItems.length > 0);
  const hasSafetyItems = computed(() => safetyItems.length > 0);
  const hasQualityItems = computed(() => qualityItems.length > 0);
  const hasHumanResourcesItems = computed(() => humanResourcesItems.length > 0);
  const hasWarehouseLogisticsItems = computed(() => warehouseLogisticsItems.length > 0);
  const hasWarehouseLogisticsItems = computed(
    () => warehouseLogisticsItems.length > 0
  );
  const hasProductionItems = computed(() => productionItems.length > 0);
  const hasEquipmentItems = computed(() => equipmentItems.length > 0);
  const hasArchiveManagementItems = computed(
    () => archiveManagementItems.length > 0
  );
  onMounted(() => {
    // 每次进入首页都强制刷新用户信息和路由权限,不做本地缓存判断
@@ -1513,6 +1616,10 @@
    --module-color: #4caf50;
  }
  .oa-module {
    --module-color: #673ab7;
  }
  .production-module {
    --module-color: #ff9800;
  }
@@ -1755,6 +1862,10 @@
    --module-color: #4caf50;
  }
  .oa-module {
    --module-color: #673ab7;
  }
  .production-module {
    --module-color: #ff9800;
  }