chenhj
2026-04-25 28c608a765864a5677d5720099ae98d9f84b2d66
Merge branch 'dev_NEW_pro' of http://114.132.189.42:9002/r/product-inventory-management into dev_NEW_pro
已修改4个文件
318 ■■■■■ 文件已修改
src/api/productionManagement/productionOrder.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/ProcessParamListDialog.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/processRoute/processRouteItem/index.vue 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionOrder/index.vue 265 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/productionManagement/productionOrder.js
@@ -47,8 +47,9 @@
export function delProductOrder(ids) {
  return request({
    url: `/productionOrder/delete/${ids}`,
    url: `/productionOrder/delete`,
    method: "delete",
    data: ids,
  });
}
@@ -97,6 +98,14 @@
  });
}
// 生产订单-获取来源数据
export function getProductOrderSource(id) {
  return request({
    url: `/productionOrder/source/${id}`,
    method: "get",
  });
}
// 生产订单-退料确认
export function confirmMaterialReturn(data) {
  return request({
src/components/ProcessParamListDialog.vue
@@ -380,6 +380,9 @@
        paramId: selectedParam.value.id,
        standardValue: selectedParam.value.standardValue || "",
        isRequired: selectedParam.value.isRequired || 0,
        technologyOperationId: props.process.id,
        technologyOperationParamId: selectedParam.value.id,
        technologyRoutingOperationId: Number(props.routeId),
      })
        .then(res => {
          if (res.code === 200) {
src/views/productionManagement/processRoute/processRouteItem/index.vue
@@ -206,7 +206,7 @@
    <div class="section-header"
         style="margin-top: 20px;">
      <div class="section-title">BOM 结构</div>
      <div class="section-actions"
      <!-- <div class="section-actions"
           v-if="pageType === 'order'">
        <el-button v-if="!bomDataValue.isEdit"
                   type="primary"
@@ -223,7 +223,7 @@
                   :loading="bomDataValue.loading">
          保存BOM
        </el-button>
      </div>
      </div> -->
    </div>
    <el-table :data="bomTableData"
              border
@@ -369,6 +369,7 @@
               :rules="rules"
               label-width="120px">
        <el-form-item label="工序"
                      v-if="operationType === 'add' || pageType === 'route'"
                      prop="technologyOperationId">
          <el-select v-model="form.technologyOperationId"
                     placeholder="请选择工序"
@@ -381,7 +382,12 @@
                       :value="process.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="工序"
                      v-else>
          <span>{{ getProcessName(form.technologyOperationId) }}</span>
        </el-form-item>
        <el-form-item label="产品名称"
                      v-if="operationType === 'add' || pageType === 'route'"
                      prop="productModelId">
          <el-button type="primary"
                     @click="showProductSelectDialog = true">
@@ -390,12 +396,21 @@
              : '选择产品' }}
          </el-button>
        </el-form-item>
        <el-form-item label="产品名称"
                      v-else>
          <span>{{ form.productName }}{{ form.model ? ' - ' + form.model : '' }}</span>
        </el-form-item>
        <el-form-item label="单位"
                      v-if="operationType === 'add' || pageType === 'route'"
                      prop="unit">
          <el-input v-model="form.unit"
                    :placeholder="form.productModelId ? '根据选择的产品自动带出' : '请先选择产品'"
                    clearable
                    :disabled="true" />
        </el-form-item>
        <el-form-item label="单位"
                      v-else>
          <span>{{ form.unit }}</span>
        </el-form-item>
        <el-form-item label="是否质检"
                      prop="isQuality">
@@ -721,9 +736,11 @@
          const addPromise = isOrderPage
            ? addRouteItem({
                productOrderId: Number(orderId.value),
                productRouteId: Number(routeId.value),
                productionOrderId: Number(orderId.value),
                orderRoutingId: Number(routeId.value),
                technologyOperationId: form.value.technologyOperationId,
                technologyRoutingId: Number(routeId.value),
                operationName: getProcessName(form.value.technologyOperationId),
                productModelId: form.value.productModelId,
                isQuality: form.value.isQuality,
                isProduction: form.value.isProduction,
@@ -758,6 +775,7 @@
            ? addOrUpdateProductProcessRouteItem({
                id: form.value.id,
                technologyOperationId: form.value.technologyOperationId,
                operationName: getProcessName(form.value.technologyOperationId),
                productModelId: form.value.productModelId,
                isQuality: form.value.isQuality,
                isProduction: form.value.isProduction,
@@ -995,7 +1013,8 @@
  });
  const syncProcessOperationFields = item => {
    const processId = item.processId ?? item.operationId ?? "";
    const processId =
      item.processId ?? item.operationId ?? item.technologyOperationId ?? "";
    if (!processId) {
      item.processId = "";
      return;
@@ -1007,7 +1026,11 @@
      option?.name || item.processName || item.operationName || "";
    item.processId = processId;
    if (pageType.value === "order") {
      item.technologyOperationId = processId;
    } else {
    item.operationId = processId;
    }
    item.processName = processName;
    item.operationName = processName;
  };
@@ -1157,7 +1180,8 @@
        productModelId: undefined,
        processId: "",
        processName: "",
        operationId: "",
        [pageType.value === "order" ? "technologyOperationId" : "operationId"]:
          "",
        operationName: "",
        unitQuantity: 1,
        demandedQuantity: 0,
@@ -1192,7 +1216,8 @@
          productModelId: undefined,
          processId: "",
          processName: "",
          operationId: "",
          [pageType.value === "order" ? "technologyOperationId" : "operationId"]:
            "",
          operationName: "",
          unitQuantity: 1,
          demandedQuantity: 0,
src/views/productionManagement/productionOrder/index.vue
@@ -43,16 +43,33 @@
                    style="width: 160px;"
                    @change="handleQuery" />
        </el-form-item>
        <el-form-item label="状态:">
          <el-select v-model="searchForm.status"
                     placeholder="请选择"
                     style="width: 160px;"
                     @change="handleQuery">
            <el-option label="待开始"
                       value="1" />
            <el-option label="进行中"
                       value="2" />
            <el-option label="已完成"
                       value="3" />
            <el-option label="已取消"
                       value="4" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary"
                     @click="handleQuery">搜索</el-button>
          <el-button type="info"
                     @click="handleReset">重置</el-button>
        </el-form-item>
      </el-form>
      <div class="action-buttons">
        <el-button type="primary"
                   @click="isShowNewModal = true">新增</el-button>
        <!-- <el-button type="primary"
                   @click="isShowNewModal = true">新增</el-button> -->
        <el-button type="danger"
                   @click="handleDelete">删除</el-button>
                   @click="handleDelete">退回</el-button>
        <el-button @click="handleOut">导出</el-button>
      </div>
    </div>
@@ -98,6 +115,76 @@
        </span>
      </template>
    </el-dialog>
    <!-- 来源数据弹窗 -->
    <el-dialog v-model="sourceDataDialogVisible"
               title="来源数据"
               width="1200px">
      <div v-if="sourceRowData"
           class="applyno-summary1">
        <div class="summary-item">
          <span class="summary-label">产品名称:</span>
          <span class="summary-value">
            <el-tag type="primary">{{ sourceRowData.productName || '-' }}</el-tag>
          </span>
        </div>
        <div class="summary-item">
          <span class="summary-label">规格:</span>
          <span class="summary-value">{{ sourceRowData.model || '-' }}</span>
        </div>
        <div class="summary-item">
          <span class="summary-label">订单需求数量:</span>
          <span class="summary-value">{{ sourceRowData.quantity || 0 }}</span>
        </div>
      </div>
      <div class="source-table-container">
        <div class="source-data-cards-container">
          <div v-for="(item, index) in sourceTableData"
               :key="index"
               class="source-data-card">
            <div class="card-body">
              <div class="info-grid">
                <div class="info-item">
                  <div class="info-label">计划号</div>
                  <div class="info-value">{{ item.mpsNo || '-' }}</div>
                </div>
                <div class="info-item">
                  <div class="info-label">数据来源</div>
                  <div class="info-value">
                    <el-tag :type="item.source === '销售' ? 'primary' : 'warning'">
                      {{ item.source || '未知' }}
                    </el-tag>
                  </div>
                </div>
                <div class="info-item">
                  <div class="info-label">合同号</div>
                  <div class="info-value">{{ item.salesContractNo || '-' }}</div>
                </div>
                <div class="info-item">
                  <div class="info-label">客户名称</div>
                  <div class="info-value">{{ item.customerName || '-' }}</div>
                </div>
                <div class="info-item">
                  <div class="info-label">项目名称</div>
                  <div class="info-value">{{ item.projectName || '-' }}</div>
                </div>
                <div class="info-item">
                  <div class="info-label">计划需求数量</div>
                  <div class="info-value">{{ item.qtyRequired || 0 }} {{ item.unit || '' }}</div>
                </div>
                <div class="info-item">
                  <div class="info-label">单位</div>
                  <div class="info-value">{{ item.unit || '-' }}</div>
                </div>
                <div class="info-item">
                  <div class="info-label">需求日期</div>
                  <div class="info-value">{{ item.requiredDate ? dayjs(item.requiredDate).format('YYYY-MM-DD') : '-' }}</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </el-dialog>
    <MaterialLedgerDialog v-model="materialDialogVisible"
                          :order-row="currentMaterialOrder"
                          @saved="getList" />
@@ -129,6 +216,7 @@
    bindingRoute,
    listProcessBom,
    delProductOrder,
    getProductOrderSource,
  } from "@/api/productionManagement/productionOrder.js";
  import { listMain as getOrderProcessRouteMain } from "@/api/productionManagement/productProcessRoute.js";
  import MaterialLedgerDialog from "@/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue";
@@ -143,6 +231,12 @@
  const router = useRouter();
  const isShowNewModal = ref(false);
  const sourceDataDialogVisible = ref(false);
  const sourceTableData = ref([]);
  const sourceRowData = ref(null);
  const sourcePage = reactive({
    total: 0,
  });
  const tableColumn = ref([
    {
@@ -150,15 +244,28 @@
      prop: "npsNo",
      width: "150px",
    },
    // 1.待开始、2.进行中、3.已完成、4.已取消
    {
      label: "销售合同号",
      prop: "salesContractNo",
      label: "状态",
      prop: "status",
      width: "150px",
    },
    {
      label: "客户名称",
      prop: "customerName",
      width: "200px",
      dataType: "tag",
      formatData: val =>
        val === 1
          ? "待开始"
          : val === 2
          ? "进行中"
          : val === 3
          ? "已完成"
          : "已取消",
      formatType: val =>
        val === 1
          ? "primary"
          : val === 2
          ? "warning"
          : val === 3
          ? "success"
          : "danger",
    },
    {
      label: "产品名称",
@@ -218,6 +325,7 @@
        {
          name: "工艺路线",
          type: "text",
          showHide: row => row.processRouteCode,
          clickFun: row => {
            showRouteItemModal(row);
          },
@@ -236,6 +344,13 @@
          showHide: row => row.processRouteCode,
          clickFun: row => {
            openBindRouteDialog(row, "change");
          },
        },
        {
          name: "来源",
          type: "text",
          clickFun: row => {
            showSourceData(row);
          },
        },
        // {
@@ -279,6 +394,7 @@
      projectName: "",
      productName: "",
      model: "",
      status: "",
    },
  });
  const { searchForm } = toRefs(data);
@@ -385,6 +501,20 @@
    materialDetailDialogVisible.value = true;
  };
  const handleReset = () => {
    searchForm.value = {
      ...searchForm.value,
      npsNo: "",
      customerName: "",
      salesContractNo: "",
      projectName: "",
      productName: "",
      model: "",
      status: "",
    };
    handleQuery();
  };
  // 查询列表
  /** 搜索按钮操作 */
  const handleQuery = () => {
@@ -465,6 +595,29 @@
    });
  };
  // 查看来源生产计划数据
  const showSourceData = row => {
    // 存储点击来源按钮时传递的row参数
    sourceRowData.value = row;
    // 调用API获取来源数据
    getProductOrderSource(row.id)
      .then(res => {
        if (res.code === 200) {
          // 直接存储返回的扁平化数据
          sourceTableData.value = res.data || [];
          sourcePage.total = sourceTableData.value.length;
          // 打开弹窗
          sourceDataDialogVisible.value = true;
        } else {
          proxy.$modal.msgError(res.msg || "获取来源数据失败");
        }
      })
      .catch(err => {
        proxy.$modal.msgError("获取来源数据失败");
        console.error(err);
      });
  };
  // 表格选择数据
  const handleSelectionChange = selection => {
    selectedRows.value = selection;
@@ -478,14 +631,15 @@
      proxy.$modal.msgWarning("请选择数据");
      return;
    }
    ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
    ElMessageBox.confirm("是否退回该生产订单?", "退回", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        console.log(ids, "ids");
        delProductOrder(ids).then(res => {
          proxy.$modal.msgSuccess("删除成功");
          proxy.$modal.msgSuccess("退回成功");
          getList();
        });
      })
