zhangwencui
7 小时以前 2b3d9f38998fa0a3903e7789c690e62cf957d4b9
追踪进度接口对接,主生产计划右侧操作栏透光问题修改
已修改4个文件
756 ■■■■ 文件已修改
src/api/productionPlan/productionPlan.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index.vue 69 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionPlan/productionPlan/index.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionPlan/trackProgress/index.vue 667 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/productionPlan/productionPlan.js
@@ -68,4 +68,14 @@
    method: "post",
    data: query,
  });
}
}
// 追踪进度
export function trackProgressByNo(query) {
  return request({
    url: "/track/trackProgressByNo",
    method: "get",
    params: query,
  });
}
src/views/index.vue
@@ -16,9 +16,9 @@
                   type="primary"
                   plain
                   @click="refreshDashboardData">刷新数据</el-button>
        <el-button size="small"
        <!-- <el-button size="small"
                   plain
                   @click="configDialogVisible = true">首页配置</el-button>
                   @click="configDialogVisible = true">首页配置</el-button> -->
      </div>
    </div>
    <div class="content-grid">
@@ -40,7 +40,7 @@
            </el-button>
          </div>
        </section>
        <section class="section-card">
        <!-- <section class="section-card">
          <div class="section-title">重点待办</div>
          <div class="todo-row"
               v-for="todo in todos"
@@ -49,7 +49,7 @@
                    :type="todo.type">{{ todo.level }}</el-tag>
            <span>{{ todo.title }}</span>
          </div>
        </section>
        </section> -->
        <section class="section-card">
          <div class="section-title">经营关注</div>
          <div class="focus-row"
@@ -157,11 +157,10 @@
          </section>
          <section class="section-card"
                   v-if="isSectionVisible('costChart')">
            <div class="section-title">能耗与成本结构</div>
            <div class="section-title">能耗类型占比</div>
            <Echarts :chartStyle="chartStyle"
                     :legend="costLegend"
                     :tooltip="pieTooltip"
                     :series="costSeries"
                     :series="energyTypeSeries"
                     style="height: 260px" />
          </section>
        </div>
@@ -542,6 +541,61 @@
      data: [],
    },
  ]);
  // 能耗类型占比数据
  const energyTypeSeries = reactive([
    {
      type: "pie",
      radius: ["40%", "70%"],
      center: ["50%", "50%"],
      avoidLabelOverlap: false,
      itemStyle: {
        borderRadius: 10,
        borderColor: "#fff",
        borderWidth: 2,
      },
      label: {
        show: true,
        formatter: "{b}: {d}%",
      },
      data: [
        { value: 0, name: "水", itemStyle: { color: "#409EFF" } },
        { value: 0, name: "电", itemStyle: { color: "#E6A23C" } },
        { value: 0, name: "气", itemStyle: { color: "#F56C6C" } },
      ],
    },
  ]);
  // 模拟能耗数据
  const energyData = reactive({
    water: 120,
    electricity: 350,
    gas: 80,
  });
  // 更新能耗类型占比图表
  const updateEnergyTypeChart = () => {
    const { water, electricity, gas } = energyData;
    const total = water + electricity + gas;
    energyTypeSeries[0].data = [
      {
        value: total > 0 ? ((water / total) * 100).toFixed(2) : 0,
        name: "水",
        itemStyle: { color: "#409EFF" },
      },
      {
        value: total > 0 ? ((electricity / total) * 100).toFixed(2) : 0,
        name: "电",
        itemStyle: { color: "#E6A23C" },
      },
      {
        value: total > 0 ? ((gas / total) * 100).toFixed(2) : 0,
        name: "气",
        itemStyle: { color: "#F56C6C" },
      },
    ];
  };
  const planTable = reactive([]);
  const recentTrendCards = reactive([
@@ -982,6 +1036,7 @@
    loadQualityData();
    loadCostComposition();
    loadWarningCenter();
    updateEnergyTypeChart();
    lastUpdatedAt.value = new Date().toLocaleString();
  };
src/views/productionPlan/productionPlan/index.vue
@@ -674,7 +674,10 @@
    router.push({
      path: "/productionPlan/trackProgress",
      query: {
        applyNo: encodeURIComponent(row.applyNo),
        id: row.id,
        applyNo: row.applyNo,
        productName: row.productName,
        model: row.model,
      },
    });
  };
