feat: 添加一键发货,自动审批通过出库,取消车牌必填项,发货完成后产品状态自己变为不足->变为已发货
已修改2个文件
319 ■■■■■ 文件已修改
src/api/salesManagement/deliveryLedger.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/salesLedger/index.vue 301 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/salesManagement/deliveryLedger.js
@@ -45,3 +45,21 @@
  });
}
// 一键发货 - 自动审批通过并出库
export function oneClickShipping(data) {
  return request({
    url: "/shippingInfo/oneClickShipping",
    method: "post",
    data,
  });
}
// 批量一键发货 - 将销售台账下所有未发货的产品全部发货
export function batchOneClickShipping(data) {
  return request({
    url: "/shippingInfo/batchOneClickShipping",
    method: "post",
    data,
  });
}
src/views/salesManagement/salesLedger/index.vue
@@ -51,11 +51,11 @@
                                                             width="100px"
                                                             align="center">
                <template #default="scope">
                                    <el-tag v-if="scope.row.approveStatus === 1 && (!scope.row.shippingDate || !scope.row.shippingCarNumber)"
                                                    type="success">充足</el-tag>
                                    <el-tag v-else-if="scope.row.approveStatus === 0 && (scope.row.shippingDate || scope.row.shippingCarNumber)"
                                                    type="success">已出库</el-tag>
                                    <!-- 已发货显示已出库 -->
                                    <el-tag v-if="scope.row.shippingDate" type="success">已出库</el-tag>
                                    <!-- 未发货且库存充足 -->
                                    <el-tag v-else-if="scope.row.approveStatus === 1" type="success">充足</el-tag>
                                    <!-- 未发货且库存不足 -->
                                    <el-tag v-else type="danger">不足</el-tag>
                </template>
              </el-table-column>
@@ -93,7 +93,7 @@
              <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
              <el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
            <!--操作-->
              <el-table-column Width="60px" label="操作" align="center">
              <el-table-column width="100px" label="操作" align="center">
                <template #default="scope">
                  <el-button
                    link
@@ -715,8 +715,93 @@
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button type="primary" @click="submitDelivery">确认发货</el-button>
                    <el-button type="success" @click="submitOneClickDelivery">一键发货</el-button>
                    <el-button type="primary" @click="submitDelivery">提交审批</el-button>
                    <el-button @click="closeDeliveryDia">取消</el-button>
                </div>
            </template>
        </el-dialog>
        <!-- 批量一键发货弹框 -->
        <el-dialog
            v-model="batchDeliveryFormVisible"
            title="批量一键发货"
            width="40%"
            @close="closeBatchDeliveryDia"
        >
            <el-form :model="batchDeliveryForm" label-width="120px" label-position="top" :rules="batchDeliveryRules" ref="batchDeliveryFormRef">
                <el-row :gutter="30">
                    <el-col :span="24">
                        <el-form-item label="发货类型:" prop="type">
                            <el-select
                                v-model="batchDeliveryForm.type"
                                placeholder="请选择发货类型"
                                style="width: 100%"
                            >
                                <el-option label="货车" value="货车" />
                                <el-option label="快递" value="快递" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="24">
                        <el-form-item label="发货日期:" prop="shippingDate">
                            <el-date-picker
                                style="width: 100%"
                                v-model="batchDeliveryForm.shippingDate"
                                value-format="YYYY-MM-DD"
                                format="YYYY-MM-DD"
                                type="date"
                                placeholder="请选择发货日期"
                                clearable
                            />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="24" v-if="batchDeliveryForm.type === '货车'">
                        <el-form-item label="发货车牌号:">
                            <el-input
                                v-model="batchDeliveryForm.shippingCarNumber"
                                placeholder="请输入发货车牌号"
                                clearable
                            />
                        </el-form-item>
                    </el-col>
                    <el-col :span="24" v-else>
                        <el-form-item label="快递公司:">
                            <el-input
                                v-model="batchDeliveryForm.expressCompany"
                                placeholder="请输入快递公司"
                                clearable
                            />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="30" v-if="batchDeliveryForm.type === '快递'">
                    <el-col :span="24">
                        <el-form-item label="快递单号:">
                            <el-input
                                v-model="batchDeliveryForm.expressNumber"
                                placeholder="请输入快递单号"
                                clearable
                            />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-alert
                    title="提示:将对该销售台账下所有未发货的产品进行一键发货,自动审批通过并出库"
                    type="warning"
                    :closable="false"
                    show-icon
                    style="margin-top: 10px;"
                />
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button type="success" @click="submitBatchDelivery">确认批量发货</el-button>
                    <el-button @click="closeBatchDeliveryDia">取消</el-button>
                </div>
            </template>
        </el-dialog>
