gongchunyi
22 小时以前 0a251e40e30e7c8a96d71b3b9b6c459d4dfa4b22
src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue
@@ -2,7 +2,7 @@
  <div>
    <el-dialog v-model="dialogVisible"
               title="领料台账"
               width="1200px"
               width="1350px"
               @close="handleClose">
      <div class="material-toolbar">
        <el-button type="primary"
@@ -13,7 +13,7 @@
                border
                row-key="tempId">
        <el-table-column label="工序名称"
                         min-width="140">
                         min-width="80">
          <template #default="{ row }">
            <span v-if="row.bom === true">{{ row.operationName || "-" }}</span>
            <el-select v-else
@@ -31,7 +31,7 @@
          </template>
        </el-table-column>
        <el-table-column label="原料名称"
                         min-width="140">
                         min-width="120">
          <template #default="{ row }">
            <span v-if="row.bom === true">{{ row.materialName || "-" }}</span>
            <el-button v-else
@@ -43,7 +43,7 @@
          </template>
        </el-table-column>
        <el-table-column label="原料型号"
                         min-width="140">
                         min-width="120">
          <template #default="{ row }">
            {{ row.materialModel || "-" }}
          </template>
@@ -66,21 +66,22 @@
          </template>
        </el-table-column>
        <el-table-column label="需求数量"
                         min-width="120">
                         min-width="100">
          <template #default="{ row }">
            <span v-if="row.bom === true">{{ row.demandedQuantity ?? "-" }}</span>
            <span v-if="row.bom === true">{{ stripTrailingZeros(row.demandedQuantity) ?? "-" }}</span>
            <el-input-number v-else
                             v-model="row.demandedQuantity"
                             :min="0"
                             :precision="3"
                             :step="1"
                             controls-position="right"
                             :formatter="value => stripTrailingZeros(value)"
                             :parser="value => parseFloat(value) || 0"
                             style="width: 100%;"
                             @change="val => handleRequiredQtyChange(row, val)" />
          </template>
        </el-table-column>
        <el-table-column label="计量单位"
                         width="100">
                         width="80">
          <template #default="{ row }">
            {{ row.unit || "-" }}
          </template>
@@ -90,9 +91,10 @@
          <template #default="{ row }">
            <el-input-number v-model="row.pickQty"
                             :min="0"
                             :precision="3"
                             :step="1"
                             controls-position="right"
                             :formatter="value => stripTrailingZeros(value)"
                             :parser="value => parseFloat(value) || 0"
                             style="width: 100%;" />
          </template>
        </el-table-column>
@@ -111,6 +113,7 @@
        <span class="dialog-footer">
          <el-button type="primary"
                     :loading="materialSaving"
                     :disabled="isSaveDisabled"
                     @click="handleMaterialSave">保存</el-button>
          <el-button @click="dialogVisible = false">取消</el-button>
        </span>
@@ -155,30 +158,67 @@
  const materialTableLoading = ref(false);
  const materialSaving = ref(false);
  const materialTableData = ref([]);
  const isSaveDisabled = computed(() => {
    if (materialTableData.value.length === 0) return true;
    return !materialTableData.value.some(row => {
      // 检查是否有任何用户输入内容
      const hasBatch = Array.isArray(row.batchNo) && row.batchNo.length > 0;
      const hasPickQty =
        row.pickQty !== null && row.pickQty !== undefined && row.pickQty !== 0;
      if (row.bom) {
        // 对于来自BOM的行,输入框只有“批号”和“领用数量”
        return hasBatch || hasPickQty;
      } else {
        // 对于新增行,输入框包括“工序”、“原料”、“需求数量”、“批号”和“领用数量”
        const hasOperation = !!row.operationName;
        const hasMaterial = !!row.materialName;
        const hasDemanded =
          row.demandedQuantity !== null &&
          row.demandedQuantity !== undefined &&
          row.demandedQuantity !== 0;
        return (
          hasBatch || hasPickQty || hasOperation || hasMaterial || hasDemanded
        );
      }
    });
  });
  const processOptions = ref([]);
  const currentMaterialSelectRowIndex = ref(-1);
  let materialTempId = 0;
  const createMaterialRow = (row = {}) => ({
    tempId: row.id || `temp_${++materialTempId}`,
    id: row.id,
    processId: row.processId || row.technologyOperationId,
    technologyOperationId: row.technologyOperationId || row.processId,
    operationName: row.operationName || "",
    bom: row.bom === true,
    materialModelId: row.materialModelId || row.productModelId,
    materialName: row.materialName || row.productName || "",
    materialModel: row.materialModel || row.model || "",
    demandedQuantity: Number(row.requiredQty ?? row.demandedQuantity ?? 0),
    unit: row.unit || "",
    pickQty: Number(row.pickQty ?? row.pickQuantity ?? 0),
    batchNo: row.batchNo
  const getDefaultBatchNo = batchNoList => {
    if (!Array.isArray(batchNoList) || batchNoList.length === 0) return [];
    return [batchNoList[0]];
  };
  const createMaterialRow = (row = {}) => {
    const batchNoList = Array.isArray(row.batchNoList) ? row.batchNoList : [];
    const batchNo = row.batchNo
      ? typeof row.batchNo === "string"
        ? row.batchNo.split(",")
        : row.batchNo
      : [],
    batchNoList: row.batchNoList || [],
  });
      : getDefaultBatchNo(batchNoList);
    return {
      tempId: row.id || `temp_${++materialTempId}`,
      id: row.id,
      processId: row.processId || row.technologyOperationId,
      technologyOperationId: row.technologyOperationId || row.processId,
      operationName: row.operationName || "",
      bom: row.bom === true,
      materialModelId: row.materialModelId || row.productModelId,
      materialName: row.materialName || row.productName || "",
      materialModel: row.materialModel || row.model || "",
      demandedQuantity: Number(row.requiredQty ?? row.demandedQuantity ?? 0),
      unit: row.unit || "",
      pickQty: Number(row.pickQty ?? row.pickQuantity ?? row.requiredQty ?? row.demandedQuantity ?? 0),
      batchNo,
      batchNoList,
    };
  };
  const getProcessOptions = async () => {
    if (!props.orderRow?.id) return;
@@ -242,6 +282,14 @@
    }
  );
  const stripTrailingZeros = val => {
    const str = String(val);
    if (str.includes(".")) {
      return parseFloat(str).toString();
    }
    return str;
  };
  const handleClose = () => {
    materialTableData.value = [];
    currentMaterialSelectRowIndex.value = -1;
@@ -291,7 +339,8 @@
      product.materialName || product.productName || product.name || "";
    row.materialModel = product.materialModel || product.model || "";
    row.unit = product.unit || product.measureUnit || "";
    row.batchNoList = product.batchNoList;
    row.batchNoList = Array.isArray(product.batchNoList) ? product.batchNoList : [];
    row.batchNo = getDefaultBatchNo(row.batchNoList);
    currentMaterialSelectRowIndex.value = -1;
    materialProductDialogVisible.value = false;
  };