@@ -1559,4 +1562,7 @@
  //     margin-bottom: 0px !important;
  //   }
  // }
  :deep(.el-table .el-table__body-wrapper tr td) {
    background-color: #fff;
  }
</style>
src/views/productionPlan/trackProgress/index.vue
@@ -10,92 +10,118 @@
                   :model="searchForm"
                   class="search-form">
            <el-form-item label="申请单编号">
              <el-input v-model="searchForm.applyNo"
                        placeholder="请输入申请单编号"
                        style="width: 400px;"></el-input>
            </el-form-item>
            <el-form-item>
              <el-button type="primary"
                         @click="handleSearch">搜索</el-button>
              <el-select v-model="selectedApplyNo"
                         filterable
                         remote
                         reserve-keyword
                         placeholder="请输入申请单编号"
                         :loading="applyNoLoading"
                         :remote-method="handleApplyNoSearch"
                         @change="handleSearch"
                         style="width: 400px;">
                <el-option v-for="option in applyNoOptions"
                           :key="option.id"
                           :label="option.applyNo+'-'+option.productName+'-'+option.model"
                           :value="option.id" />
              </el-select>
            </el-form-item>
          </el-form>
        </div>
      </template>
      <!-- 基础信息 -->
      <div class="detail-section">
      <div v-if="rowData.productionPlanDto"
           class="detail-section">
        <h3 class="section-title">基础信息</h3>
        <el-descriptions :column="3"
                         border>
          <el-descriptions-item label="申请单编号">{{ rowData.applyNo || '-' }}</el-descriptions-item>
          <el-descriptions-item label="产品名称">{{ rowData.productName || '-' }}</el-descriptions-item>
          <el-descriptions-item label="产品规格">{{ rowData.model || '-' }}</el-descriptions-item>
          <el-descriptions-item label="物料编码">{{ rowData.materialCode || '-' }}</el-descriptions-item>
          <el-descriptions-item label="下发数量">{{ rowData.assignedQuantity || 0 }} <span class="unit">方</span></el-descriptions-item>
          <el-descriptions-item label="当前状态">
            <el-tag :type="getStatusType(rowData.status)">
              {{ getStatusText(rowData.status) }}
            </el-tag>
          </el-descriptions-item>
        </el-descriptions>
        <el-skeleton :loading="loading"
                     animated>
          <template #template>
            <el-skeleton-item variant="p"
                              style="width: 80%" />
            <el-skeleton-item variant="p"
                              style="width: 60%" />
            <el-skeleton-item variant="p"
                              style="width: 40%" />
          </template>
          <el-descriptions :column="3"
                           border>
            <el-descriptions-item label="申请单编号">{{ rowData.productionPlanDto?.applyNo || '-' }}</el-descriptions-item>
            <el-descriptions-item label="产品名称">{{ rowData.productionPlanDto?.productName || '-' }}</el-descriptions-item>
            <el-descriptions-item label="产品规格">{{ rowData.productionPlanDto?.model || '-' }}</el-descriptions-item>
            <el-descriptions-item label="物料编码">{{ rowData.productionPlanDto?.materialCode || '-' }}</el-descriptions-item>
            <el-descriptions-item label="下发数量">{{ rowData.productionPlanDto?.assignedQuantity || 0 }} <span class="unit">方</span></el-descriptions-item>
            <el-descriptions-item label="当前状态">
              <el-tag :type="getStatusType(rowData.productionPlanDto?.status)">
                {{ getStatusText(rowData.productionPlanDto?.status) }}
              </el-tag>
            </el-descriptions-item>
          </el-descriptions>
        </el-skeleton>
      </div>
      <div class="progress-container">
      <el-empty v-else
                description="暂无数据" />
      <div v-if="rowData.orderDtoList"
           class="progress-container">
        <div class="progress-section">
          <h3 class="section-title">订单信息</h3>
          <div v-for="item in rowData.orderList"
               :key="item.orderNo"
               class="order-item">
            <el-descriptions :column="3"
                             border>
              <el-descriptions-item label="订单编号">{{ item.orderNo || '-' }}</el-descriptions-item>
              <!-- <el-descriptions-item label="订单状态">
                <el-tag :type="getStatusType(item.status)">{{ getStatusText(item.status) }}</el-tag>
              </el-descriptions-item> -->
              <el-descriptions-item label="开始日期">{{ item.startTime || '-' }}</el-descriptions-item>
              <el-descriptions-item label="完成进度">
                <el-progress :percentage="item.completionRate"
                             :color="customColors(item.completionRate)"
                             :status="item.completionRate === 100 ? 'success' : ''"
                             style="width: 120px;" />
              </el-descriptions-item>
              <el-descriptions-item label="需求数量">{{ item.quantity || 0 }} <span class="unit">方</span></el-descriptions-item>
              <el-descriptions-item label="完成数量">{{ item.completeQuantity || 0 }} <span class="unit">方</span></el-descriptions-item>
              <el-descriptions-item label="剩余数量">{{ item.remainingQuantity || 0 }} <span class="unit">方</span></el-descriptions-item>
            </el-descriptions>
            <el-table :data="trackProgressForm.progressDetails"
                      border
                      style="width: auto; height: 200px">
              <el-table-column prop="step"
                               label="步骤(点击查看详情)"
                               align="center">
                <template #default="{ row, $index }">
                  <el-link v-if="$index!=0"
                           @click="handleClickStep(row)"
                           type="primary">{{ row.step }}</el-link>
                  <span v-else>{{ row.step }}</span>
                </template>
              </el-table-column>
              <!-- <el-table-column prop="status"
                               label="状态"
                               align="center">
                <template #default="scope">
                  <el-tag :type="scope.row.status === 'completed' ? 'success' : scope.row.status === 'processing' ? 'warning' : 'info'">
                    {{ scope.row.status === 'completed' ? '已完成' : scope.row.status === 'processing' ? '进行中' : '待开始' }}
                  </el-tag>
                </template>
              </el-table-column> -->
              <el-table-column prop="quantity"
                               label="数量"
                               align="center" />
              <el-table-column prop="startTime"
                               label="时间"
                               align="center" />
              <el-table-column prop="startTime1"
                               label="岗位人员"
                               align="center" />
            </el-table>
          </div>
          <el-skeleton :loading="loading"
                       animated>
            <template #template>
              <el-skeleton-item variant="p"
                                style="width: 80%" />
              <el-skeleton-item variant="p"
                                style="width: 60%" />
              <el-skeleton-item variant="p"
                                style="width: 40%" />
              <el-skeleton-item variant="p"
                                style="width: 100%" />
            </template>
            <div v-for="(item, index) in rowData.orderDtoList"
                 :key="item.productOrderDto?.npsNo || index"
                 class="order-item">
              <el-descriptions :column="3"
                               border>
                <el-descriptions-item label="订单编号">{{ item.productOrderDto?.npsNo || '-' }}</el-descriptions-item>
                <el-descriptions-item label="开始日期">{{ item.productOrderDto?.startTime || '-' }}</el-descriptions-item>
                <el-descriptions-item label="完成进度">
                  <el-progress :percentage="item.productOrderDto?.completionStatus"
                               :color="customColors(item.productOrderDto?.completionStatus)"
                               :status="item.productOrderDto?.completionStatus === 100 ? 'success' : ''"
                               style="width: 120px;" />
                </el-descriptions-item>
                <el-descriptions-item label="需求数量">{{ item.productOrderDto?.quantity || 0 }} <span class="unit">方</span></el-descriptions-item>
                <el-descriptions-item label="完成数量">{{ item.productOrderDto?.completeQuantity || 0 }} <span class="unit">方</span></el-descriptions-item>
                <el-descriptions-item label="剩余数量">{{ (item.productOrderDto?.quantity - item.productOrderDto?.completeQuantity) || 0 }} <span class="unit">方</span></el-descriptions-item>
              </el-descriptions>
              <el-table :data="item.productionProductMainDtos"
                        border
                        style="width: auto; max-height: 200px">
                <el-table-column prop="step"
                                 label="报工(点击查看详情)"
                                 align="center">
                  <template #default="{ row }">
                    <el-link @click="handleClickStep(row)"
                             type="primary">{{ row.productNo }}</el-link>
                  </template>
                </el-table-column>
                <el-table-column prop="quantity"
                                 label="数量(方)"
                                 align="center" />
                <el-table-column prop="reportingTime"
                                 label="时间"
                                 align="center" />
                <el-table-column prop="schedule"
                                 label="班次"
                                 align="center" />
                <el-table-column prop="postName"
                                 label="岗位人员"
                                 align="center" />
              </el-table>
            </div>
          </el-skeleton>
        </div>
      </div>
      <el-empty v-else-if="rowData.productionPlanDto"
                description="暂无进度" />
    </el-card>
    <!-- 生产报工详情弹窗 -->
    <el-dialog v-model="detailDialogVisible"