@@ -726,8 +811,9 @@
<script setup>
import { getToken } from "@/utils/auth";
import pagination from "@/components/PIMTable/Pagination.vue";
import {onMounted, ref, getCurrentInstance} from "vue";
import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
import {onMounted, ref, getCurrentInstance, h} from "vue";
import { ElButton } from "element-plus";
import { addShippingInfo, oneClickShipping, batchOneClickShipping } from "@/api/salesManagement/deliveryLedger.js";
import { ElMessageBox, ElMessage } from "element-plus";
import { UploadFilled, Download } from "@element-plus/icons-vue";
import useUserStore from "@/store/modules/user";
@@ -871,6 +957,26 @@
// 发货相关
const deliveryFormVisible = ref(false);
const currentDeliveryRow = ref(null);
// 批量一键发货相关
const batchDeliveryFormVisible = ref(false);
const currentBatchDeliveryRow = ref(null);
const batchDeliveryFormData = reactive({
  batchDeliveryForm: {
    type: "货车",
    shippingDate: "",
    shippingCarNumber: "",
    expressCompany: "",
    expressNumber: "",
  },
  batchDeliveryRules: {
    type: [
      { required: true, message: "请选择发货类型", trigger: "change" }
    ],
    shippingDate: [{ required: true, message: "请选择发货日期", trigger: "change" }],
  },
});
const { batchDeliveryForm, batchDeliveryRules } = toRefs(batchDeliveryFormData);
const deliveryFileList = ref([]);
const deliveryFormData = reactive({
  deliveryForm: {
@@ -895,11 +1001,9 @@
});
const { deliveryForm, deliveryRules } = toRefs(deliveryFormData);
// 发货类型校验:货车时要求车牌,快递时要求快递公司
// 发货类型校验:货车时车牌非必填,快递时要求快递公司
const validateShippingCarNumber = (value, callback) => {
  if (deliveryForm.value.type === "货车") {
    if (!value) return callback(new Error("请输入发货车牌号"));
  }
  // 取消车牌必填限制
  callback();
};
const validateExpressCompany = (value, callback) => {
@@ -1098,6 +1202,8 @@
const expandChange = (row, expandedRows) => {
    if (expandedRows.length > 0) {
        expandedRowKeys.value = [];
        // 设置当前展开行,用于一键发货
        currentExpandedRow.value = row;
        try {
            productList({ salesLedgerId: row.id, type: 1 }).then((res) => {
                const index = tableData.value.findIndex((item) => item.id === row.id);
@@ -1111,6 +1217,7 @@
        }
    } else {
        expandedRowKeys.value = [];
        currentExpandedRow.value = null;
    }
};
@@ -1138,13 +1245,58 @@
        "taxExclusiveTotalPrice",
    ]);
};
// 子表合计方法
// 当前展开行的销售台账数据(用于一键发货)
const currentExpandedRow = ref(null);
// 当前展开行是否有未发货产品
const hasUnshippedProducts = ref(false);
// 子表合计方法 - 最后一列显示一键发货按钮
const summarizeChildrenTable = (param) => {
    return proxy.summarizeTable(param, [
        "taxInclusiveUnitPrice",
        "taxInclusiveTotalPrice",
        "taxExclusiveTotalPrice",
    ]);
    const { columns, data } = param;
    const sums = [];
    // 检查是否有未发货的产品
    const unshipped = data.filter(item => {
        const status = item.shippingStatus;
        return !item.shippingDate && (!status || status === '待发货' || status === '审核拒绝');
    });
    hasUnshippedProducts.value = unshipped.length > 0;
    columns.forEach((column, index) => {
        if (index === 0) {
            sums[index] = "合计";
            return;
        }
        const prop = column.property;
        const summaryProps = ["taxInclusiveUnitPrice", "taxInclusiveTotalPrice", "taxExclusiveTotalPrice"];
        if (summaryProps.includes(prop)) {
            const values = data.map((item) => Number(item[prop]));
            if (!values.every(isNaN)) {
                const sum = values.reduce((acc, val) => (!isNaN(val) ? acc + val : acc), 0);
                sums[index] = parseFloat(sum).toFixed(2);
            } else {
                sums[index] = "";
            }
        } else if (index === columns.length - 1 && currentExpandedRow.value && hasUnshippedProducts.value) {
            // 最后一列(操作列)渲染一键发货按钮,仅当有未发货产品时显示
            sums[index] = h(
                ElButton,
                {
                    type: 'success',
                    size: 'small',
                    onClick: () => openBatchDeliveryForm(currentExpandedRow.value)
                },
                { default: () => '一键发货' }
            );
        } else {
            sums[index] = "";
        }
    });
    return sums;
};
// 打开弹框
const openForm = async (type, row) => {
@@ -2299,6 +2451,55 @@
  });
};
// 一键发货 - 自动审批通过并出库
const submitOneClickDelivery = () => {
  proxy.$refs["deliveryFormRef"].validate((valid) => {
    if (valid) {
      // 保存当前展开的行ID,以便发货后重新加载子表格数据
      const currentExpandedKeys = [...expandedRowKeys.value];
      const salesLedgerId = currentDeliveryRow.value.salesLedgerId;
      // 获取上传图片的临时ID
      let tempFileIds = [];
      if (deliveryFileList.value !== null && deliveryFileList.value.length > 0) {
        tempFileIds = deliveryFileList.value.map((item) => item.tempId);
      }
      oneClickShipping({
        salesLedgerId: salesLedgerId,
        salesLedgerProductId: currentDeliveryRow.value.id,
        type: deliveryForm.value.type,
        shippingDate: deliveryForm.value.shippingDate,
        shippingCarNumber: deliveryForm.value.type === "货车" ? deliveryForm.value.shippingCarNumber : "",
        expressCompany: deliveryForm.value.type === "快递" ? deliveryForm.value.expressCompany : "",
        expressNumber: deliveryForm.value.type === "快递" ? deliveryForm.value.expressNumber : "",
        tempFileIds: tempFileIds,
      })
        .then(() => {
          proxy.$modal.msgSuccess("一键发货成功");
          closeDeliveryDia();
          // 刷新主表数据
          getList().then(() => {
            // 如果之前有展开的行,重新加载这些行的子表格数据
            if (currentExpandedKeys.length > 0) {
              const loadPromises = currentExpandedKeys.map(ledgerId => {
                return productList({ salesLedgerId: ledgerId, type: 1 }).then((res) => {
                  const index = tableData.value.findIndex((item) => item.id === ledgerId);
                  if (index > -1) {
                    tableData.value[index].children = res.data;
                  }
                });
              });
              Promise.all(loadPromises).then(() => {
                expandedRowKeys.value = currentExpandedKeys;
              });
            }
          });
        })
    }
  });
};
// 关闭发货弹框
const closeDeliveryDia = () => {
  proxy.resetForm("deliveryFormRef");
@@ -2306,6 +2507,68 @@
  deliveryFormVisible.value = false;
  currentDeliveryRow.value = null;
};
// 打开批量一键发货弹框
const openBatchDeliveryForm = (row) => {
  currentBatchDeliveryRow.value = row;
  batchDeliveryForm.value = {
    type: "货车",
    shippingDate: getCurrentDate(),
    shippingCarNumber: "",
    expressCompany: "",
    expressNumber: "",
  };
  batchDeliveryFormVisible.value = true;
};
// 关闭批量发货弹框
const closeBatchDeliveryDia = () => {
  proxy.resetForm("batchDeliveryFormRef");
  batchDeliveryFormVisible.value = false;
  currentBatchDeliveryRow.value = null;
};
// 提交批量一键发货
const submitBatchDelivery = () => {
  proxy.$refs["batchDeliveryFormRef"].validate((valid) => {
    if (valid) {
      // 保存当前展开的行ID
      const currentExpandedKeys = [...expandedRowKeys.value];
      const salesLedgerId = currentBatchDeliveryRow.value.id;
      batchOneClickShipping({
        salesLedgerId: salesLedgerId,
        type: batchDeliveryForm.value.type,
        shippingDate: batchDeliveryForm.value.shippingDate,
        shippingCarNumber: batchDeliveryForm.value.type === "货车" ? batchDeliveryForm.value.shippingCarNumber : "",
        expressCompany: batchDeliveryForm.value.type === "快递" ? batchDeliveryForm.value.expressCompany : "",
        expressNumber: batchDeliveryForm.value.type === "快递" ? batchDeliveryForm.value.expressNumber : "",
      })
        .then(() => {
          proxy.$modal.msgSuccess("批量发货成功");
          closeBatchDeliveryDia();
          // 刷新主表数据
          getList().then(() => {
            // 如果之前有展开的行,重新加载这些行的子表格数据
            if (currentExpandedKeys.length > 0) {
              const loadPromises = currentExpandedKeys.map(ledgerId => {
                return productList({ salesLedgerId: ledgerId, type: 1 }).then((res) => {
                  const index = tableData.value.findIndex((item) => item.id === ledgerId);
                  if (index > -1) {
                    tableData.value[index].children = res.data;
                  }
                });
              });
              Promise.all(loadPromises).then(() => {
                expandedRowKeys.value = currentExpandedKeys;
              });
            }
          });
        })
    }
  });
};
const currentFactoryName = ref("");
const getCurrentFactoryName = async () => {
    let res = await userStore.getInfo();