gongchunyi
2026-09-29 eee1310bc134b2bb7c8a406750cb64e9fe226ac2
src/views/salesManagement/salesLedger/index.vue
@@ -108,6 +108,8 @@
                               prop="specificationModel" />
              <el-table-column label="单位"
                               prop="unit" />
              <el-table-column label="件数"
                               prop="packagingSpec" />
              <el-table-column label="产品状态"
                               width="100px"
                               align="center">
@@ -130,6 +132,21 @@
                  <el-tag :type="getShippingStatusType(scope.row)"
                          size="small">
                    {{ getShippingStatusText(scope.row) }}
                  </el-tag>
                </template>
              </el-table-column>
              <el-table-column label="发货类型"
                               width="100"
                               align="center">
                <template #default="scope">
                  <el-tag v-if="getShippingTypeText(scope.row)"
                          :type="getShippingTypeTag(scope.row)"
                          size="small">
                    {{ getShippingTypeText(scope.row) }}
                  </el-tag>
                  <el-tag v-else
                          type="info"
                          size="small">-
                  </el-tag>
                </template>
              </el-table-column>
@@ -253,11 +270,17 @@
                       type="primary"
                       @click="openForm('view', scope.row)">详情
            </el-button>
            <el-button link
                       type="primary"
                       @click="openForm('edit', scope.row)"
                       :disabled="!scope.row.isEdit || scope.row.hasProductionRecord || !canEditLedger(scope.row)">编辑
            </el-button>
            <el-tooltip :content="editDisabledReason(scope.row)"
                        :disabled="!editDisabledReason(scope.row)"
                        placement="top">
              <span>
                <el-button link
                           type="primary"
                           @click="openForm('edit', scope.row)"
                           :disabled="isLedgerEditDisabled(scope.row)">编辑
                </el-button>
              </span>
            </el-tooltip>
            <el-button link
                       type="primary"
                       @click="openFileDialog(scope.row)">附件
@@ -462,6 +485,8 @@
                           prop="specificationModel" />
          <el-table-column label="单位"
                           prop="unit" />
          <el-table-column label="件数"
                           prop="packagingSpec" />
          <el-table-column label="数量"
                           prop="quantity" />
          <el-table-column label="税率(%)"
@@ -656,6 +681,15 @@
                           :label="dict.label"
                           :value="dict.value" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="件数:"
                          prop="packagingSpec">
              <el-input v-model="productForm.packagingSpec"
                        clearable />
            </el-form-item>
          </el-col>
        </el-row>
@@ -941,6 +975,8 @@
                           value="货车" />
                <el-option label="快递"
                           value="快递" />
                <el-option label="自送"
                           value="自送" />
              </el-select>
            </el-form-item>
          </el-col>
@@ -950,10 +986,16 @@
                        disabled />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="已选择发货数量:">
              <el-input :model-value="selectedDeliveryQuantity"
                        disabled />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="24"
                  v-if="deliveryForm.type === '货车'">
        <el-row :gutter="30"
                v-if="deliveryForm.type === '货车'">
          <el-col :span="24">
            <el-form-item label="发货车牌号:"
                          prop="shippingCarNumber">
              <el-input v-model="deliveryForm.shippingCarNumber"
@@ -961,8 +1003,10 @@
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="24"
                  v-else>
        </el-row>
        <el-row :gutter="30"
                v-else-if="deliveryForm.type === '快递'">
          <el-col :span="24">
            <el-form-item label="快递公司:"
                          prop="expressCompany">
              <el-input v-model="deliveryForm.expressCompany"
@@ -1088,6 +1132,7 @@
    tableAmountFormatter,
    formatDecimal,
    buildAmountSummaryFormat,
    roundAmount,
  } from "@/utils/numberFormat";
  import ImageUpload from "@/components/AttachmentUpload/image/index.vue";
  import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
@@ -1169,6 +1214,7 @@
      productModelId: "",
      specificationModel: "",
      unit: "",
      packagingSpec: "",
      quantity: "",
      taxInclusiveUnitPrice: "",
      taxRate: "",