@@ -104,142 +130,159 @@
               :close-on-click-modal="false"
               custom-class="custom-dialog">
      <div class="detail-container">
        <!-- 基础信息 -->
        <div class="detail-section">
          <h3 class="section-title">基础信息</h3>
          <el-descriptions :column="3"
                           border>
            <el-descriptions-item label="生产订单号">{{ detailData.npsNo || '-' }}</el-descriptions-item>
            <el-descriptions-item label="班组"><el-tag :type="detailData.schedule == '白班' ? 'primary' : 'warning'">{{ detailData.schedule || '-' }}</el-tag></el-descriptions-item>
            <el-descriptions-item label="岗位人员">{{ detailData.postName || '-' }}</el-descriptions-item>
            <el-descriptions-item label="产品编码">{{ detailData.materialCode || '-' }}</el-descriptions-item>
            <el-descriptions-item label="产品名称">{{ detailData.productName || '-' }}</el-descriptions-item>
            <el-descriptions-item label="规格">{{ detailData.model || '-' }}</el-descriptions-item>
            <el-descriptions-item label="合格数量"><span class="num2">{{ detailData.qualifiedQuantity || 0 }}</span> <span class="unit">方</span></el-descriptions-item>
            <el-descriptions-item label="不合格数量"><span class="num3">{{ detailData.unqualifiedQuantity || 0 }}</span> <span class="unit">方</span></el-descriptions-item>
            <el-descriptions-item label="总数量"><span class="num1">{{ detailData.quantity || 0 }}</span> <span class="unit">方</span></el-descriptions-item>
            <el-descriptions-item label="报工时间">{{ formatTime(detailData.reportingTime) }}</el-descriptions-item>
            <el-descriptions-item label="创建时间">{{ formatTime(detailData.createTime) }}</el-descriptions-item>
            <el-descriptions-item label="更新时间">{{ formatTime(detailData.updateTime) }}</el-descriptions-item>
          </el-descriptions>
        </div>
        <!-- 工序信息 -->
        <div class="detail-section"
             v-if="detailData.productionProductRouteItemDtoList && detailData.productionProductRouteItemDtoList.length > 0">
          <h3 class="section-title">工序信息</h3>
          <div v-for="(process) in detailData.productionProductRouteItemDtoList"
               :key="process.id"
               class="process-item">
            <div class="process-header">
              <h4 class="process-title">{{ process.processName || '-' }}</h4>
              <div class="process-info">
                <span class="process-label">岗位人员:{{ process.postName || '-' }}</span>
                <span class="process-label">工序ID:{{ process.processNo || '-' }}</span>
        <el-skeleton :loading="dialogLoading"
                     animated>
          <template #template>
            <el-skeleton-item variant="p"
                              style="width: 80%" />
            <el-skeleton-item variant="p"
                              style="width: 60%" />
            <el-skeleton-item variant="p"
                              style="width: 40%" />
            <el-skeleton-item variant="h3"
                              style="width: 50%" />
            <el-skeleton-item variant="p"
                              style="width: 100%" />
            <el-skeleton-item variant="p"
                              style="width: 100%" />
          </template>
          <!-- 基础信息 -->
          <div class="detail-section">
            <h3 class="section-title">基础信息</h3>
            <el-descriptions :column="3"
                             border>
              <el-descriptions-item label="生产订单号">{{ detailData.npsNo || '-' }}</el-descriptions-item>
              <el-descriptions-item label="班组"><el-tag :type="detailData.schedule == '白班' ? 'primary' : 'warning'">{{ detailData.schedule || '-' }}</el-tag></el-descriptions-item>
              <el-descriptions-item label="岗位人员">{{ detailData.postName || '-' }}</el-descriptions-item>
              <el-descriptions-item label="产品编码">{{ detailData.materialCode || '-' }}</el-descriptions-item>
              <el-descriptions-item label="产品名称">{{ detailData.productName || '-' }}</el-descriptions-item>
              <el-descriptions-item label="规格">{{ detailData.model || '-' }}</el-descriptions-item>
              <el-descriptions-item label="合格数量"><span class="num2">{{ detailData.qualifiedQuantity || 0 }}</span> <span class="unit">方</span></el-descriptions-item>
              <el-descriptions-item label="不合格数量"><span class="num3">{{ detailData.unqualifiedQuantity || 0 }}</span> <span class="unit">方</span></el-descriptions-item>
              <el-descriptions-item label="总数量"><span class="num1">{{ detailData.quantity || 0 }}</span> <span class="unit">方</span></el-descriptions-item>
              <el-descriptions-item label="报工时间">{{ formatTime(detailData.reportingTime) }}</el-descriptions-item>
              <el-descriptions-item label="创建时间">{{ formatTime(detailData.createTime) }}</el-descriptions-item>
              <el-descriptions-item label="更新时间">{{ formatTime(detailData.updateTime) }}</el-descriptions-item>
            </el-descriptions>
          </div>
          <!-- 工序信息 -->
          <div class="detail-section"
               v-if="detailData.productionProductRouteItemDtoList && detailData.productionProductRouteItemDtoList.length > 0">
            <h3 class="section-title">工序信息</h3>
            <div v-for="(process) in detailData.productionProductRouteItemDtoList"
                 :key="process.id"
                 class="process-item">
              <div class="process-header">
                <h4 class="process-title">{{ process.processName || '-' }}</h4>
                <div class="process-info">
                  <span class="process-label">岗位人员:{{ process.postName || '-' }}</span>
                  <span class="process-label">工序ID:{{ process.processNo || '-' }}</span>
                </div>
              </div>
            </div>
            <!-- 工序基本信息 -->
            <div class="process-details">
              <el-descriptions :column="2"
                               border>
                <el-descriptions-item label="设备异常情况">{{ process.equipmentMalfunction || '-' }}</el-descriptions-item>
                <el-descriptions-item label="当班设备处置">{{ process.equipmentDisposal || '-' }}</el-descriptions-item>
                <el-descriptions-item label="工艺人员交待"
                                      :span="2">{{ process.processExplained || '-' }}</el-descriptions-item>
              </el-descriptions>
            </div>
            <!-- 工序参数 -->
            <div v-if="process.productionProductRouteItemParamDtoList && process.productionProductRouteItemParamDtoList.length > 0">
              <!-- BOM信息 -->
              <div class="param-section"
                   v-if="getBomList(process.productionProductRouteItemParamDtoList).length > 0">
                <h5 class="param-title">投入品信息</h5>
                <el-table :data="getBomList(process.productionProductRouteItemParamDtoList)"
                          style="width: 100%"
                          size="small">
                  <el-table-column prop="paramName"
                                   label="产品名称"
                                   min-width="120"></el-table-column>
                  <el-table-column prop="model"
                                   label="规格型号"
                                   min-width="120"></el-table-column>
                  <el-table-column prop="productValue"
                                   label="投入量"
                                   min-width="100"></el-table-column>
                  <el-table-column prop="unit"
                                   label="单位"
                                   width="80"></el-table-column>
                </el-table>
              <!-- 工序基本信息 -->
              <div class="process-details">
                <el-descriptions :column="2"
                                 border>
                  <el-descriptions-item label="设备异常情况">{{ process.equipmentMalfunction || '-' }}</el-descriptions-item>
                  <el-descriptions-item label="当班设备处置">{{ process.equipmentDisposal || '-' }}</el-descriptions-item>
                  <el-descriptions-item label="工艺人员交待"
                                        :span="2">{{ process.processExplained || '-' }}</el-descriptions-item>
                </el-descriptions>
              </div>
              <!-- 参数信息 -->
              <div class="param-section"
                   v-if="getParamList(process.productionProductRouteItemParamDtoList).length > 0">
                <h5 class="param-title">生产记录</h5>
                <el-card v-for="group in getParamGroups(process.productionProductRouteItemParamDtoList)"
                         :key="group.sourceSort"
                         class="detail-card"
                         style="margin-top: 10px;">
                  <template #header>
                    <div class="card-header">
                      <span v-if="Object.keys(getParamGroups(process.productionProductRouteItemParamDtoList)).length > 1">生产记录组 - {{ group.sourceSort }}</span>
                      <span v-else>生产记录</span>
                    </div>
                  </template>
                  <el-table :data="group.items"
              <!-- 工序参数 -->
              <div v-if="process.productionProductRouteItemParamDtoList && process.productionProductRouteItemParamDtoList.length > 0">
                <!-- BOM信息 -->
                <div class="param-section"
                     v-if="getBomList(process.productionProductRouteItemParamDtoList).length > 0">
                  <h5 class="param-title">投入品信息</h5>
                  <el-table :data="getBomList(process.productionProductRouteItemParamDtoList)"
                            style="width: 100%"
                            :row-class-name="rowClassName">
                            size="small">
                    <el-table-column prop="paramName"
                                     label="指标" />
                                     label="产品名称"
                                     min-width="120"></el-table-column>
                    <el-table-column prop="model"
                                     label="规格型号"
                                     min-width="120"></el-table-column>
                    <el-table-column prop="productValue"
                                     label="投入量"
                                     min-width="100"></el-table-column>
                    <el-table-column prop="unit"
                                     label="单位"
                                     width="100">
                      <template #default="scope">
                        {{ scope.row.unit || "/" }}
                      </template>
                    </el-table-column>
                    <el-table-column prop="standardText"
                                     label="标准值" />
                    <el-table-column prop="paramValue"
                                     label="实际值" />
                    <el-table-column prop="result"
                                     label="结果"
                                     width="100">
                      <template #default="scope">
                        <el-tag :type="scope.row.result === '合格' ? 'success' : 'danger'">
                          {{ scope.row.result }}
                        </el-tag>
                      </template>
                    </el-table-column>
                                     width="80"></el-table-column>
                  </el-table>
                </el-card>
                </div>
                <!-- 参数信息 -->
                <div class="param-section"
                     v-if="getParamList(process.productionProductRouteItemParamDtoList).length > 0">
                  <h5 class="param-title">生产记录</h5>
                  <el-card v-for="group in getParamGroups(process.productionProductRouteItemParamDtoList)"
                           :key="group.sourceSort"
                           class="detail-card"
                           style="margin-top: 10px;">
                    <template #header>
                      <div class="card-header">
                        <span v-if="Object.keys(getParamGroups(process.productionProductRouteItemParamDtoList)).length > 1">生产记录组 - {{ group.sourceSort }}</span>
                        <span v-else>生产记录</span>
                      </div>
                    </template>
                    <el-table :data="group.items"
                              style="width: 100%"
                              :row-class-name="rowClassName">
                      <el-table-column prop="paramName"
                                       label="指标" />
                      <el-table-column prop="unit"
                                       label="单位"
                                       width="100">
                        <template #default="scope">
                          {{ scope.row.unit || "/" }}
                        </template>
                      </el-table-column>
                      <el-table-column prop="standardText"
                                       label="标准值" />
                      <el-table-column prop="paramValue"
                                       label="实际值" />
                      <el-table-column prop="result"
                                       label="结果"
                                       width="100">
                        <template #default="scope">
                          <el-tag :type="scope.row.result === '合格' ? 'success' : 'danger'">
                            {{ scope.row.result }}
                          </el-tag>
                        </template>
                      </el-table-column>
                    </el-table>
                  </el-card>
                </div>
              </div>
            </div>
            <!-- 上传文件 -->
            <div class="file-section"
                 v-if="process.fileList && process.fileList.length > 0">
              <h5 class="file-title">上传文件</h5>
              <div class="file-grid">
                <div v-for="file in process.fileList"
                     :key="file.id"
                     class="file-item">
                  <el-image style="width: 100px; height: 100px"
                            v-if="file.fileUrl"
                            :src="baseUrl + file.fileUrl"
                            :zoom-rate="1.2"
                            :max-scale="7"
                            :alt="file.fileName"
                            :min-scale="0.2"
                            :preview-src-list="formatFileList(process.fileList)"
                            show-progress
                            :initial-index="4"
                            fit="cover" />
                  <div class="file-info">
                    <span class="file-name">{{ file.fileName || '-' }}</span>
              <!-- 上传文件 -->
              <div class="file-section"
                   v-if="process.fileList && process.fileList.length > 0">
                <h5 class="file-title">上传文件</h5>
                <div class="file-grid">
                  <div v-for="file in process.fileList"
                       :key="file.id"
                       class="file-item">
                    <el-image style="width: 100px; height: 100px"
                              v-if="file.fileUrl"
                              :src="baseUrl + file.fileUrl"
                              :zoom-rate="1.2"
                              :max-scale="7"
                              :alt="file.fileName"
                              :min-scale="0.2"
                              :preview-src-list="formatFileList(process.fileList)"
                              show-progress
                              :initial-index="4"
                              fit="cover" />
                    <div class="file-info">
                      <span class="file-name">{{ file.fileName || '-' }}</span>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        </el-skeleton>
      </div>
      <template #footer>
        <div class="dialog-footer">
