gaoluyang
4 天以前 6e173210a874ff7601aa68eab56e912f5619c79c
src/views/salesManagement/salesLedger/index.vue
@@ -100,12 +100,10 @@
                               width="100px"
                               align="center">
                <template #default="scope">
                  <el-tag
                      v-if="scope.row.approveStatus === 1 && scope.row.noQuantity !== 0"
                  <el-tag v-if="scope.row.approveStatus === 1 "
                      type="success">充足
                  </el-tag>
                  <el-tag
                      v-else-if="scope.row.approveStatus === 0 && scope.row.noQuantity === 0"
                  <el-tag v-else-if="scope.row.approveStatus === 0 && scope.row.noQuantity === 0"
                      type="success">已出库
                  </el-tag>
                  <el-tag v-else
@@ -286,10 +284,15 @@
          <el-col :span="12">
            <el-form-item label="销售合同号:"
                          prop="salesContractNo">
              <div style="display: flex; align-items: center; gap: 12px;width: 100%;">
                <el-checkbox v-model="form.autoGenerateContractNo" v-if="operationType === 'add'">自动生成
                </el-checkbox>
              <el-input v-model="form.salesContractNo"
                        placeholder="自动生成"
                          :placeholder="form.autoGenerateContractNo ? '自动生成' : '请输入'"
                        clearable
                        disabled/>
                          :disabled="form.autoGenerateContractNo" />
              </div>
            </el-form-item>
          </el-col>
          <el-col :span="12">
@@ -640,12 +643,10 @@
                         placeholder="请选择"
                         clearable
                         @change="calculateFromTaxRate">
                <el-option
                  v-for="dict in tax_rate"
                <el-option v-for="dict in tax_rate"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
                           :value="dict.value" />
              </el-select>
            </el-form-item>
          </el-col>
@@ -762,7 +763,9 @@
    </FormDialog>
    <!-- // todo 附件预览相关 -->
    <!-- 附件列表弹窗 -->
    <FileList v-if="fileDialogVisible" v-model:visible="fileDialogVisible" record-type="sales_ledger"
    <FileList v-if="fileDialogVisible"
              v-model:visible="fileDialogVisible"
              record-type="sales_ledger"
              :record-id="recordId"/>
    <!-- 打印预览弹窗 -->
    <el-dialog v-model="printPreviewVisible"
@@ -900,12 +903,54 @@
                          prop="type">
              <el-select v-model="deliveryForm.type"
                         placeholder="请选择发货类型"
                         style="width: 100%">
                         style="width: 100%"
                         @change="handleDeliveryTypeChange">
                <el-option label="货车"
                           value="货车"/>
                <el-option label="快递"
                           value="快递"/>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="待发货数量:">
              <el-input :model-value="currentDeliveryRow?.noQuantity"
                        disabled />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="24" v-if="deliveryForm.type === '货车'">
            <el-form-item label="发货车牌号:"
                          prop="shippingCarNumber">
              <el-input v-model="deliveryForm.shippingCarNumber"
                        placeholder="请输入发货车牌号"
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="24" v-else>
            <el-form-item label="快递公司:"
                          prop="expressCompany">
              <el-input v-model="deliveryForm.expressCompany"
                        placeholder="请输入快递公司"
                        clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30" v-if="deliveryForm.type === '快递'">
          <el-col :span="24">
            <el-form-item label="快递单号:"
                          prop="expressNumber">
              <el-input v-model="deliveryForm.expressNumber"
                        placeholder="请输入快递单号"
                        clearable />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="发货图片:">
              <ImageUpload v-model:file-list="deliveryFileList" :limit="9" />
            </el-form-item>
          </el-col>
        </el-row>
@@ -921,7 +966,7 @@
                <el-table-column label="批号"
                                 prop="batchNo"
                                 min-width="180"/>
                <el-table-column label="数量"
                <el-table-column label="库存数量"
                                 min-width="120"
                                 align="center">
                  <template #default="scope">
@@ -986,10 +1031,13 @@
import useFormData from "@/hooks/useFormData.js";
import dayjs from "dayjs";
import FileUpload from "@/components/AttachmentUpload/file/index.vue";
  import ImageUpload from "@/components/AttachmentUpload/image/index.vue";
import { getCurrentDate } from "@/utils/index.js";
import {listCustomer} from "@/api/basicData/customer.js";
const FileList = defineAsyncComponent(() => import("@/components/Dialog/FileList.vue"));
  const FileList = defineAsyncComponent(() =>
    import("@/components/Dialog/FileList.vue")
  );
const router = useRouter();
const route = useRoute();
@@ -1011,6 +1059,7 @@
});
const total = ref(0);
const fileList = ref([]);
  const deliveryFileList = ref([]);