@@ -1250,7 +1296,7 @@
      rawList.forEach(item => {
        total += Number(getDeliveryBatchQuantity(item) || 0);
      });
      currentStock.value = total;
      currentStock.value = roundAmount(total);
    } catch (e) {
      console.error(e);
      currentStock.value = 0;
@@ -1259,35 +1305,45 @@
  const getCurrentDeliveryRowQuantity = () => {
    return Number(currentDeliveryRow.value?.noQuantity || 0);
  };
  const selectedDeliveryQuantity = computed(() => {
    return roundAmount(
      (deliveryForm.value.batchNoList || []).reduce(
        (sum, item) => sum + Number(item?.deliveryQuantity || 0),
        0
      )
    );
  });
  const 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 otherBatchTotal = roundAmount(
      (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 remainingProductQuantity = roundAmount(
      Math.max(0, productQuantity - otherBatchTotal)
    );
    return Math.max(0, Math.min(batchQuantity, remainingProductQuantity));
  };
  const handleDeliveryBatchQuantityChange = 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 otherBatchTotal = roundAmount(
      (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 remainingProductQuantity = roundAmount(
      Math.max(0, productQuantity - otherBatchTotal)
    );
    const currentValue = Number(row?.deliveryQuantity || 0);
@@ -1341,7 +1397,7 @@
      shippingCarNumber: "",
      expressCompany: "",
      expressNumber: "",
      type: "货车", // 货车, 快递
      type: "货车", // 货车, 快递, 自送
    },
    deliveryRules: {
      shippingCarNumber: [
@@ -1507,6 +1563,18 @@
  };
  const canEditLedger = row => isCurrentUserMaintainer(row);
  const canDeleteLedger = row => isCurrentUserMaintainer(row);
  /**
   * 需要生产的订单:生产计划已下发(含部分下发)后不可编辑;
   * 走库存的订单:已发货后不可编辑,否则可以编辑。
   */
  const editDisabledReason = row => {
    if (!row) return "";
    if (!canEditLedger(row)) return "当前系统登录人不是维护人,不能编辑数据";
    if (row.hasProductionRecord) return "生产计划已下发,不能编辑";
    if (!row.isEdit) return "订单已发货,不能编辑";
    return "";
  };
  const isLedgerEditDisabled = row => !!editDisabledReason(row);
  const sensitiveAmountFormatter = (row, column, cellValue) => {
    if (!isCurrentUserMaintainer(row)) {
      return "*****";
@@ -1683,9 +1751,12 @@
  };
  // 打开弹框
  const openForm = async (type, row) => {
    if (type === "edit" && row && !canEditLedger(row)) {
      proxy.$modal.msgWarning("当前系统登录人不是维护人,不能编辑数据");
      return;
    if (type === "edit" && row) {
      const disabledReason = editDisabledReason(row);
      if (disabledReason) {
        proxy.$modal.msgWarning(disabledReason);
        return;
      }
    }
    operationType.value = type;
    form.value = {};
@@ -2426,16 +2497,33 @@
  };
  /**
   * 获取发货类型文本(货车/快递/自送)
   * 子表行未返回发货类型字段,依据互斥的发货信息推断:
   * 有车牌为货车,有快递公司/单号为快递,已发货但两者皆无为自送
   */
  const getShippingTypeText = row => {
    if (!row) return "";
    if (row.shippingCarNumber) return "货车";
    if (row.expressCompany || row.expressNumber) return "快递";
    if (row.shippingDate) return "自送";
    return "";
  };
  const getShippingTypeTag = row => {
    const type = getShippingTypeText(row);
    const typeTagMap = {
      货车: "warning",
      快递: "primary",
      自送: "success",
    };
    return typeTagMap[type] || "info";
  };
  /**
   * 判断是否可以发货
   * 只有在产品状态是充足,发货状态是待发货和审核拒绝的时候才可以发货
   * @param row 行数据
   */
  const canShip = row => {
    // 产品状态必须是充足(approveStatus === 1)
    if (row.approveStatus !== 1) {
      return false;
    }
    // 获取发货状态
    const shippingStatus = row.shippingStatus;
@@ -2490,7 +2578,7 @@
    // 检查是否可以发货
    if (!canShip(row)) {
      proxy.$modal.msgWarning(
        "只有在产品状态是充足,发货状态是待发货或审核拒绝的时候才可以发货"
        "只有在发货状态是待发货、审核拒绝或部分发货的时候才可以发货"
      );
      return;
    }
@@ -2521,9 +2609,11 @@
          proxy.$modal.msgWarning("请至少填写一个批号的发货数量");
          return;
        }
        const totalDeliveryQuantity = selectedBatchRows.reduce(
          (sum, item) => sum + Number(item.deliveryQuantity || 0),
          0
        const totalDeliveryQuantity = roundAmount(
          selectedBatchRows.reduce(
            (sum, item) => sum + Number(item.deliveryQuantity || 0),
            0
          )
        );
        const currentRowNoQuantity = Number(
          currentDeliveryRow.value?.noQuantity || 0
@@ -2605,8 +2695,12 @@
    if (val === "货车") {
      deliveryForm.value.expressCompany = "";
      deliveryForm.value.expressNumber = "";
    } else if (val === "快递") {
      deliveryForm.value.shippingCarNumber = "";
    } else {
      deliveryForm.value.shippingCarNumber = "";
      deliveryForm.value.expressCompany = "";
      deliveryForm.value.expressNumber = "";
    }
  };