@@ -255,6 +298,11 @@
  import { ElMessage } from "element-plus";
  import { useRouter, useRoute } from "vue-router";
  import dayjs from "dayjs";
  import {
    trackProgressByNo,
    productionPlanListPage,
  } from "@/api/productionPlan/productionPlan";
  import { productionReportDetail } from "@/api/productionManagement/productionReporting.js";
  const router = useRouter();
  const route = useRoute();
@@ -271,15 +319,21 @@
    remark: "",
  });
  // 搜索表单
  const searchForm = reactive({
    applyNo: "",
  });
  // 生产报工详情弹窗
  const detailDialogVisible = ref(false);
  const detailData = ref({});
  const baseUrl = import.meta.env.VITE_APP_BASE_API;
  // 加载状态
  const loading = ref(false);
  // 弹窗加载状态
  const dialogLoading = ref(false);
  // 申请单下拉框数据
  const applyNoOptions = ref([]);
  const applyNoLoading = ref(false);
  const applyNoQuery = ref("");
  const selectedApplyNo = ref(null);
  // 获取状态类型
  const getStatusType = status => {
@@ -392,28 +446,52 @@
    router.push("/productionPlan/productionPlan");
  };
  // 处理申请单编号搜索
  const handleApplyNoSearch = query => {
    if (query) {
      applyNoLoading.value = true;
      productionPlanListPage({
        current: -1,
        size: -1,
        applyNo: query,
      })
        .then(res => {
          // 转换数据格式为下拉框所需的格式
          applyNoOptions.value = res.data.records;
        })
        .catch(error => {
          console.error(error);
        })
        .finally(() => {
          applyNoLoading.value = false;
        });
    } else {
      applyNoOptions.value = [];
    }
  };
  // 处理搜索
  const handleSearch = () => {
    const applyNo = searchForm.applyNo.trim();
    if (!applyNo) {
      ElMessage.warning("请输入申请单编号");
    if (!selectedApplyNo.value) {
      ElMessage.warning("请选择申请单编号");
      return;
    }
    // 这里可以添加搜索逻辑,例如调用API获取数据
    // 目前使用模拟数据
    ElMessage.success(`搜索申请单编号: ${applyNo}`);
    // 模拟搜索结果
    rowData.applyNo = applyNo;
    rowData.productName = "搜索结果产品";
    rowData.model = "搜索结果规格";
    rowData.materialCode = "MAT-" + applyNo;
    rowData.assignedQuantity = 100;
    rowData.status = 1;
    trackProgressForm.progressDetails = generateProgressDetails(1);
    trackProgressForm.completionRate = calculateCompletionRate(
      trackProgressForm.progressDetails
    );
    rowData.orderList = generateOrderList();
    // 调用API获取数据
    loading.value = true;
    trackProgressByNo({ productionPlanId: selectedApplyNo.value })
      .then(res => {
        console.log(res, "搜索结果");
        // 合并数据到rowData
        Object.assign(rowData, res.data);
        ElMessage.success("搜索成功");
      })
      .catch(error => {
        ElMessage.error("搜索失败,请稍后重试");
        console.error(error);
      })
      .finally(() => {
        loading.value = false;
      });
  };
  // 生成模拟订单数据
@@ -451,97 +529,23 @@
  // 处理点击步骤查看详情
  const handleClickStep = row => {
    // 这里可以添加获取报工详情数据的逻辑
    // 目前使用模拟数据
    detailData.value = {
      npsNo: "NPS-2026-001",
      schedule: "白班",
      postName: "张三",
      materialCode: rowData.materialCode || "MAT-001",
      productName: rowData.productName || "产品A",
      model: rowData.model || "规格A",
      qualifiedQuantity: 100,
      unqualifiedQuantity: 5,
      quantity: 105,
      reportingTime: new Date(),
      createTime: new Date(),
      updateTime: new Date(),
      productionProductRouteItemDtoList: [
        {
          id: 1,
          processName: "工序1",
          postName: "张三",
          processNo: "PROC-001",
          equipmentMalfunction: "无异常",
          equipmentDisposal: "正常运行",
          processExplained: "按照标准工艺操作",
          productionProductRouteItemParamDtoList: [
            {
              id: 11,
              paramName: "原材料A",
              model: "型号A",
              productValue: "100",
              unit: "kg",
              bomId: 101,
            },
            {
              id: 12,
              paramName: "温度",
              paramValue: "25",
              unit: "°C",
              sourceSort: 1,
              valueMode: 2,
              minValue: 20,
              maxValue: 30,
            },
            {
              id: 13,
              paramName: "压力",
              paramValue: "1.5",
              unit: "MPa",
              sourceSort: 1,
              valueMode: 2,
              minValue: 1.0,
              maxValue: 2.0,
            },
            {
              id: 14,
              paramName: "转速",
              paramValue: "1500",
              unit: "rpm",
              sourceSort: 2,
              valueMode: 1,
              standardValue: "1500",
            },
            {
              id: 15,
              paramName: "电流",
              paramValue: "12",
              unit: "A",
              sourceSort: 2,
              valueMode: 2,
              minValue: 10,
              maxValue: 15,
            },
          ],
          fileList: [
            {
              id: 21,
              fileName: "生产记录1.jpg",
              fileUrl: "/upload/files/20260301/12345.jpg",
              fileSize: 1024000,
            },
            {
              id: 22,
              fileName: "生产记录2.jpg",
              fileUrl: "/upload/files/20260301/67890.jpg",
              fileSize: 2048000,
            },
          ],
        },
      ],
    };
    detailDialogVisible.value = true;
    // 获取报工详情数据
    dialogLoading.value = true;
    productionReportDetail(row.id)
      .then(res => {
        console.log(res, "报工详情");
        // 将API返回的数据赋值给detailData
        detailData.value = res.data;
        // 打开弹窗
        detailDialogVisible.value = true;
      })
      .catch(error => {
        ElMessage.error("获取报工详情失败,请稍后重试");
        console.error(error);
      })
      .finally(() => {
        dialogLoading.value = false;
      });
  };
  // 格式化时间
@@ -637,29 +641,26 @@
  // 页面加载时获取数据
  onMounted(() => {
    // 从路由参数中获取数据
    applyNo.value = route.query.applyNo
      ? decodeURIComponent(route.query.applyNo)
    selectedApplyNo.value = route.query.applyNo
      ? route.query.applyNo +
        "-" +
        route.query.productName +
        "-" +
        route.query.model
      : null;
    searchForm.applyNo = applyNo.value;
    // 生成假数据
    rowData.applyNo = applyNo.value || "APPLY-2026-001";
    rowData.productName = "测试产品";
    rowData.model = "测试规格";
    rowData.materialCode = "MAT-001";
    rowData.assignedQuantity = 233;
    rowData.status = 1;
    // 赋值给表单数据
    trackProgressForm.materialCode = rowData.materialCode;
    trackProgressForm.currentStatus = rowData.status;
    trackProgressForm.progressDetails = generateProgressDetails(rowData.status);
    trackProgressForm.completionRate = calculateCompletionRate(
      trackProgressForm.progressDetails
    );
    trackProgressForm.remark = "";
    // 生成模拟订单数据
    rowData.orderList = generateOrderList();
    if (route.query.id) {
      loading.value = true;
      trackProgressByNo({ productionPlanId: route.query.id })
        .then(res => {
          console.log(res, "追踪进度");
          // 合并数据到rowData
          Object.assign(rowData, res.data);
        })
        .finally(() => {
          loading.value = false;
        });
    }
  });
</script>