@@ -550,3 +704,90 @@
    margin-top: unset;
  }
</style>
<style lang="scss">
  .status-cell {
    font-weight: 600;
    color: #409eff;
    font-family: "Courier New", monospace;
    text-shadow: 0 1px 2px rgba(64, 158, 255, 0.2);
  }
  .source-table-container {
    margin-top: 20px;
  }
  .source-data-cards-container {
    display: flex;
    flex-direction: column;
    gap: 16px;
    max-height: 500px;
    overflow-y: auto;
    padding: 10px;
    background-color: #f5f7fa;
    border-radius: 4px;
    padding-bottom: 20px;
    .source-data-card {
      background: #fff;
      border-radius: 8px;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      overflow: hidden;
      .card-body {
        padding: 20px;
        .info-grid {
          display: grid;
          grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
          gap: 16px;
          .info-item {
            display: flex;
            flex-direction: column;
            .info-label {
              font-size: 12px;
              color: #909399;
              margin-bottom: 4px;
              font-weight: 500;
            }
            .info-value {
              font-size: 14px;
              color: #303133;
              font-weight: 500;
            }
          }
        }
      }
    }
  }
  .applyno-summary1 {
    padding: 16px 20px;
    background: #f5f7fa;
    border-bottom: 1px solid #e4e7ed;
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    .summary-item {
      display: flex;
      align-items: center;
      margin-right: 20px;
      .summary-label {
        font-size: 13px;
        color: #909399;
        margin-right: 8px;
        font-weight: 500;
      }
      .summary-value {
        font-size: 14px;
        color: #303133;
        font-weight: 500;
      }
    }
  }
</style>