5 天以前 3d15065e1a1b5297033cebb87165dd6298706705
Merge remote-tracking branch 'origin/dev_NEW_pro' into dev_NEW_pro
已修改14个文件
767 ■■■■ 文件已修改
src/api/salesManagement/deliveryLedger.js 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue 490 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/purchaseReturnOrder/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/processRoute/processRouteItem/index.vue 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionCosting/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionOrder/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionReporting/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionTraceability/index.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/workOrderManagement/index.vue 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionPlan/productionPlan/index.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/deliveryLedger/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/salesLedger/index.vue 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/salesManagement/deliveryLedger.js
@@ -17,6 +17,14 @@
    method: "get",
  });
}
// 修改发货台账
export function getDeliveryDetailByShippingNo(query) {
  return request({
    url: "/shippingInfo/getDateilByShippingNo",
    method: "get",
    params: query,
  });
}
export function addOrUpdateDeliveryLedger(query) {
  return request({
@@ -51,4 +59,3 @@
    data,
  });
}
src/router/index.js
@@ -155,12 +155,6 @@
    meta: { title: "财务管理", icon: "money" },
    children: [
      {
        path: "general-ledger",
        component: () => import("@/views/financialManagement/generalLedger/index.vue"),
        name: "GeneralLedger",
        meta: { title: "总帐科目" },
      },
      {
        path: "sales-out",
        component: () => import("@/views/financialManagement/receivable/salesOut.vue"),
        name: "SalesOut",
@@ -172,12 +166,7 @@
        name: "SalesReturn",
        meta: { title: "销售退货" },
      },
      {
        path: "receivable-reconciliation",
        component: () => import("@/views/financialManagement/receivable/reconciliation.vue"),
        name: "ReceivableReconciliation",
        meta: { title: "应收对账" },
      },
      {
        path: "invoice-apply",
        component: () => import("@/views/financialManagement/receivable/invoiceApply.vue"),
@@ -197,17 +186,18 @@
        meta: { title: "收款单" },
      },
      {
        path: "receivable-reconciliation",
        component: () => import("@/views/financialManagement/receivable/reconciliation.vue"),
        name: "ReceivableReconciliation",
        meta: { title: "应收对账" },
      },
      {
        path: "purchase-in",
        component: () => import("@/views/financialManagement/payable/purchaseIn.vue"),
        name: "PurchaseIn",
        meta: { title: "采购入库" },
      },
      {
        path: "payable-reconciliation",
        component: () => import("@/views/financialManagement/payable/reconciliation.vue"),
        name: "PayableReconciliation",
        meta: { title: "应付对账" },
      },
      {
        path: "input-invoice",
        component: () => import("@/views/financialManagement/payable/input-invoice.vue"),
@@ -220,11 +210,18 @@
        name: "PaymentApply",
        meta: { title: "付款申请" },
      },
      {
        path: "payment",
        component: () => import("@/views/financialManagement/payable/payment.vue"),
        name: "Payment",
        meta: { title: "付款单" },
      },
      {
        path: "payable-reconciliation",
        component: () => import("@/views/financialManagement/payable/reconciliation.vue"),
        name: "PayableReconciliation",
        meta: { title: "应付对账" },
      },
      {
        path: "fixed-assets",
@@ -239,6 +236,12 @@
        meta: { title: "无形资产" },
      },
      {
        path: "general-ledger",
        component: () => import("@/views/financialManagement/generalLedger/index.vue"),
        name: "GeneralLedger",
        meta: { title: "总帐科目" },
      },
      {
        path: "voucher",
        component: () => import("@/views/financialManagement/voucher/index.vue"),
        name: "Voucher",
src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
@@ -1,85 +1,103 @@
<template>
  <div>
    <el-dialog
      v-model="dialogFormVisible"
    <el-dialog v-model="dialogFormVisible"
      :title="operationType === 'approval' ? '审批' : '详情'"
      width="700px"
      @close="closeDia"
    >
            <el-form :model="form" label-width="140px" label-position="top" ref="formRef">
               @close="closeDia">
      <el-form :model="form"
               label-width="140px"
               label-position="top"
               ref="formRef">
                <el-row>
                    <el-col :span="24">
                        <el-form-item label="流程编号:" prop="approveId">
                            <el-input v-model="form.approveId" placeholder="自动编号" clearable disabled/>
            <el-form-item label="流程编号:"
                          prop="approveId">
              <el-input v-model="form.approveId"
                        placeholder="自动编号"
                        clearable
                        disabled />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="24">
                        <el-form-item label="申请部门:">
                            <el-select
                                disabled
              <el-select disabled
                                v-model="form.approveDeptId"
                                placeholder="选择部门"
                            >
                                <el-option
                                    v-for="user in productOptions"
                         placeholder="选择部门">
                <el-option v-for="user in productOptions"
                                    :key="user.deptId"
                                    :label="user.deptName"
                                    :value="user.deptId"
                                />
                           :value="user.deptId" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row v-if="!isQuotationApproval && !isPurchaseApproval">
                    <el-col :span="24">
                        <el-form-item :label="props.approveType == 5 ? '采购合同号:' : '审批事由:'" prop="approveReason">
                            <el-input v-model="form.approveReason" placeholder="请输入" clearable type="textarea" disabled/>
            <el-form-item :label="props.approveType == 5 ? '采购合同号:' : '审批事由:'"
                          prop="approveReason">
              <el-input v-model="form.approveReason"
                        placeholder="请输入"
                        clearable
                        type="textarea"
                        disabled />
                        </el-form-item>
                    </el-col>
                </el-row>
            </el-form>
      <!-- 报价审批:展示报价详情(复用销售报价"查看详情对话框"内容结构) -->
      <div v-if="isQuotationApproval" style="margin: 10px 0 18px;">
      <div v-if="isQuotationApproval"
           style="margin: 10px 0 18px;">
        <el-divider content-position="left">报价详情</el-divider>
        <el-skeleton :loading="quotationLoading" animated>
        <el-skeleton :loading="quotationLoading"
                     animated>
          <template #template>
            <el-skeleton-item variant="h3" style="width: 30%" />
            <el-skeleton-item variant="text" style="width: 100%" />
            <el-skeleton-item variant="text" style="width: 100%" />
            <el-skeleton-item variant="h3"
                              style="width: 30%" />
            <el-skeleton-item variant="text"
                              style="width: 100%" />
            <el-skeleton-item variant="text"
                              style="width: 100%" />
          </template>
          <template #default>
            <el-empty v-if="!currentQuotation || !currentQuotation.quotationNo" description="未查询到对应报价详情" />
            <el-empty v-if="!currentQuotation || !currentQuotation.quotationNo"
                      description="未查询到对应报价详情" />
            <template v-else>
              <el-descriptions :column="2" border>
              <el-descriptions :column="2"
                               border>
                <el-descriptions-item label="报价单号">{{ currentQuotation.quotationNo }}</el-descriptions-item>
                <el-descriptions-item label="客户名称">{{ currentQuotation.customer }}</el-descriptions-item>
                <el-descriptions-item label="业务员">{{ currentQuotation.salesperson }}</el-descriptions-item>
                <el-descriptions-item label="报价日期">{{ currentQuotation.quotationDate }}</el-descriptions-item>
                <el-descriptions-item label="有效期至">{{ currentQuotation.validDate }}</el-descriptions-item>
                <el-descriptions-item label="付款方式">{{ currentQuotation.paymentMethod }}</el-descriptions-item>
                <el-descriptions-item label="报价总额" :span="2">
                <el-descriptions-item label="报价总额"
                                      :span="2">
                  <span style="font-size: 18px; color: #e6a23c; font-weight: bold;">
                    ¥{{ Number(currentQuotation.totalAmount ?? 0).toFixed(2) }}
                  </span>
                </el-descriptions-item>
              </el-descriptions>
              <div style="margin-top: 20px;">
                <h4>产品明细</h4>
                <el-table :data="currentQuotation.products || []" border style="width: 100%">
                  <el-table-column prop="product" label="产品名称" />
                  <el-table-column prop="specification" label="规格型号" />
                  <el-table-column prop="unit" label="单位" />
                  <el-table-column prop="unitPrice" label="单价">
                <el-table :data="currentQuotation.products || []"
                          border
                          style="width: 100%">
                  <el-table-column prop="product"
                                   label="产品名称" />
                  <el-table-column prop="specification"
                                   label="规格型号" />
                  <el-table-column prop="unit"
                                   label="单位" />
                  <el-table-column prop="unitPrice"
                                   label="单价">
                    <template #default="scope">¥{{ Number(scope.row.unitPrice ?? 0).toFixed(2) }}</template>
                  </el-table-column>
                </el-table>
              </div>
              <div v-if="currentQuotation.remark" style="margin-top: 20px;">
              <div v-if="currentQuotation.remark"
                   style="margin-top: 20px;">
                <h4>备注</h4>
                <p>{{ currentQuotation.remark }}</p>
              </div>
@@ -87,20 +105,26 @@
          </template>
        </el-skeleton>
      </div>
      <!-- 采购审批:展示采购详情 -->
      <div v-if="isPurchaseApproval" style="margin: 10px 0 18px;">
      <div v-if="isPurchaseApproval"
           style="margin: 10px 0 18px;">
        <el-divider content-position="left">采购详情</el-divider>
        <el-skeleton :loading="purchaseLoading" animated>
        <el-skeleton :loading="purchaseLoading"
                     animated>
          <template #template>
            <el-skeleton-item variant="h3" style="width: 30%" />
            <el-skeleton-item variant="text" style="width: 100%" />
            <el-skeleton-item variant="text" style="width: 100%" />
            <el-skeleton-item variant="h3"
                              style="width: 30%" />
            <el-skeleton-item variant="text"
                              style="width: 100%" />
            <el-skeleton-item variant="text"
                              style="width: 100%" />
          </template>
          <template #default>
            <el-empty v-if="!currentPurchase || !currentPurchase.purchaseContractNumber" description="未查询到对应采购详情" />
            <el-empty v-if="!currentPurchase || !currentPurchase.purchaseContractNumber"
                      description="未查询到对应采购详情" />
            <template v-else>
              <el-descriptions :column="2" border>
              <el-descriptions :column="2"
                               border>
                <el-descriptions-item label="采购合同号">{{ currentPurchase.purchaseContractNumber }}</el-descriptions-item>
                <el-descriptions-item label="供应商名称">{{ currentPurchase.supplierName }}</el-descriptions-item>
                <el-descriptions-item label="项目名称">{{ currentPurchase.projectName }}</el-descriptions-item>
@@ -108,24 +132,32 @@
                <el-descriptions-item label="签订日期">{{ currentPurchase.executionDate }}</el-descriptions-item>
                <el-descriptions-item label="录入日期">{{ currentPurchase.entryDate }}</el-descriptions-item>
                <el-descriptions-item label="付款方式">{{ currentPurchase.paymentMethod }}</el-descriptions-item>
                <el-descriptions-item label="合同金额" :span="2">
                <el-descriptions-item label="合同金额"
                                      :span="2">
                  <span style="font-size: 18px; color: #e6a23c; font-weight: bold;">
                    ¥{{ Number(currentPurchase.contractAmount ?? 0).toFixed(2) }}
                  </span>
                </el-descriptions-item>
              </el-descriptions>
              <div style="margin-top: 20px;">
                <h4>产品明细</h4>
                <el-table :data="currentPurchase.productData || []" border style="width: 100%">
                  <el-table-column prop="productCategory" label="产品名称" />
                  <el-table-column prop="specificationModel" label="规格型号" />
                  <el-table-column prop="unit" label="单位" />
                  <el-table-column prop="quantity" label="数量" />
                  <el-table-column prop="taxInclusiveUnitPrice" label="含税单价">
                <el-table :data="currentPurchase.productData || []"
                          border
                          style="width: 100%">
                  <el-table-column prop="productCategory"
                                   label="产品名称" />
                  <el-table-column prop="specificationModel"
                                   label="规格型号" />
                  <el-table-column prop="unit"
                                   label="单位" />
                  <el-table-column prop="quantity"
                                   label="数量" />
                  <el-table-column prop="taxInclusiveUnitPrice"
                                   label="含税单价">
                    <template #default="scope">¥{{ Number(scope.row.taxInclusiveUnitPrice ?? 0).toFixed(2) }}</template>
                  </el-table-column>
                  <el-table-column prop="taxInclusiveTotalPrice" label="含税总价">
                  <el-table-column prop="taxInclusiveTotalPrice"
                                   label="含税总价">
                    <template #default="scope">¥{{ Number(scope.row.taxInclusiveTotalPrice ?? 0).toFixed(2) }}</template>
                  </el-table-column>
                </el-table>
@@ -134,22 +166,101 @@
          </template>
        </el-skeleton>
      </div>
      <el-form :model="{ activities }" ref="formRef" label-position="top">
        <el-steps :active="getActiveStep()" finish-status="success" process-status="process" align-center direction="vertical">
          <el-step
            v-for="(activity, index) in activities"
      <!-- 发货审批:展示发货详情 -->
      <div v-if="isDeliveryApproval"
           style="margin: 10px 0 18px;">
        <el-divider content-position="left">发货详情</el-divider>
        <el-skeleton :loading="deliveryLoading"
                     animated>
          <template #template>
            <el-skeleton-item variant="h3"
                              style="width: 30%" />
            <el-skeleton-item variant="text"
                              style="width: 100%" />
            <el-skeleton-item variant="text"
                              style="width: 100%" />
          </template>
          <template #default>
            <el-empty v-if="!currentDelivery || !currentDelivery.shippingInfo"
                      description="未查询到对应发货详情" />
            <template v-else>
              <el-descriptions :column="2"
                               border>
                <el-descriptions-item label="销售订单">{{ currentDelivery.shippingInfo.salesContractNo || '--' }}</el-descriptions-item>
                <el-descriptions-item label="发货订单号">{{ currentDelivery.shippingInfo.shippingNo || '--' }}</el-descriptions-item>
                <el-descriptions-item label="客户名称">{{ currentDelivery.shippingInfo.customerName || '--' }}</el-descriptions-item>
                <el-descriptions-item label="发货类型">{{ currentDelivery.shippingInfo.type || '--' }}</el-descriptions-item>
                <el-descriptions-item label="发货日期">{{ currentDelivery.shippingInfo.shippingDate || '--' }}</el-descriptions-item>
                <el-descriptions-item label="审核状态">{{ currentDelivery.shippingInfo.status || '--' }}</el-descriptions-item>
                <el-descriptions-item label="发货车牌号">{{ currentDelivery.shippingInfo.shippingCarNumber || '--' }}</el-descriptions-item>
                <el-descriptions-item label="快递公司">{{ currentDelivery.shippingInfo.expressCompany || '--' }}</el-descriptions-item>
                <el-descriptions-item label="快递单号"
                                      :span="2">{{ currentDelivery.shippingInfo.expressNumber || '--' }}</el-descriptions-item>
              </el-descriptions>
              <div style="margin-top: 20px;">
                <h4>产品明细</h4>
                <el-table :data="deliveryProductList"
                          border
                          size="small"
                          style="width: 100%">
                  <el-table-column prop="batchNo"
                                   label="批号"
                                   show-overflow-tooltip />
                  <el-table-column prop="productName"
                                   label="产品名称"
                                   show-overflow-tooltip />
                  <el-table-column prop="specificationModel"
                                   label="规格型号"
                                   show-overflow-tooltip />
                  <el-table-column prop="deliveryQuantity"
                                   label="发货数量"
                                   align="center" />
                </el-table>
              </div>
              <div v-if="currentDelivery.shippingInfo.storageBlobVOs && currentDelivery.shippingInfo.storageBlobVOs.length"
                   style="margin-top: 20px;">
                <h4>发货图片</h4>
                <ImagePreview :file-list="currentDelivery.shippingInfo.storageBlobVOs" />
              </div>
            </template>
          </template>
        </el-skeleton>
      </div>
      <el-form :model="{ activities }"
               ref="formRef"
               label-position="top">
        <el-steps :active="getActiveStep()"
                  finish-status="success"
                  process-status="process"
                  align-center
                  direction="vertical">
          <el-step v-for="(activity, index) in activities"
            :key="index"
                        finish-status="success"
            :title="getNodeTitle(index, activities.length)"
            :description="activity.approveNodeUser"
            :icon="getNodeIcon(activity, index)"
          >
                   :icon="getNodeIcon(activity, index)">
                        <template #icon>
                            <el-icon v-if="activity.approveNodeStatus === 2" color="red" :size="22"><WarningFilled /></el-icon>
                            <el-icon v-else-if="activity.isShen" color="#1890ff" :size="22"><Edit /></el-icon>
                            <el-icon v-else-if="activity.approveNodeStatus === 1" color="#67C23A" :size="26"><Check /></el-icon>
                            <el-icon v-else color="#C0C4CC" :size="22"><MoreFilled /></el-icon>
              <el-icon v-if="activity.approveNodeStatus === 2"
                       color="red"
                       :size="22">
                <WarningFilled />
              </el-icon>
              <el-icon v-else-if="activity.isShen"
                       color="#1890ff"
                       :size="22">
                <Edit />
              </el-icon>
              <el-icon v-else-if="activity.approveNodeStatus === 1"
                       color="#67C23A"
                       :size="26">
                <Check />
              </el-icon>
              <el-icon v-else
                       color="#C0C4CC"
                       :size="22">
                <MoreFilled />
              </el-icon>
                        </template>
            <template #title>
              <span style="color: #000000">{{ getNodeTitle(index, activities.length) }}</span>
@@ -157,29 +268,36 @@
            <template #description>
              <div class="node-user">
                <div class="avatar-wrapper">
                  <img :src="userStore.avatar" class="user-avatar" alt=""/>
                  <img :src="userStore.avatar"
                       class="user-avatar"
                       alt="" />
                </div>
                <span style="color: #000000">{{ activity.approveNodeUser }}-{{activity.isApproval}}</span>
              </div>
              <div v-if="!activity.isShen" class="node-reason">
              <div v-if="!activity.isShen"
                   class="node-reason">
                <span>审批意见:</span>{{ activity.approveNodeReason }}
              </div>
              <div v-else-if="activity.isShen">
                <el-form-item
                  :prop="'activities.' + index + '.approveNodeReason'"
                  :rules="[{ required: true, message: '审批意见不能为空', trigger: 'blur' }]"
                >
                  <el-input v-model="activity.approveNodeReason" clearable type="textarea" :disabled="operationType === 'view'"></el-input>
                <el-form-item :prop="'activities.' + index + '.approveNodeReason'"
                              :rules="[{ required: true, message: '审批意见不能为空', trigger: 'blur' }]">
                  <el-input v-model="activity.approveNodeReason"
                            clearable
                            type="textarea"
                            :disabled="operationType === 'view'"></el-input>
                </el-form-item>
              </div>
            </template>
          </el-step>
        </el-steps>
      </el-form>
      <template #footer v-if="operationType === 'approval'">
      <template #footer
                v-if="operationType === 'approval'">
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm(2)">不通过</el-button>
          <el-button type="primary" @click="submitForm(1)">通过</el-button>
          <el-button type="primary"
                     @click="submitForm(2)">不通过</el-button>
          <el-button type="primary"
                     @click="submitForm(1)">通过</el-button>
          <el-button @click="closeDia">取消</el-button>
        </div>
      </template>
@@ -188,38 +306,56 @@
</template>
<script setup>
import { computed, getCurrentInstance, nextTick, reactive, ref, toRefs } from "vue";
  import {
    computed,
    getCurrentInstance,
    nextTick,
    reactive,
    ref,
    toRefs,
  } from "vue";
import {
    approveProcessDetails,
    getDept,
    updateApproveNode
    updateApproveNode,
} from "@/api/collaborativeApproval/approvalProcess.js";
import useUserStore from "@/store/modules/user.js";
import { WarningFilled, Edit, Check, MoreFilled } from '@element-plus/icons-vue'
  import {
    WarningFilled,
    Edit,
    Check,
    MoreFilled,
  } from "@element-plus/icons-vue";
import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
import { getPurchaseByCode } from "@/api/procurementManagement/procurementLedger.js";
const emit = defineEmits(['close'])
const { proxy } = getCurrentInstance()
  import { getDeliveryDetailByShippingNo } from "@/api/salesManagement/deliveryLedger.js";
  import ImagePreview from "@/components/AttachmentPreview/image/index.vue";
  const emit = defineEmits(["close"]);
  const { proxy } = getCurrentInstance();
const props = defineProps({
  approveType: {
    type: [Number, String],
    default: 0
  }
})
      default: 0,
    },
  });
