zhangwencui
2 天以前 4a23db908d36b20deab22a211da5f25c4f683cca
src/views/procurementManagement/procurementLedger/index.vue
@@ -215,6 +215,11 @@
            </el-button>
            <el-button link
                       type="primary"
                       @click="handleStockIn(scope.row)"
                       :disabled="scope.row.approvalStatus !== 3 || scope.row.stockInStatus === '完全入库'">入库
            </el-button>
            <el-button link
                       type="primary"
                       @click="openFileDialog(scope.row)">附件</el-button>
          </template>
        </el-table-column>
@@ -679,6 +684,86 @@
        </el-row>
      </el-form>
    </FormDialog>
    <!-- 入库弹窗 -->
    <FormDialog v-model="stockInDialogVisible"
                title="入库确认"
                :width="'90%'"
                @close="stockInDialogVisible = false"
                @confirm="submitStockIn"
                @cancel="stockInDialogVisible = false">
      <el-form :model="stockInForm"
               label-width="120px"
               label-position="top">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="采购合同号">
              <el-input v-model="stockInForm.purchaseContractNumber"
                        disabled />
            </el-form-item>
          </el-col>
        </el-row>
        <el-table :data="stockInForm.details"
                  border>
          <el-table-column align="center"
                           label="序号"
                           type="index"
                           width="60" />
          <el-table-column label="产品大类"
                           prop="productCategory"
                           show-overflow-tooltip />
          <el-table-column label="规格型号"
                           prop="specificationModel"
                           show-overflow-tooltip />
          <el-table-column label="单位"
                           prop="unit"
                           width="70" />
          <el-table-column label="待入库数量"
                           prop="availableQuality"
                           width="100" />
          <el-table-column label="本次入库数量"
                           width="130">
            <template #default="scope">
              <el-input-number v-model="scope.row.inboundQuantity"
                               :step="0.01"
                               :min="0"
                               :max="scope.row.availableQuality"
                               @change="handleInboundChange(scope.row)"
                               controls-position="right"
                               style="width: 100%" />
            </template>
          </el-table-column>
          <el-table-column label="是否含水"
                           width="100"
                           align="center">
            <template #default="scope">
              <el-switch v-model="scope.row.isContainsWater"
                         @change="handleInboundChange(scope.row)" />
            </template>
          </el-table-column>
          <el-table-column label="含水量(%)"
                           width="130">
            <template #default="scope">
              <el-input-number v-if="scope.row.isContainsWater"
                               v-model="scope.row.waterContent"
                               :precision="2"
                               :step="0.1"
                               :min="0"
                               :max="100"
                               @change="handleInboundChange(scope.row)"
                               controls-position="right"
                               style="width: 100%" />
              <span v-else>--</span>
            </template>
          </el-table-column>
          <el-table-column label="实际入库数量"
                           width="130">
            <template #default="scope">
              <span style="font-weight: bold; color: #409EFF;">{{ scope.row.actualInboundQuantity }}</span>
            </template>
          </el-table-column>
        </el-table>
      </el-form>
    </FormDialog>
    <FileList v-if="fileListDialogVisible"
              v-model:visible="fileListDialogVisible"
              record-type="purchase_ledger"
@@ -722,6 +807,7 @@
    getPurchaseTemplateList,
    delPurchaseTemplate,
  } from "@/api/procurementManagement/procurementLedger.js";
  import { addSutockIn } from "@/api/inventoryManagement/stockIn.js";
  import useFormData from "@/hooks/useFormData.js";
  const FileList = defineAsyncComponent(() =>
    import("@/components/Dialog/FileList.vue")
@@ -741,6 +827,14 @@
  const tableLoading = ref(false);
  const recordId = ref();
  const fileListDialogVisible = ref(false);
  // 入库弹窗相关
  const stockInDialogVisible = ref(false);
  const stockInLoading = ref(false);
  const stockInForm = reactive({
    purchaseLedgerId: null,
    purchaseContractNumber: "",
    details: [],
  });
  const page = reactive({
    current: 1,
    size: 100,
@@ -1234,6 +1328,108 @@
    productSelectedRows.value = selectedRows;
  };
  const expandedRowKeys = ref([]);
  // 入库处理
  const handleStockIn = async row => {
    stockInForm.purchaseLedgerId = row.id;
    stockInForm.purchaseContractNumber = row.purchaseContractNumber;
    stockInForm.details = [];
    try {
      proxy.$modal.loading("正在加载产品信息...");
      const res = await productList({ salesLedgerId: row.id, type: 2 });
      if (res.code === 200) {
        // 过滤掉已经完全入库的产品(如果有这个状态的话,或者直接显示所有可用数量大于0的产品)
        stockInForm.details = (res.data || [])
          .filter(item => (item.availableQuality || 0) > 0)
          .map(item => ({
            ...item,
            inboundQuantity: item.availableQuality || 0, // 默认入库全部可用数量
            isContainsWater: false,
            waterContent: 0,
            actualInboundQuantity: item.availableQuality || 0,
          }));
        if (stockInForm.details.length === 0) {
          proxy.$modal.msgWarning("该合同下没有可入库的产品记录");
          return;
        }
        stockInDialogVisible.value = true;
      }
    } catch (error) {
      console.error("加载产品列表失败:", error);
      proxy.$modal.msgError("加载产品列表失败");
    } finally {
      proxy.$modal.closeLoading();
    }
  };
  // 计算实际入库数量
  const handleInboundChange = row => {
    if (row.isContainsWater) {
      // 实际入库 = 本次入库数量 * (1 - 含水量/100)
      row.actualInboundQuantity = Number(
        (row.inboundQuantity * (1 - (row.waterContent || 0) / 100)).toFixed(2)
      );
    } else {
      row.actualInboundQuantity = row.inboundQuantity;
    }
  };
  const submitStockIn = async () => {
    if (stockInForm.details.length === 0) {
      proxy.$modal.msgWarning("请选择入库产品");
      return;
    }
    // 验证入库数量
    const invalid = stockInForm.details.some(
      item => !item.inboundQuantity || item.inboundQuantity <= 0
    );
    if (invalid) {
      proxy.$modal.msgWarning("请输入有效的入库数量");
      return;
    }
    const overLimit = stockInForm.details.some(
      item => item.inboundQuantity > item.availableQuality
    );
    if (overLimit) {
      proxy.$modal.msgWarning("入库数量不能超过可用数量");
      return;
    }
    try {
      stockInLoading.value = true;
      const params = {
        purchaseLedgerId: stockInForm.purchaseLedgerId,
        purchaseContractNumber: stockInForm.purchaseContractNumber,
        nickName: userStore.nickName,
        details: stockInForm.details.map(item => ({
          id: item.id,
          inboundQuantity: item.inboundQuantity,
          isContainsWater: item.isContainsWater,
          waterContent: item.isContainsWater ? item.waterContent : 0,
          actualInboundQuantity: item.actualInboundQuantity,
        })),
      };
      const res = await addSutockIn(params);
      if (res.code === 200) {
        proxy.$modal.msgSuccess("入库成功");
        stockInDialogVisible.value = false;
        getList(); // 刷新列表
      } else {
        proxy.$modal.msgError(res.msg || "入库失败");
      }
    } catch (error) {
      console.error("入库提交失败:", error);
      proxy.$modal.msgError("入库提交失败");
    } finally {
      stockInLoading.value = false;
    }
  };
  // 展开行
  const expandChange = async (row, expandedRows) => {
    if (expandedRows.length > 0) {