spring
7 小时以前 b9c0cee25748ea2d5621a8ca56ceb855a9ce3700
src/views/productionManagement/workOrderManagement/components/MaterialDialog.vue
@@ -11,18 +11,33 @@
        <el-table-column label="原料名称" prop="materialName" min-width="140" />
        <el-table-column label="原料型号" prop="materialModel" min-width="140" />
        <el-table-column label="计量单位" prop="unit" min-width="100" />
        <el-table-column label="领用数量" prop="pickQty" min-width="100" />
        <el-table-column label="线边仓数量" prop="pickQty" min-width="100" />
        <el-table-column label="补料数量" prop="supplementQty" min-width="100" />
        <el-table-column label="退料数量" prop="returnQty" min-width="100" />
        <el-table-column label="实际数量" prop="actualQty" min-width="100" />
        <el-table-column label="操作" align="center" fixed="right" width="220">
        <el-table-column label="实际数量" min-width="140">
          <template #default="{ row }">
            <el-input-number
              v-model="row.actualQty"
              :min="0"
              :precision="3"
              :step="1"
              controls-position="right"
              style="width: 100%;"
            />
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" fixed="right" width="180">
          <template #default="{ row }">
            <el-button type="primary" link @click="openSupplementDialog(row)">补料</el-button>
            <el-button type="warning" link @click="openReturnDialog(row)">退料</el-button>
            <el-button type="info" link @click="openSupplementRecordDialog(row)">补料记录</el-button>
          </template>
        </el-table-column>
      </el-table>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" :loading="pickSubmitting" @click="handleSubmitPick">领用</el-button>
          <el-button @click="dialogVisible = false">取消</el-button>
        </span>
      </template>
    </el-dialog>
    <FormDialog
@@ -60,31 +75,6 @@
      </template>
    </FormDialog>
    <FormDialog
      v-model="returnDialogVisible"
      title="退料"
      width="500px"
      @confirm="handleSubmitReturn"
    >
      <el-form ref="returnFormRef" :model="returnForm" :rules="returnRules" label-width="120px">
        <el-form-item label="退料数量" prop="returnQty">
          <el-input-number
            v-model="returnForm.returnQty"
            :min="0.001"
            :precision="3"
            :step="1"
            style="width: 100%;"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" :loading="returnSubmitting" @click="handleSubmitReturn">确定</el-button>
          <el-button @click="returnDialogVisible = false">取消</el-button>
        </span>
      </template>
    </FormDialog>
    <el-dialog v-model="supplementRecordDialogVisible" title="补料记录" width="900px">
      <el-table v-loading="supplementRecordLoading" :data="supplementRecordTableData" border row-key="id">
        <el-table-column label="补料数量" prop="supplementQty" min-width="100" />
@@ -108,8 +98,8 @@
import {
  listWorkOrderMaterialLedger,
  addWorkOrderMaterialSupplement,
  addWorkOrderMaterialReturn,
  listWorkOrderMaterialSupplementRecord,
  pickWorkOrderMaterial,
} from "@/api/productionManagement/workOrder.js";
const props = defineProps({
@@ -134,6 +124,7 @@
const materialTableData = ref([]);
const currentMaterialRow = ref(null);
const currentMaterialOrderRow = ref(null);
const pickSubmitting = ref(false);
const supplementDialogVisible = ref(false);
const supplementSubmitting = ref(false);
@@ -141,13 +132,6 @@
const supplementForm = reactive({
  supplementQty: null,
  supplementReason: "",
});
const returnDialogVisible = ref(false);
const returnSubmitting = ref(false);
const returnFormRef = ref(null);
const returnForm = reactive({
  returnQty: null,
});
const supplementRecordDialogVisible = ref(false);
@@ -158,10 +142,6 @@
  supplementQty: [{ required: true, message: "请输入补料数量", trigger: "blur" }],
  supplementReason: [{ required: true, message: "请输入补料原因", trigger: "blur" }],
};
const returnRules = {
  returnQty: [{ required: true, message: "请输入退料数量", trigger: "blur" }],
};
const loadMaterialTable = async row => {
  if (!row?.id) return;
  currentMaterialOrderRow.value = row;
@@ -234,49 +214,6 @@
  });
};
const openReturnDialog = row => {
  currentMaterialRow.value = row;
  returnForm.returnQty = null;
  returnDialogVisible.value = true;
  nextTick(() => {
    returnFormRef.value?.clearValidate();
  });
};
const handleSubmitReturn = () => {
  returnFormRef.value?.validate(async valid => {
    if (!valid || !currentMaterialRow.value?.id) {
      ElMessage.warning("缺少物料明细ID");
      return;
    }
    const returnQty = Number(returnForm.returnQty);
    const minQty =
      Number(currentMaterialRow.value.pickQty || 0) +
      Number(currentMaterialRow.value.supplementQty || 0);
    if (returnQty < minQty) {
      ElMessage.warning(`退料数量不能低于领用数量+补料数量(${minQty})`);
      return;
    }
    returnSubmitting.value = true;
    try {
      await addWorkOrderMaterialReturn({
        materialLedgerId: currentMaterialRow.value.id,
        returnQty,
        workOrderId: currentMaterialOrderRow.value?.id,
      });
      returnDialogVisible.value = false;
      await loadMaterialTable(currentMaterialOrderRow.value);
      ElMessage.success("退料成功");
      emit("refresh");
    } catch (e) {
      console.error("退料失败", e);
      ElMessage.error("退料失败");
    } finally {
      returnSubmitting.value = false;
    }
  });
};
const openSupplementRecordDialog = async row => {
  supplementRecordDialogVisible.value = true;
  supplementRecordLoading.value = true;
@@ -293,4 +230,49 @@
    supplementRecordLoading.value = false;
  }
};
const validatePickRows = () => {
  if (materialTableData.value.length === 0) {
    return { valid: false, message: "暂无可领用物料" };
  }
  const invalidRow = materialTableData.value.find(item => item.actualQty === null || item.actualQty === undefined || item.actualQty === "");
  if (invalidRow) {
    return { valid: false, message: "请填写实际数量后再领用" };
  }
  const exceedRow = materialTableData.value.find(item => {
    const maxQty = Number(item.pickQty || 0) + Number(item.supplementQty || 0);
    return Number(item.actualQty || 0) > maxQty;
  });
  if (exceedRow) {
    return { valid: false, message: "实际数量不能大于领用数量+补料数量" };
  }
  return { valid: true, message: "" };
};
const handleSubmitPick = async () => {
  if (!currentMaterialOrderRow.value?.id) return;
  const validateResult = validatePickRows();
  if (!validateResult.valid) {
    ElMessage.warning(validateResult.message);
    return;
  }
  pickSubmitting.value = true;
  try {
    await pickWorkOrderMaterial({
      workOrderId: currentMaterialOrderRow.value.id,
      items: materialTableData.value.map(item => ({
        materialLedgerId: item.id,
        actualQty: Number(item.actualQty || 0),
      })),
    });
    ElMessage.success("领用成功");
    await loadMaterialTable(currentMaterialOrderRow.value);
    emit("refresh");
  } catch (e) {
    console.error("领用失败", e);
    ElMessage.error("领用失败");
  } finally {
    pickSubmitting.value = false;
  }
};
</script>