// 用户信息表单弹框数据
const operationType = ref("");
@@ -1025,6 +1074,7 @@
  },
  form: {
    salesContractNo: "",
      autoGenerateContractNo: true,
    salesman: "",
    customerId: "",
    entryPerson: "",
@@ -1112,12 +1162,13 @@
const deliveryFormVisible = ref(false);
const currentDeliveryRow = ref(null);
const getDeliveryBatchQuantity = item => {
  const quantity = item?.qualitity
      ?? item?.quantity
      ?? item?.unLockedQuantity
      ?? item?.qualifiedUnLockedQuantity
      ?? item?.qualifiedQuantity
      ?? item?.stockQuantity;
    const quantity =
      item?.qualitity ??
      item?.quantity ??
      item?.unLockedQuantity ??
      item?.qualifiedUnLockedQuantity ??
      item?.qualifiedQuantity ??
      item?.stockQuantity;
  return quantity ?? 0;
};
const getCurrentDeliveryRowQuantity = () => {
@@ -1140,11 +1191,27 @@
  return Math.max(0, Math.min(batchQuantity, remainingProductQuantity));
};
const handleDeliveryBatchQuantityChange = row => {
  const max = getDeliveryBatchDeliveryMax(row);
    const productQuantity = getCurrentDeliveryRowQuantity();
    const batchQuantity = Number(getDeliveryBatchQuantity(row) || 0);
    const otherBatchTotal = (deliveryForm.value.batchNoList || []).reduce(
      (sum, item) => {
        if (item?.id === row?.id) return sum;
        return sum + Number(item?.deliveryQuantity || 0);
      },
      0
    );
    const remainingProductQuantity = Math.max(
      0,
      productQuantity - otherBatchTotal
    );
  const currentValue = Number(row?.deliveryQuantity || 0);
  if (currentValue > max) {
    row.deliveryQuantity = max;
    proxy.$modal.msgWarning("发货数量不能超过这个产品的数量");
    if (currentValue > batchQuantity) {
      row.deliveryQuantity = batchQuantity;
      proxy.$modal.msgWarning("发货数量不能大于库存数量");
    } else if (currentValue > remainingProductQuantity) {
      row.deliveryQuantity = remainingProductQuantity;
      proxy.$modal.msgWarning("所有批次发货数量之和不能大于待发货数量");
  }
};
const getSelectedDeliveryBatchRows = () => {
@@ -1159,22 +1226,43 @@
      ? res.data
      : res?.data?.records || res?.data?.rows || [];
  const seenIds = new Set();
  return rawList.filter(item => {
    return rawList
      .filter(item => {
    if (!item?.id || !item?.batchNo || seenIds.has(item.id)) {
      return false;
    }
    seenIds.add(item.id);
    return true;
  }).map(item => ({
      })
      .map(item => ({
    ...item,
    deliveryQuantity: 0,
  }));
};
  const validateDeliveryShippingCarNumber = (_rule, value, callback) => {
    if (deliveryForm.value.type === "货车" && !value) {
      return callback(new Error("请输入发货车牌号"));
    }
    callback();
  };
  const validateDeliveryExpressCompany = (_rule, value, callback) => {
    if (deliveryForm.value.type === "快递" && !value) {
      return callback(new Error("请输入快递公司"));
    }
    callback();
  };
const deliveryFormData = reactive({
  deliveryForm: {
      shippingCarNumber: "",
      expressCompany: "",
      expressNumber: "",
    type: "货车", // 货车, 快递
  },
  deliveryRules: {
      shippingCarNumber: [
        { validator: validateDeliveryShippingCarNumber, trigger: "blur" },
      ],
      expressCompany: [{ validator: validateDeliveryExpressCompany, trigger: "blur" }],
    type: [{required: true, message: "请选择发货类型", trigger: "change"}],
  },
});
@@ -1496,7 +1584,7 @@
  selectedQuotation.value = null;
  let userLists = await userListNoPage();
  userList.value = userLists.data;
  listCustomer({current: -1, size: -1}).then(res => {
    listCustomer({ current: -1, size: -1, type: 0 }).then(res => {
    customerOption.value = res.data.records;
  });
  form.value.entryPerson = userStore.id;
@@ -1505,6 +1593,8 @@
    form.value.entryDate = getCurrentDate();
    // 签订日期默认为当天
    form.value.executionDate = getCurrentDate();
      // 默认自动生成销售合同号
      form.value.autoGenerateContractNo = true;
  } else {
    currentId.value = row.id;
    getSalesLedgerWithProducts({id: row.id, type: 1}).then(res => {
@@ -1512,6 +1602,8 @@
      form.value.entryPerson = Number(res.entryPerson);
      productData.value = form.value.productData;
      fileList.value = form.value.storageBlobVOs;
        // 编辑时设置自动生成为false,允许手动修改
        form.value.autoGenerateContractNo = false;
    });
  }
  // let userAll = await userStore.getInfo()
@@ -1623,6 +1715,8 @@
      taxExclusiveTotalPrice: taxExclusiveTotalPrice,
      invoiceType: "增普票",
      isProduction: true,
        productId: p.productId,
        productModelId: p.productModelId
    };
  });
@@ -1646,6 +1740,9 @@
      }
      form.value.storageBlobDTOs = fileList;
      form.value.type = 1;
        if (form.value.autoGenerateContractNo) {
          form.value.salesContractNo = '';
        }
      addOrUpdateSalesLedger(form.value).then(res => {
        proxy.$modal.msgSuccess("提交成功");
        closeDia();
@@ -2145,8 +2242,10 @@
                                                              <tbody>
                                                                ${
        item.products &&
        item.products
            .length > 0
                                                                              item
                                                                                .products
                                                                                .length >
                                                                                0
            ? item.products
                .map(
                    product => `
@@ -2178,7 +2277,9 @@
                                                                    </tr>
                                                                  `
                )
                .join("")
                                                                                    .join(
                                                                                      ""
                                                                                    )
            : '<tr><td colspan="6" style="text-align: center; color: #999;">暂无产品数据</td></tr>'
    }
                                                              </tbody>
@@ -2508,6 +2609,7 @@
    审核拒绝: "审核拒绝",
    审核通过: "审核通过",
    已发货: "已发货",
      部分发货: "部分发货",
  };
  return statusTextMap[statusStr] || "待发货";
};
@@ -2539,6 +2641,7 @@
    审核拒绝: "danger",
    审核通过: "success",
    已发货: "success",
      部分发货: "warning",
  };
  return typeTextMap[statusStr] || "info";
};
@@ -2564,18 +2667,18 @@
  // 发货状态必须是"待发货"或"审核拒绝"
  const statusStr = shippingStatus ? String(shippingStatus).trim() : "";
  return statusStr === "待发货" || statusStr === "审核拒绝";
    return statusStr === "待发货" || statusStr === "审核拒绝" || statusStr === "部分发货";
};
// 打开附件弹窗
const recordId = ref(0)
const fileDialogVisible = ref(false)
  const recordId = ref(0);
  const fileDialogVisible = ref(false);
