gaoluyang
2026-08-12 c7d9c7f73f92dd8fb2b7cb3f8cfe6841ca956d18
src/views/productionManagement/productionTraceability/index.vue
@@ -1,5 +1,7 @@
<template>
  <div class="app-container">
    <PageHeader v-if="showHeader"
                content="生产订单" />
    <el-card style="height:82vh;overflow:auto;">
      <template #header>
        <div class="card-header">
@@ -11,7 +13,7 @@
                         filterable
                         remote
                         reserve-keyword
                         placeholder="请输入生产订单号"
                         placeholder="请输入生产订单号搜索"
                         :loading="npsNoLoading"
                         :remote-method="handleNpsNoSearch"
                         @change="handleSearch"
@@ -20,6 +22,18 @@
                           :key="option.id"
                           :label="option.npsNo + '-' + option.productName + '-' + option.model"
                           :value="option.id" />
                <template #footer>
                  <div v-if="npsNoHasMore"
                       class="select-load-more"
                       @click="loadMoreNpsNo">
                    <span v-if="npsNoLoadingMore">加载中...</span>
                    <span v-else>点击加载更多</span>
                  </div>
                  <div v-else-if="npsNoOptions.length > 0"
                       class="select-load-more no-more">
                    没有更多了
                  </div>
                </template>
              </el-select>
            </el-form-item>
          </el-form>
@@ -33,7 +47,7 @@
                         border>
          <el-descriptions-item label="生产订单号">{{ rowData.productionOrderDto?.npsNo || '-' }}</el-descriptions-item>
          <el-descriptions-item label="产品名称">{{ rowData.productionOrderDto?.productName || '-' }}</el-descriptions-item>
          <el-descriptions-item label="产品规格">{{ rowData.productionOrderDto?.model || '-' }}</el-descriptions-item>
          <el-descriptions-item label="规格型号">{{ rowData.productionOrderDto?.model || '-' }}</el-descriptions-item>
          <!-- <el-descriptions-item label="物料编码">{{ rowData.productionOrderDto?.materialCode || '-' }}</el-descriptions-item> -->
          <el-descriptions-item label="计划数量">{{ rowData.productionOrderDto?.quantity || 0 }} <span class="unit">{{ rowData.productionOrderDto?.unit || '-' }}</span></el-descriptions-item>
          <el-descriptions-item label="当前状态">
@@ -78,11 +92,17 @@
                  {{ row.workOrder.model || '-' }}
                </template>
              </el-table-column>
              <el-table-column label="工序"
                               prop="workOrder.operationName"
                               align="center" />
              <el-table-column prop="workOrder.planQuantity"
                               label="需求数量"
                               align="center" />
              <el-table-column prop="workOrder.completeQuantity"
                               label="完成数量"
                               align="center" />
              <el-table-column prop="workOrder.scrapQty"
                               label="报废数量"
                               align="center" />
              <el-table-column prop="workOrder.completionStatus"
                               label="完成进度"
@@ -152,6 +172,15 @@
                {{ parseTime(row.createTime) }}
              </template>
            </el-table-column>
            <el-table-column label="工时(h)"
                             prop="workHour"
                             align="center" />
            <el-table-column label="产出数量"
                             prop="quantity"
                             align="center" />
            <el-table-column label="报废数量"
                             prop="scrapQty"
                             align="center" />
            <el-table-column label="操作"
                             align="center"
                             width="200">
@@ -267,7 +296,7 @@
</template>
<script setup>
  import { ref, reactive, onMounted } from "vue";
  import { ref, reactive, onMounted, computed } from "vue";
  import { useRoute, useRouter } from "vue-router";
  import { ElMessage } from "element-plus";
  import { parseTime } from "@/utils/ruoyi";
@@ -280,13 +309,24 @@
  const route = useRoute();
  const router = useRouter();
  // 判断是否显示页头
  const showHeader = computed(() => {
    return (
      Object.keys(route.query).length > 0 || Object.keys(route.params).length > 0
    );
  });
  // 搜索相关
  const searchForm = reactive({
    npsNo: "",
  });
  const selectedNpsNo = ref(null);
  const npsNoLoading = ref(false);
  const npsNoLoadingMore = ref(false);
  const npsNoOptions = ref([]);
  const npsNoPage = reactive({ current: 1, size: 20, total: 0 });
  const npsNoHasMore = computed(() => npsNoOptions.value.length < npsNoPage.total);
  const npsNoSearchKeyword = ref("");
  // 详情数据
  const rowData = reactive({
@@ -336,21 +376,45 @@
    return "#67c23a";
  };
  // 模拟搜索方法
  const handleNpsNoSearch = async query => {
    npsNoSearchKeyword.value = query || "";
    npsNoPage.current = 1;
    npsNoOptions.value = [];
    npsNoLoading.value = true;
    try {
      const res = await productOrderListPage({
        npsNo: query || "",
        pageNum: 1,
        pageSize: 50,
        current: npsNoPage.current,
        size: npsNoPage.size,
      });
      // 参照 productionOrder/index.vue 的数据结构 res.data.records
      npsNoOptions.value = res.data?.records || res.rows || [];
      const records = res.data?.records || [];
      npsNoOptions.value = records;
      npsNoPage.total = res.data?.total || 0;
    } catch (error) {
      console.error(error);
    } finally {
      npsNoLoading.value = false;
    }
  };
  const loadMoreNpsNo = async () => {
    if (npsNoLoadingMore.value || !npsNoHasMore.value) return;
    npsNoLoadingMore.value = true;
    npsNoPage.current++;
    try {
      const res = await productOrderListPage({
        npsNo: npsNoSearchKeyword.value,
        current: npsNoPage.current,
        size: npsNoPage.size,
      });
      const records = res.data?.records || [];
      npsNoOptions.value = [...npsNoOptions.value, ...records];
      npsNoPage.total = res.data?.total || 0;
    } catch (error) {
      console.error(error);
      npsNoPage.current--;
    } finally {
      npsNoLoadingMore.value = false;
    }
  };
@@ -385,6 +449,7 @@
      workOrder: row.workOrder || {},
      reports: (row.reportList || []).map(r => ({
        ...r.reportMain,
        ...(r.reportOutputList[0] || {}),
        productionOperationParamList: r.reportParamList || [],
      })),
    };
@@ -703,4 +768,26 @@
  .param-detail-list {
    padding: 10px;
  }
  .select-load-more {
    text-align: center;
    padding: 8px 0;
    font-size: 13px;
    color: #409eff;
    cursor: pointer;
    border-top: 1px solid #ebeef5;
    &:hover {
      background-color: #f5f7fa;
    }
    &.no-more {
      color: #c0c4cc;
      cursor: default;
      &:hover {
        background-color: transparent;
      }
    }
  }
</style>