const dialogFormVisible = ref(false);
const operationType = ref('')
const activities = ref([])
  const operationType = ref("");
  const activities = ref([]);
const formRef = ref(null);
const userStore = useUserStore()
  const userStore = useUserStore();
const productOptions = ref([]);
const quotationLoading = ref(false)
const currentQuotation = ref({})
const purchaseLoading = ref(false)
const currentPurchase = ref({})
const isQuotationApproval = computed(() => Number(props.approveType) === 6)
const isPurchaseApproval = computed(() => Number(props.approveType) === 5)
  const quotationLoading = ref(false);
  const currentQuotation = ref({});
  const purchaseLoading = ref(false);
  const currentPurchase = ref({});
  const deliveryLoading = ref(false);
  const currentDelivery = ref({});
  const deliveryProductList = ref([]);
  const isQuotationApproval = computed(() => Number(props.approveType) === 6);
  const isPurchaseApproval = computed(() => Number(props.approveType) === 5);
  const isDeliveryApproval = computed(() => Number(props.approveType) === 7);
const data = reactive({
    form: {
@@ -233,8 +369,8 @@
// 节点标题
const getNodeTitle = (index, len) => {
  if (index === len - 1) return '结束';
  return '审批';
    if (index === len - 1) return "结束";
    return "审批";
};
// 获取当前激活步骤
@@ -247,18 +383,18 @@
};
// 步骤icon
const getNodeIcon = (activity, index) => {
  if (activity.approveNodeStatus === 2) return 'el-icon-warning'; // 不通过
  if (activity.isShen) return 'Edit';
  return '';
    if (activity.approveNodeStatus === 2) return "el-icon-warning"; // 不通过
    if (activity.isShen) return "Edit";
    return "";
};
// 打开弹框
const openDialog = (type, row) => {
  operationType.value = type;
  dialogFormVisible.value = true;
  currentQuotation.value = {}
  currentPurchase.value = {}
    form.value = {...row}
    currentQuotation.value = {};
    currentPurchase.value = {};
    form.value = { ...row };
    // 立即清除表单验证状态(因为字段是disabled的,不需要验证)
    nextTick(() => {
        if (formRef.value) {
@@ -269,7 +405,8 @@
    getProductOptions().then(() => {
        // 确保值类型匹配(如果选项已加载)
        if (productOptions.value.length > 0 && form.value.approveDeptId) {
            const matchedOption = productOptions.value.find(opt =>
        const matchedOption = productOptions.value.find(
          opt =>
                opt.deptId == form.value.approveDeptId || 
                String(opt.deptId) === String(form.value.approveDeptId)
            );
@@ -289,13 +426,15 @@
  if (isQuotationApproval.value) {
    const quotationNo = row?.approveReason;
    if (quotationNo) {
      quotationLoading.value = true
      getQuotationList({ quotationNo }).then((res) => {
        const records = res?.data?.records || []
        currentQuotation.value = records[0] || {}
      }).finally(() => {
        quotationLoading.value = false
        quotationLoading.value = true;
        getQuotationList({ quotationNo })
          .then(res => {
            const records = res?.data?.records || [];
            currentQuotation.value = records[0] || {};
      })
          .finally(() => {
            quotationLoading.value = false;
          });
    }
  }
@@ -303,45 +442,132 @@
  if (isPurchaseApproval.value) {
    const purchaseContractNumber = row?.approveReason;
    if (purchaseContractNumber) {
      purchaseLoading.value = true
      getPurchaseByCode({ purchaseContractNumber }).then((res) => {
        currentPurchase.value = res
      }).catch((err) => {
        console.error('查询采购详情失败:', err)
        proxy.$modal.msgError('查询采购详情失败')
      }).finally(() => {
        purchaseLoading.value = false
        purchaseLoading.value = true;
        getPurchaseByCode({ purchaseContractNumber })
          .then(res => {
            currentPurchase.value = res;
      })
          .catch(err => {
            console.error("查询采购详情失败:", err);
            proxy.$modal.msgError("查询采购详情失败");
          })
          .finally(() => {
            purchaseLoading.value = false;
          });
      }
    }
    // 发货审批:用审批事由字段承载的"发货单号"去查发货详情
    if (isDeliveryApproval.value) {
      const deliveryNo = row?.approveReason;
      if (deliveryNo) {
        deliveryLoading.value = true;
        currentDelivery.value = {};
        deliveryProductList.value = [];
        getDeliveryDetailByShippingNo({ shippingNo: deliveryNo })
          .then(res => {
            const detailData = res?.data || res || {};
            currentDelivery.value = detailData;
            deliveryProductList.value =
              detailData.shippingProductDetailDtoList || [];
          })
          .catch(err => {
            console.error("查询发货详情失败:", err);
            proxy.$modal.msgError("查询发货详情失败");
          })
          .finally(() => {
            deliveryLoading.value = false;
          });
    }
  }
  approveProcessDetails(row.approveId).then((res) => {
    activities.value = res.data
    approveProcessDetails(row.approveId).then(res => {
      activities.value = res.data;
    // 增加isApproval字段
    activities.value.forEach(item => {
            if (item.url && item.url.includes('word')) {
                item.urlTem = item.url.replaceAll('word', 'img')
        if (item.url && item.url.includes("word")) {
          item.urlTem = item.url.replaceAll("word", "img");
            } else {
                item.urlTem = item.url
          item.urlTem = item.url;
            }
      if (item.approveNodeStatus === 2) {
        item.isApproval = '已驳回';
          item.isApproval = "已驳回";
      } else if (item.approveNodeStatus === 1) {
        item.isApproval = '已同意';
          item.isApproval = "已同意";
      } else {
        item.isApproval = '未审批';
          item.isApproval = "未审批";
      }
    })
  })
      });
    });
  };
  const getDeliveryProductInfoList = () => {
    const row = currentDelivery.value;
    if (!row) return [];
    const normalizeBatchNoList = value => {
      if (Array.isArray(value)) return value;
      if (typeof value === "string" && value.includes(",")) {
        return value
          .split(",")
          .map(item => item.trim())
          .filter(Boolean);
}
      return value ? [value] : [];
    };
    const detailList = deliveryProductList.value.length
      ? deliveryProductList.value
      : [
          row.batchNoDetailList,
          row.batchNoList,
          row.shippingBatchList,
          row.shippingInfoDetailList,
          row.detailList,
          row.batchDetailList,
        ].find(value => Array.isArray(value) && value.length);
    const batchNoList = normalizeBatchNoList(row.batchNo);
    const toTableRow = (item = {}) => ({
      batchNo:
        typeof item === "string" || typeof item === "number"
          ? item
          : item.batchNo ?? item.batchNumber ?? row.batchNo ?? "--",
      productName: item.productName ?? row.productName ?? "--",
      specificationModel:
        item.specificationModel ?? item.model ?? row.specificationModel ?? "--",
      deliveryQuantity:
        item.deliveryQuantity ??
        item.quantity ??
        item.shippingQuantity ??
        row.deliveryQuantity ??
        row.quantity ??
        "--",
    });
    if (detailList?.length) {
      return detailList.map(toTableRow);
    }
    if (batchNoList.length) {
      return batchNoList.map(batchNo => toTableRow({ batchNo }));
    }
    return [toTableRow()];
  };
  const getApprovalStatusText = status => {
    const statusMap = {
      0: "待审核",
      1: "审核通过",
      2: "审核拒绝",
      3: "审核中",
    };
    return statusMap[status] || "待审核";
  };
const getProductOptions = () => {
    return getDept().then((res) => {
    return getDept().then(res => {
        productOptions.value = res.data;
    });
};
// 提交审批
const submitForm = (status) => {
  const filteredActivities = activities.value.filter(activity => activity.isShen);
  const submitForm = status => {
    const filteredActivities = activities.value.filter(
      activity => activity.isShen
    );
  if (!filteredActivities || filteredActivities.length === 0) {
    proxy.$modal.msgError("未找到待审批的节点");
    return;
@@ -353,7 +579,8 @@
  }
  currentActivity.approveNodeStatus = status;
  // 判断是否为最后一步
  const isLast = activities.value.findIndex(a => a.isShen) === activities.value.length-1;
    const isLast =
      activities.value.findIndex(a => a.isShen) === activities.value.length - 1;
  updateApproveNode({ ...currentActivity, isLast }).then(() => {
    proxy.$modal.msgSuccess("提交成功");
    closeDia();
@@ -363,11 +590,11 @@
const closeDia = () => {
  proxy.resetForm("formRef");
  dialogFormVisible.value = false;
  quotationLoading.value = false
  currentQuotation.value = {}
  purchaseLoading.value = false
  currentPurchase.value = {}
  emit('close')
    quotationLoading.value = false;
    currentQuotation.value = {};
    purchaseLoading.value = false;
    currentPurchase.value = {};
    emit("close");
};
defineExpose({
  openDialog,
@@ -375,7 +602,6 @@
</script>
<style scoped>
.node-user {
  margin: 10px 0;
  font-size: 16px;
src/views/procurementManagement/purchaseReturnOrder/index.vue
@@ -88,10 +88,10 @@
          <el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" width="130">
            <template #default="scope">{{ formatAmount(scope.row.taxInclusiveUnitPrice) }}</template>
          </el-table-column>
          <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" width="130">
          <el-table-column label="退货总价(元)" prop="taxInclusiveTotalPrice" width="130">
            <template #default="scope">{{ formatAmount(scope.row.taxInclusiveTotalPrice) }}</template>
          </el-table-column>
          <el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" width="140">
          <el-table-column label="不退货总价(元)" prop="taxExclusiveTotalPrice" width="140">
            <template #default="scope">{{ formatAmount(scope.row.taxExclusiveTotalPrice) }}</template>
          </el-table-column>
          <el-table-column label="是否质检" prop="isChecked" width="100" align="center">
src/views/productionManagement/processRoute/processRouteItem/index.vue
@@ -111,6 +111,13 @@
      <el-table-column label="单位"
                       prop="unit"
                       width="100" />
      <el-table-column label="计费类型"
                       prop="type"
                       width="100">
        <template #default="scope">
          {{scope.row.type==0 ? "计时" : "计件"}}
        </template>
      </el-table-column>
      <el-table-column label="是否质检"
                       prop="isQuality"
                       width="100">
@@ -181,12 +188,16 @@
                  {{ item.model }}
                  <!-- <span v-if="item.unit" class="product-unit">{{ item.unit }}</span> -->
                </div>
                <el-tag class="product-tag"
                        :type="item.type == 1 ? 'primary' : 'success'"
                        style="margin-left: 8px;">{{ item.type==0?'计时':'计件' }}</el-tag>
                <el-tag type="primary"
                        class="product-tag"
                        style="margin-left: 8px;"
                        v-if="item.isQuality">质检</el-tag>
                <el-tag type="primary"
                        class="product-tag"
                        :style="item.isQuality?'margin-left:8px':''"
                        style="margin-left: 8px;"
                        v-if="item.isProduction">生产</el-tag>
              </div>
              <div v-else
@@ -424,6 +435,13 @@
                      v-else>
          <span>{{ form.unit }}</span>
        </el-form-item>
        <el-form-item label="计费类型"
                      prop="type">
          <el-radio-group v-model="form.type">
            <el-radio :label="0">计时</el-radio>
            <el-radio :label="1">计件</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="是否质检"
                      prop="isQuality">
          <el-switch v-model="form.isQuality"
@@ -558,6 +576,7 @@
    model: "",
    unit: "",
    isQuality: false,
    type: 0,
    isProduction: false,
  });
@@ -687,6 +706,7 @@
      model: row.model || "",
      unit: row.unit || "",
      isQuality: row.isQuality,
      type: row.type || 0,
      isProduction: row.isProduction,
    };
    dialogVisible.value = true;
@@ -758,6 +778,7 @@
                operationName: getProcessName(form.value.technologyOperationId),
                productModelId: form.value.productModelId,
                isQuality: form.value.isQuality,
                type: form.value.type,
                isProduction: form.value.isProduction,
                dragSort,
              })
@@ -766,6 +787,7 @@
                technologyOperationId: form.value.technologyOperationId,
                productModelId: form.value.productModelId,
                isQuality: form.value.isQuality,
                type: form.value.type,
                isProduction: form.value.isProduction,
                dragSort,
              });
@@ -793,6 +815,7 @@
                operationName: getProcessName(form.value.technologyOperationId),
                productModelId: form.value.productModelId,
                isQuality: form.value.isQuality,
                type: form.value.type,
                isProduction: form.value.isProduction,
              })
            : addOrUpdateProcessRouteItem1({
@@ -801,6 +824,7 @@
                productModelId: form.value.productModelId,
                id: form.value.id,
                isQuality: form.value.isQuality,
                type: form.value.type,
                isProduction: form.value.isProduction,
              });
@@ -832,6 +856,7 @@
      model: "",
      unit: "",
      isQuality: false,
      type: 0,
      isProduction: false,
    };
    formRef.value?.resetFields();
@@ -1068,6 +1093,7 @@
    processOptions.value.forEach(item => {
      if (item.id == value) {
        form.value.isQuality = item.isQuality;
        form.value.type = item.type || 0;
        form.value.isProduction = item.isProduction;
      }
    });
src/views/productionManagement/productionCosting/index.vue
@@ -125,6 +125,11 @@
      minWidth: 100,
    },
    {
      label: "工时(h)",
      prop: "workHour",
      minWidth: 100,
    },
    {
      label: "生产数量",
      prop: "quantity",
      minWidth: 100,
src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue
@@ -312,12 +312,20 @@
        !item.materialName ||
        (Number(item.pickQty) > 0 &&
          (!item.batchNo || item.batchNo.length === 0)) ||
        (item.batchNo && item.batchNo.length > 0 && Number(item.pickQty) <= 0) ||
        item.demandedQuantity === null ||
        item.demandedQuantity === undefined ||
        item.pickQty === null ||
        item.pickQty === undefined
    );
    if (invalidRow) {
      if (
        invalidRow.batchNo &&
        invalidRow.batchNo.length > 0 &&
        Number(invalidRow.pickQty) <= 0
      ) {
        return { valid: false, message: "选择了批号时,领用数量必须大于零" };
      }
      return { valid: false, message: "请完善工序、原料、批号和数量后再保存" };
    }
    return { valid: true, message: "" };
src/views/productionManagement/productionOrder/index.vue
@@ -810,9 +810,9 @@
    })
      .then(() => {
        proxy.download(
          "/productOrder/export",
          "/productionOrder/export",
          { ...searchForm.value },
          "生产订单.xlsx"
          "生产订单数据.xlsx"
        );
      })
      .catch(() => {
src/views/productionManagement/productionReporting/index.vue
@@ -187,6 +187,11 @@
      width: 120,
    },
    {
      label: "工时(h)",
      width: 100,
      prop: "workHour",
    },
    {
      label: "工序",
      prop: "process",
      width: 120,
src/views/productionManagement/productionTraceability/index.vue
@@ -78,11 +78,17 @@
                  {{ row.workOrder.model || '-' }}
                </template>
              </el-table-column>
              <el-table-column label="工序"
                               prop="workOrder.operationName"
                               align="center" />
              <el-table-column prop="workOrder.planQuantity"
                               label="需求数量"
                               align="center" />
              <el-table-column prop="workOrder.completeQuantity"
                               label="完成数量"
                               align="center" />
              <el-table-column prop="workOrder.scrapQty"
                               label="报废数量"
                               align="center" />
              <el-table-column prop="workOrder.completionStatus"
                               label="完成进度"
@@ -152,6 +158,15 @@
                {{ parseTime(row.createTime) }}
              </template>
            </el-table-column>
            <el-table-column label="工时(h)"
                             prop="workHour"
                             align="center" />
            <el-table-column label="产出数量"
                             prop="quantity"
                             align="center" />
            <el-table-column label="报废数量"
                             prop="scrapQty"
                             align="center" />
            <el-table-column label="操作"
                             align="center"
                             width="200">
@@ -385,6 +400,7 @@
      workOrder: row.workOrder || {},
      reports: (row.reportList || []).map(r => ({
        ...r.reportMain,
        ...(r.reportOutputList[0] || {}),
        productionOperationParamList: r.reportParamList || [],
      })),
    };
src/views/productionManagement/workOrderManagement/index.vue
@@ -161,6 +161,17 @@
                       :value="user.userId" />
          </el-select>
        </el-form-item>
        <!-- 工时 -->
        <el-form-item label="工时"
                      v-if="currentReportRowData?.type == 0"
                      prop="workHour">
          <el-input v-model.number="reportForm.workHour"
                    type="number"
                    min="0"
                    style="width: 280px"
                    placeholder="请输入工时" /><span style="margin-left:10px"
                class="param-unit">h</span>
        </el-form-item>
        <div v-if="params.length > 0"
             class="param-grid"
             v-loading="paramLoading">
@@ -259,6 +270,7 @@
    addProductMain,
    downProductWorkOrder,
  } from "@/api/productionManagement/workOrder.js";
  import { listMaterialPickingDetail } from "@/api/productionManagement/productionOrder.js";
  import { findProcessParamListOrder } from "@/api/productionManagement/productProcessRoute.js";
  import { getUserProfile, userListNoPageByTenantId } from "@/api/system/user.js";
  import { getDicts } from "@/api/system/dict/data";
@@ -418,6 +430,7 @@
    productMainId: null,
    productionOrderRoutingOperationId: "",
    productionOrderId: "",
    workHour: 0,
    paramGroups: {},
  });
@@ -644,7 +657,21 @@
    fileDialogVisible.value = true;
  };
  const showReportDialog = row => {
  const showReportDialog = async row => {
    if (row.productionOrderId) {
      try {
        const res = await listMaterialPickingDetail(row.productionOrderId);
        const records = Array.isArray(res.data)
          ? res.data
          : res.data?.records || [];
        if (res.code === 200 && records.length === 0) {
          proxy.$modal.msgError("未领料无法报工");
          return;
        }
      } catch (error) {
        console.error("查询领料详情失败:", error);
      }
    }
    currentReportRowData.value = row;
    reportForm.planQuantity = row.planQuantity;
    reportForm.quantity =
@@ -658,6 +685,11 @@
    reportForm.productionOrderRoutingOperationId =
      row.productionOrderRoutingOperationId;
    reportForm.productionOrderId = row.productionOrderId;
    if (row.type == 0) {
      reportForm.workHour = row.workHour || 0;
    } else {
      reportForm.workHour = 0;
    }
    nextTick(() => {
      reportFormRef.value?.clearValidate();
      if (row.productionOrderRoutingOperationId && row.productionOrderId) {
@@ -757,6 +789,7 @@
        productionOrderRoutingOperationId:
          reportForm.productionOrderRoutingOperationId,
        productionOrderId: reportForm.productionOrderId,
        workHour: reportForm.workHour,
        productionOperationParamList: productionOperationParamList,
      };
src/views/productionPlan/productionPlan/index.vue
@@ -13,6 +13,14 @@
                    style="width: 160px;"
                    @keyup.enter="handleQuery" />
        </el-form-item>
        <el-form-item label="销售合同号:"
                      prop="salesContractNo">
          <el-input v-model="searchForm.salesContractNo"
                    placeholder="请输入"
                    clearable
                    style="width: 160px;"
                    @keyup.enter="handleQuery" />
        </el-form-item>
        <el-form-item label="需求日期范围:"
                      prop="dateRange">
          <el-date-picker v-model="searchForm.dateRange"
@@ -589,6 +597,7 @@
  const data = reactive({
    searchForm: {
      mpsNo: "",
      salesContractNo: "",
      productName: "",
      model: "",
      status: "",
@@ -617,6 +626,7 @@
    }
    Object.assign(searchForm.value, {
      mpsNo: "",
      salesContractNo: "",
      productName: "",
      model: "",
      status: "",
src/views/salesManagement/deliveryLedger/index.vue
@@ -56,7 +56,7 @@
                link
                type="primary"
                :disabled="!isApproved(scope.row.status)"
                @click="openForm('edit', scope.row)">补充发货信息
                @click="openForm('edit', scope.row)">发货
            </el-button>
            <el-button
                link
@@ -319,9 +319,9 @@
// 打开弹框
const openForm = async (type, row) => {
  // 补充发货信息:仅“审核通过”允许编辑
  // 发货:仅“审核通过”允许编辑
  if (type === 'edit' && row && !isApproved(row.status)) {
    proxy.$modal.msgWarning("只有审核通过的数据才可以补充发货信息");
    proxy.$modal.msgWarning("只有审核通过的数据才可以发货");
    return;
  }
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
@@ -640,12 +638,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 +758,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"
@@ -908,6 +906,12 @@
              </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">
@@ -921,7 +925,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">
@@ -989,7 +993,9 @@
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();
@@ -1112,12 +1118,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 +1147,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,13 +1182,15 @@
      ? 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,
  }));
@@ -2145,8 +2170,10 @@
                                                              <tbody>
                                                                ${
        item.products &&
        item.products
            .length > 0
                                                                              item
                                                                                .products
                                                                                .length >
                                                                                0
            ? item.products
                .map(
                    product => `
@@ -2178,7 +2205,9 @@
                                                                    </tr>
                                                                  `
                )
                .join("")
                                                                                    .join(
                                                                                      ""
                                                                                    )
            : '<tr><td colspan="6" style="text-align: center; color: #999;">暂无产品数据</td></tr>'
    }
                                                              </tbody>
@@ -2568,14 +2597,14 @@
};
// 打开附件弹窗
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 => {
@@ -2612,16 +2641,23 @@
          (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,