// 打开附件弹框
const openFileDialog = async (row) => {
  recordId.value = row.id
  fileDialogVisible.value = true
}
  const openFileDialog = async row => {
    recordId.value = row.id;
    fileDialogVisible.value = true;
  };
// 打开发货弹框
const openDeliveryForm = async row => {
@@ -2592,10 +2695,14 @@
      row.productModelId || row.modelId
  );
  deliveryForm.value = {
      shippingCarNumber: "",
      expressCompany: "",
      expressNumber: "",
    type: "货车",
    batchNo: [],
    batchNoList,
  };
    deliveryFileList.value = [];
  deliveryFormVisible.value = true;
};
@@ -2612,20 +2719,40 @@
          (sum, item) => sum + Number(item.deliveryQuantity || 0),
          0
      );
      const currentRowQuantity = Number(currentDeliveryRow.value?.quantity || 0);
      if (currentRowQuantity > 0 && totalDeliveryQuantity > currentRowQuantity) {
        proxy.$modal.msgWarning("批号发货总数不能超过当前产品数量");
        const currentRowNoQuantity = Number(
          currentDeliveryRow.value?.noQuantity || 0
        );
        if (
          currentRowNoQuantity > 0 &&
          totalDeliveryQuantity > currentRowNoQuantity
        ) {
          proxy.$modal.msgWarning("批号发货总数不能超过待发货数量");
        return;
      }
      // 保存当前展开的行ID,以便发货后重新加载子表格数据
      const currentExpandedKeys = [...expandedRowKeys.value];
      const salesLedgerId = currentDeliveryRow.value.salesLedgerId;
      deliveryForm.value.batchNo = selectedBatchRows.map(item => item.id);
      const productModelId = currentDeliveryRow.value.productModelId || currentDeliveryRow.value.modelId;
        const productModelId =
          currentDeliveryRow.value.productModelId ||
          currentDeliveryRow.value.modelId;
      addShippingInfo({
        salesLedgerId: salesLedgerId,
        salesLedgerProductId: currentDeliveryRow.value.id,
        type: deliveryForm.value.type,
          shippingCarNumber:
            deliveryForm.value.type === "货车"
              ? deliveryForm.value.shippingCarNumber
              : "",
          expressCompany:
            deliveryForm.value.type === "快递"
              ? deliveryForm.value.expressCompany
              : "",
          expressNumber:
            deliveryForm.value.type === "快递"
              ? deliveryForm.value.expressNumber
              : "",
          storageBlobDTOs: deliveryFileList.value || [],
        batchNo: deliveryForm.value.batchNo,
        batchNoDetailList: selectedBatchRows.map(item => ({
          stockInventoryId: item.id,
@@ -2665,8 +2792,18 @@
};
// 关闭发货弹框
  const handleDeliveryTypeChange = val => {
    if (val === "货车") {
      deliveryForm.value.expressCompany = "";
      deliveryForm.value.expressNumber = "";
    } else {
      deliveryForm.value.shippingCarNumber = "";
    }
  };
const closeDeliveryDia = () => {
  proxy.resetForm("deliveryFormRef");
    deliveryFileList.value = [];
  deliveryFormVisible.value = false;
  currentDeliveryRow.value = null;
};