gongchunyi
2026-06-22 492802e4fc1b371ba21a2a490c8dcd67d7c8b29c
src/views/salesManagement/salesLedger/index.vue
@@ -1,362 +1,1028 @@
<template>
  <div class="app-container">
    <div class="search_form">
      <el-form :model="searchForm"
               :inline="true">
        <el-form-item label="客户名称:">
          <el-select v-model="searchForm.customerId"
                     filterable
                     placeholder="请选择客户名称"
                     clearable
                     style="width: 220px"
                     @change="handleQuery">
            <el-option v-for="item in customerOption"
                       :key="item.id"
                       :label="item.customerName"
                       :value="item.id">
              {{ item.customerName + "——" + item.taxpayerIdentificationNumber }}
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="销售合同号:">
          <el-input v-model="searchForm.salesContractNo"
                    placeholder="请输入"
                    clearable
                    prefix-icon="Search"
                    @change="handleQuery" />
        </el-form-item>
        <el-form-item label="项目名称:">
          <el-input v-model="searchForm.projectName"
                    placeholder="请输入"
                    clearable
                    prefix-icon="Search"
                    @change="handleQuery" />
        </el-form-item>
        <el-form-item label="产品宽(mm):">
          <el-input v-model="searchForm.width"
                    placeholder="请输入"
                    clearable
                    prefix-icon="Search"
                    @change="handleQuery" />
        </el-form-item>
        <el-form-item label="产品高(mm):">
          <el-input v-model="searchForm.height"
                    placeholder="请输入"
                    clearable
                    prefix-icon="Search"
                    @change="handleQuery" />
        </el-form-item>
        <el-form-item label="录入日期:">
          <el-date-picker v-model="searchForm.entryDate"
                          value-format="YYYY-MM-DD"
                          format="YYYY-MM-DD"
                          type="daterange"
                          placeholder="请选择"
    <template v-if="isFormPageMode">
      <div class="sales-ledger-page-header">
        <div class="sales-ledger-page-header-content">
          <div class="sales-ledger-page-title">{{ pageFormTitle }}</div>
          <div class="sales-ledger-page-subtitle">{{ pageFormSubtitle }}</div>
        </div>
        <el-button class="sales-ledger-page-back"
                   @click="exitFormPage()">返回台账</el-button>
      </div>
      <div class="sales-ledger-page-form">
        <el-form :model="form"
                 label-width="140px"
                 label-position="top"
                 :rules="rules"
                 @keydown.capture="handleTabScrollFollow"
                 ref="formRef">
          <el-row v-if="operationType === 'add'"
                  style="margin-bottom: 10px;">
            <el-col :span="24"
                    style="text-align: right;">
              <el-button type="primary"
                         plain
                         @click="openQuotationDialog">
                从销售报价导入
              </el-button>
            </el-col>
          </el-row>
          <el-row :gutter="30">
            <el-col :span="12">
              <el-form-item label="销售合同号:"
                            prop="salesContractNo">
                <el-input v-model="form.salesContractNo"
                          placeholder="自动生成"
                          clearable
                          @change="changeDaterange" />
        </el-form-item>
        <el-form-item label="发货状态:">
          <el-select v-model="searchForm.deliveryStatus"
                     placeholder="请选择"
                     clearable
                     style="width: 140px">
            <el-option label="未发货"
                       :value="1" />
            <el-option label="审批中"
                       :value="2" />
            <el-option label="审批失败"
                       :value="3" />
            <el-option label="已发货"
                       :value="4" />
          </el-select>
        </el-form-item>
        <el-form-item label="入库状态:">
          <el-select v-model="searchForm.stockStatus"
                     placeholder="请选择"
                     clearable
                     style="width: 140px">
            <el-option label="未入库"
                       :value="0" />
            <el-option label="部分入库"
                       :value="1" />
            <el-option label="已入库"
                       :value="2" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary"
                     @click="handleQuery"> 搜索 </el-button>
        </el-form-item>
                          disabled />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="业务员:"
                            prop="salesman">
                <el-select v-model="form.salesman"
                           placeholder="请选择"
                           clearable
                           :disabled="isReviewedEdit">
                  <el-option v-for="item in userList"
                             :key="item.nickName"
                             :label="item.nickName"
                             :value="item.nickName" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="30">
            <el-col :span="12">
              <el-form-item label="客户名称:"
                            prop="customerId">
                <el-select v-model="form.customerId"
                           filterable
                           placeholder="请选择"
                           clearable
                           :disabled="isReviewedEdit">
                  <el-option v-for="item in customerOption"
                             :key="item.id"
                             :label="item.customerName"
                             :value="item.id">
                    {{ item.customerName + (item.taxpayerIdentificationNumber ? "——" + item.taxpayerIdentificationNumber : "") }}
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="项目名称:"
                            prop="projectName">
                <el-input v-model="form.projectName"
                          placeholder="请输入"
                          clearable
                          :disabled="isReviewedEdit" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="30">
            <el-col :span="12">
              <el-form-item label="签订日期:"
                            prop="executionDate">
                <el-date-picker style="width: 100%"
                                v-model="form.executionDate"
                                value-format="YYYY-MM-DD"
                                format="YYYY-MM-DD"
                                type="date"
                                placeholder="请选择"
                                clearable
                                :disabled="isReviewedEdit" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="交货日期:"
                            prop="deliveryDate">
                <el-date-picker style="width: 100%"
                                v-model="form.deliveryDate"
                                value-format="YYYY-MM-DD"
                                format="YYYY-MM-DD"
                                type="date"
                                placeholder="请选择"
                                clearable
                                :disabled="isReviewedEdit" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="30">
            <el-col :span="12">
              <el-form-item label="录入人:"
                            prop="entryPerson">
                <el-select v-model="form.entryPerson"
                           filterable
                           default-first-option
                           :reserve-keyword="false"
                           placeholder="请选择"
                           clearable
                           @change="changs"
                           :disabled="isReviewedEdit">
                  <el-option v-for="item in userList"
                             :key="item.userId"
                             :label="item.nickName"
                             :value="item.userId" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="录入日期:"
                            prop="entryDate">
                <el-date-picker style="width: 100%"
                                v-model="form.entryDate"
                                value-format="YYYY-MM-DD"
                                format="YYYY-MM-DD"
                                type="date"
                                placeholder="请选择"
                                clearable
                                :disabled="isReviewedEdit" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-form-item label="产品信息:"
                          prop="entryDate">
              <el-button plain
                         type="danger"
                         :disabled="isReviewedEdit"
                         @click="deleteProduct">删除</el-button>
              <el-button plain
                         type="primary"
                         :disabled="isReviewedEdit"
                         @click="pinSelectedProductRow">固定</el-button>
            </el-form-item>
          </el-row>
          <el-table :data="productData"
                    border
                    class="compact-product-table"
                    @selection-change="productSelected"
                    show-summary
                    :summary-method="summarizeProductTable">
            <el-table-column align="center"
                             type="selection"
                             width="55"
                             :selectable="(row) => !isProductShipped(row)" />
            <el-table-column align="center"
                             label="序号"
                             type="index"
                             width="60" />
            <el-table-column label="产品大类"
                             prop="productCategory"
                             min-width="120">
              <template #default="scope">
                <el-tree-select v-if="scope.row.__editing"
                                v-model="scope.row.__productCategoryId"
                                placeholder="请选择"
                                clearable
                                filterable
                                check-strictly
                                :data="productOptions"
                                :render-after-expand="false"
                                style="width: 100%"
                                :filter-node-method="filterProductCategoryNode"
                                @change="(val) => handleInlineProductCategoryChange(scope.row, val)"
                                :disabled="isReviewedEdit" />
                <span v-else>{{ scope.row.productCategory ?? "" }}</span>
              </template>
            </el-table-column>
            <el-table-column label="规格型号"
                             prop="specificationModel"
                             min-width="140">
              <template #default="scope">
                <el-select v-if="scope.row.__editing"
                           v-model="scope.row.productModelId"
                           placeholder="请选择"
                           clearable
                           filterable
                           style="width: 100%"
                           @change="(val) => handleInlineProductModelChange(scope.row, val)"
                           :disabled="isReviewedEdit">
                  <el-option v-for="item in modelOptions"
                             :key="item.id"
                             :label="item.model"
                             :value="item.id" />
                </el-select>
                <span v-else>{{ scope.row.specificationModel ?? "" }}</span>
              </template>
            </el-table-column>
            <el-table-column label="厚度(mm)"
                             prop="thickness"
                             min-width="95">
              <template #default="scope">
                <el-input-number :controls="false" v-if="scope.row.__editing"
                                 v-model="scope.row.thickness"
                                 :min="0"
                                 :step="1"
                                 :precision="2"
                                 style="width: 100%"
                                 placeholder="请输入"
                                 clearable
                                 :disabled="isReviewedEdit" />
                <span v-else>{{ scope.row.thickness ?? "" }}</span>
              </template>
            </el-table-column>
            <el-table-column label="楼层编号"
                             prop="floorCode"
                             min-width="120"
                             show-overflow-tooltip>
              <template #default="scope">
                <el-input v-if="scope.row.__editing"
                          v-model="scope.row.floorCode"
                          placeholder="请输入"
                          clearable
                          style="width: 100%"
                          :disabled="isReviewedEdit" />
                <span v-else>{{ scope.row.floorCode ?? "" }}</span>
              </template>
            </el-table-column>
            <el-table-column label="含税单价(元)"
                             prop="taxInclusiveUnitPrice"
                             min-width="85">
              <template #default="scope">
                <el-input-number v-if="scope.row.__editing"
                                 :controls="false"
                                 :step="0.01"
                                 :min="0"
                                 :precision="2"
                                 style="width: 100%"
                                 v-model="scope.row.taxInclusiveUnitPrice"
                                 placeholder="请输入"
                                 clearable
                                 @change="() => handleInlineUnitPriceChange(scope.row)"
                                 @input="() => handleInlineUnitPriceChange(scope.row)" />
                <span v-else>{{ formattedNumber(null, null, scope.row.taxInclusiveUnitPrice) }}</span>
              </template>
            </el-table-column>
            <el-table-column label="宽(mm)"
                             prop="width"
                             min-width="85">
              <template #default="scope">
                <el-input-number v-if="scope.row.__editing"
                                 :controls="false"
                                 v-model="scope.row.width"
                                 :min="0"
                                 :step="1"
                                 :precision="2"
                                 style="width:100%"
                                 placeholder="请输入"
                                 clearable
                                 @change="() => handleInlineSizeChange(scope.row)"
                                 @input="() => handleInlineSizeChange(scope.row)"
                                 :disabled="isReviewedEdit" />
                <span v-else>{{ scope.row.width ?? "" }}</span>
              </template>
            </el-table-column>
            <el-table-column label="高(mm)"
                             prop="height"
                             min-width="85">
              <template #default="scope">
                <el-input-number v-if="scope.row.__editing"
                                 :controls="false"
                                 v-model="scope.row.height"
                                 :min="0"
                                 :step="1"
                                 :precision="2"
                                 style="width: 100%"
                                 placeholder="请输入"
                                 clearable
                                 @change="() => handleInlineSizeChange(scope.row)"
                                 @input="() => handleInlineSizeChange(scope.row)"
                                 :disabled="isReviewedEdit" />
                <span v-else>{{ scope.row.height ?? "" }}</span>
              </template>
            </el-table-column>
            <el-table-column label="数量"
                             prop="quantity"
                             min-width="85">
              <template #default="scope">
                <el-input-number :controls="false" v-if="scope.row.__editing"
                                 v-model="scope.row.quantity"
                                 :step="1"
                                 :min="0"
                                 :precision="0"
                                 style="width: 100%"
                                 placeholder="请输入"
                                 clearable
                                 @change="() => handleInlineQuantityChange(scope.row)"
                                 @input="() => handleInlineQuantityChange(scope.row)"
                                 :disabled="isReviewedEdit" />
                <span v-else>{{ scope.row.quantity ?? "" }}</span>
              </template>
            </el-table-column>
            <el-table-column label="结算单片面积(㎡)"
                             prop="settlePieceArea"
                             min-width="120">
              <template #default="scope">
                <el-input-number :controls="false" v-if="scope.row.__editing"
                                 v-model="scope.row.settlePieceArea"
                                 :min="0"
                                 :step="1"
                                 :precision="4"
                                 style="width: 100%"
                                 placeholder="请输入"
                                 clearable
                                 @change="() => handleInlineSettleAreaChange(scope.row)"
                                 :disabled="isReviewedEdit" />
                <span v-else>{{ scope.row.settlePieceArea ? Number(scope.row.settlePieceArea).toFixed(4) : "" }}</span>
              </template>
            </el-table-column>
            <el-table-column label="面积(m²)"
                             prop="actualTotalArea"
                             min-width="110">
              <template #default="scope">
                <el-input-number :controls="false" v-if="scope.row.__editing"
                                 v-model="scope.row.actualTotalArea"
                                 :min="0"
                                 :step="1"
                                 :precision="4"
                                 style="width: 100%"
                                 placeholder="自动计算"
                                 :disabled="isReviewedEdit" />
                <span v-else>{{ scope.row.actualTotalArea ? Number(scope.row.actualTotalArea).toFixed(4) : "" }}</span>
              </template>
            </el-table-column>
            <el-table-column label="税率(%)"
                             prop="taxRate"
                             min-width="80">
              <template #default="scope">
                <el-select v-if="scope.row.__editing"
                           v-model="scope.row.taxRate"
                           placeholder="请选择"
                           clearable
                           style="width: 100%"
                           @change="() => handleInlineTaxRateChange(scope.row)"
                           :disabled="isReviewedEdit">
                  <el-option label="1"
                             value="1" />
                  <el-option label="3"
                             value="3" />
                  <el-option label="6"
                             value="6" />
                  <el-option label="9"
                             value="9" />
                  <el-option label="13"
                             value="13" />
                </el-select>
                <span v-else>{{ scope.row.taxRate ?? "" }}</span>
              </template>
            </el-table-column>
            <el-table-column label="含税总价(元)"
                             prop="taxInclusiveTotalPrice"
                             :formatter="formattedNumber"
                             min-width="100" />
            <el-table-column label="不含税总价(元)"
                             prop="taxExclusiveTotalPrice"
                             :formatter="formattedNumber"
                             min-width="100" />
            <el-table-column label="加工要求"
                             prop="processRequirement"
                             min-width="100"
                             show-overflow-tooltip>
              <template #default="scope">
                <el-input v-if="scope.row.__editing"
                          v-model="scope.row.processRequirement"
                          placeholder="请输入"
                          clearable
                          style="width: 100%"
                          :disabled="isReviewedEdit" />
                <span v-else>{{ scope.row.processRequirement ?? "" }}</span>
              </template>
            </el-table-column>
            <el-table-column label="发票类型"
                             prop="invoiceType"
                             min-width="90">
              <template #default="scope">
                <el-select v-if="scope.row.__editing"
                           v-model="scope.row.invoiceType"
                           placeholder="请选择"
                           clearable
                           style="width: 100%"
                           :disabled="isReviewedEdit">
                  <el-option label="增普票"
                             value="增普票" />
                  <el-option label="增专票"
                             value="增专票" />
                </el-select>
                <span v-else>{{ scope.row.invoiceType ?? "" }}</span>
              </template>
            </el-table-column>
            <el-table-column label="备注"
                             prop="remark"
                             min-width="100"
                             show-overflow-tooltip>
              <template #default="scope">
                <el-input v-if="scope.row.__editing"
                          v-model="scope.row.remark"
                          placeholder="请输入"
                          clearable
                          style="width: 100%"
                          :disabled="isReviewedEdit" />
                <span v-else>{{ scope.row.remark ?? "" }}</span>
              </template>
            </el-table-column>
            <el-table-column label="重箱"
                             prop="heavyBox"
                             min-width="80">
              <template #default="scope">
                <el-input v-if="scope.row.__editing"
                          v-model="scope.row.heavyBox"
                          placeholder="请输入"
                          clearable
                          style="width: 100%"
                          :disabled="isReviewedEdit" />
                <span v-else>{{ scope.row.heavyBox ?? "" }}</span>
              </template>
            </el-table-column>
            <el-table-column fixed="right"
                             label="操作"
                             min-width="150"
                             align="center">
              <template #default="scope">
                <template v-if="scope.row.__editing">
                  <el-button link
                             type="primary"
                             size="small"
                             @click="saveProductInline(scope.row, scope.$index)">保存</el-button>
                  <el-button link
                             type="danger"
                             size="small"
                             @click="cancelProductInline(scope.row, scope.$index)">取消</el-button>
                  <el-popover :width="560"
                              trigger="click"
                              :hide-after="0"
                              :visible="scope.row.__otherAmountPopoverVisible"
                              @update:visible="(val) => handleOtherAmountPopoverVisibleChange(scope.row, val)">
                    <template #reference>
                      <el-button link
                                 type="primary"
                                 size="small"
                                 @click="openOtherAmountInline(scope.row)">
                        额外加工({{ (scope.row.salesProductProcessList || []).length || 0 }})
                      </el-button>
                    </template>
                    <div style="display:flex; align-items:center; justify-content:space-between; gap: 10px; margin-bottom: 8px;">
                      <div style="font-weight: 600; color:#303133;">
                        额外加工
                      </div>
                      <el-button type="primary"
                                 plain
                                 size="small"
                                 :disabled="isReviewedEdit"
                                 @click="startAddOtherAmountForRow(scope.row)">
                        新增
                      </el-button>
                    </div>
                    <div v-if="scope.row.__inlineOtherAmountAdding"
                         style="display:flex; flex-direction:column; gap: 8px; margin-bottom: 10px;"
                         @click.stop>
                      <el-select v-model="scope.row.__inlineOtherAmountAddId"
                                 filterable
                                 clearable
                                 placeholder="请选择额外加工项目"
                                 style="width: 100%;">
                        <el-option v-for="item in otherAmountSelectOptions"
                                   :key="item.id"
                                   :label="item.processName"
                                   :value="item.id" />
                      </el-select>
                      <div style="display:flex; justify-content:flex-end; gap: 8px;">
                        <el-button size="small"
                                   @click="scope.row.__inlineOtherAmountAdding = false; scope.row.__inlineOtherAmountAddId = null">
                          取消
                        </el-button>
                        <el-button type="primary"
                                   size="small"
                                   :disabled="isReviewedEdit || scope.row.__inlineOtherAmountAddId === null || scope.row.__inlineOtherAmountAddId === undefined || scope.row.__inlineOtherAmountAddId === ''"
                                   @click="confirmAddOtherAmountForRow(scope.row)">
                          确认添加
                        </el-button>
                      </div>
                    </div>
                    <div v-if="Array.isArray(scope.row.salesProductProcessList) && scope.row.salesProductProcessList.length > 0"
                         style="display:flex; flex-wrap:wrap; gap: 8px;">
                      <div v-for="(item, idx) in scope.row.salesProductProcessList"
                           :key="String(item.id) + '_' + idx"
                           style="display:flex; align-items:center; gap: 8px; flex: 0 0 calc(50% - 4px); max-width: calc(50% - 4px);">
                        <el-tag type="info"
                                style="max-width: 170px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">
                          {{ item.processName }}
                        </el-tag>
                        <el-input-number :controls="false" v-model="item.quantity"
                                         :min="0"
                                         :step="1"
                                         :precision="0"
                                         style="width: 120px;"
                                         placeholder="数量"
                                         :disabled="isReviewedEdit"
                                         @change="handleOtherAmountQuantityChange(scope.row)" />
                        <el-button type="danger"
                                   link
                                   size="small"
                                   :disabled="isReviewedEdit"
                                   @click="removeOtherAmountAtForRow(scope.row, idx)">
                          删除
                        </el-button>
                      </div>
                    </div>
                    <div v-else
                         style="color:#909399; font-size: 13px;">
                      暂无额外加工
                    </div>
                  </el-popover>
                </template>
                <template v-else>
                  <el-button v-if="isReviewedEdit"
                             link
                             type="primary"
                             size="small"
                             :disabled="isProductShipped(scope.row)"
                             @click="editPriceOnly(scope.row)">
                    修改单价
                  </el-button>
                  <template v-if="!isReviewedEdit">
                    <el-button link
                               type="primary"
                               size="small"
                               :disabled="isProductShipped(scope.row)"
                               @click="editProductInline(scope.row, scope.$index)">
                      编辑
                    </el-button>
                    <el-button link
                               type="primary"
                               size="small"
                               :disabled="isProductShipped(scope.row)"
                               @click="copyProductInline(scope.row, scope.$index)">
                      复制
                    </el-button>
                  </template>
                  <el-popover :width="560"
                              trigger="click"
                              :hide-after="0"
                              :visible="scope.row.__otherAmountPopoverVisible"
                              @update:visible="(val) => handleOtherAmountPopoverVisibleChange(scope.row, val)">
                    <template #reference>
                      <el-button link
                                 type="primary"
                                 size="small"
                                 :disabled="isProductShipped(scope.row)"
                                 @click="openOtherAmountInline(scope.row)">
                        额外加工({{ (scope.row.salesProductProcessList || []).length || 0 }})
                      </el-button>
                    </template>
                    <div style="display:flex; align-items:center; justify-content:space-between; gap: 10px; margin-bottom: 8px;">
                      <div style="font-weight: 600; color:#303133;">
                        额外加工
                      </div>
                      <el-button type="primary"
                                 plain
                                 size="small"
                                 :disabled="isProductShipped(scope.row) || isReviewedEdit"
                                 @click="startAddOtherAmountForRow(scope.row)">
                        新增
                      </el-button>
                    </div>
                    <div v-if="scope.row.__inlineOtherAmountAdding"
                         style="display:flex; flex-direction:column; gap: 8px; margin-bottom: 10px;"
                         @click.stop>
                      <el-select v-model="scope.row.__inlineOtherAmountAddId"
                                 filterable
                                 clearable
                                 placeholder="请选择额外加工项目"
                                 style="width: 100%;"
                                 :disabled="isProductShipped(scope.row) || isReviewedEdit">
                        <el-option v-for="item in otherAmountSelectOptions"
                                   :key="item.id"
                                   :label="item.processName"
                                   :value="item.id" />
                      </el-select>
                      <div style="display:flex; justify-content:flex-end; gap: 8px;">
                        <el-button size="small"
                                   :disabled="isProductShipped(scope.row) || isReviewedEdit"
                                   @click="scope.row.__inlineOtherAmountAdding = false; scope.row.__inlineOtherAmountAddId = null">
                          取消
                        </el-button>
                        <el-button type="primary"
                                   size="small"
                                   :disabled="isProductShipped(scope.row) || isReviewedEdit || scope.row.__inlineOtherAmountAddId === null || scope.row.__inlineOtherAmountAddId === undefined || scope.row.__inlineOtherAmountAddId === ''"
                                   @click="confirmAddOtherAmountForRow(scope.row)">
                          确认添加
                        </el-button>
                      </div>
                    </div>
                    <div v-if="Array.isArray(scope.row.salesProductProcessList) && scope.row.salesProductProcessList.length > 0"
                         style="display:flex; flex-wrap:wrap; gap: 8px;">
                      <div v-for="(item, idx) in scope.row.salesProductProcessList"
                           :key="String(item.id) + '_' + idx"
                           style="display:flex; align-items:center; gap: 8px; flex: 0 0 calc(50% - 4px); max-width: calc(50% - 4px);">
                        <el-tag type="info"
                                style="max-width: 170px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">
                          {{ item.processName }}
                        </el-tag>
                        <el-input-number :controls="false" v-model="item.quantity"
                                         :min="0"
                                         :step="1"
                                         :precision="0"
                                         style="width: 120px;"
                                         placeholder="数量"
                                         :disabled="isProductShipped(scope.row) || isReviewedEdit"
                                         @change="handleOtherAmountQuantityChange(scope.row)" />
                        <el-button type="danger"
                                   link
                                   size="small"
                                   :disabled="isProductShipped(scope.row) || isReviewedEdit"
                                   @click="removeOtherAmountAtForRow(scope.row, idx)">
                          删除
                        </el-button>
                      </div>
                    </div>
                    <div v-else
                         style="color:#909399; font-size: 13px;">
                      暂无额外加工
                    </div>
                  </el-popover>
                </template>
              </template>
            </el-table-column>
          </el-table>
          <el-row :gutter="30">
            <el-col :span="24">
              <el-form-item label="备注:"
                            prop="remarks">
                <el-input v-model="form.remarks"
                          placeholder="请输入"
                          clearable
                          type="textarea"
                          :rows="2"
                          :disabled="isReviewedEdit" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="30">
            <el-col :span="24">
              <el-form-item label="客户备注:"
                            prop="customerRemarks">
                <el-input v-model="form.customerRemarks"
                          placeholder="请输入"
                          clearable
                          type="textarea"
                          :rows="2"
                          :disabled="isReviewedEdit" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="30">
            <el-col :span="24">
              <el-form-item label="附件材料:"
                            prop="salesLedgerFiles">
                <el-upload v-model:file-list="fileList"
                           :action="upload.url"
                           multiple
                           ref="fileUpload"
                           auto-upload
                           :headers="upload.headers"
                           :before-upload="handleBeforeUpload"
                           :on-error="handleUploadError"
                           :on-success="handleUploadSuccess"
                           :on-remove="handleRemove">
                  <el-button type="primary">上传</el-button>
                  <template #tip>
                    <div class="el-upload__tip">
                      文件格式支持
                      doc,docx,xls,xlsx,ppt,pptx,pdf,txt,xml,jpg,jpeg,png,gif,bmp,rar,zip,7z
                    </div>
                  </template>
                </el-upload>
              </el-form-item>
            </el-col>
          </el-row>
          <div class="sales-ledger-page-actions">
            <el-button type="primary" @click="submitForm">提交</el-button>
          </div>
        </el-form>
      </div>
    </template>
    <template v-else>
    <div class="sales-ledger-status-bar">
      <button v-for="tab in salesLedgerStatusTabs"
              :key="tab.key"
              type="button"
              class="sales-ledger-status-tab"
              :class="{ 'is-active': activeStatusTab === tab.key }"
              @click="handleStatusTabChange(tab.key)">
        {{ tab.label }}
      </button>
    </div>
    <ReverseAuditHistory v-if="activeStatusTab === 'reverseReviewed'" />
    <div v-else>
    <div class="search_form">
      <el-form :model="searchForm" label-width="110px">
        <el-row :gutter="20">
          <el-col :xs="24" :sm="12" :md="8" :lg="8">
            <el-form-item label="客户名称:">
              <el-select v-model="searchForm.customerId"
                         filterable
                         placeholder="请选择客户名称"
                         clearable
                         style="width: 100%"
                         @change="handleQuery">
                <el-option v-for="item in customerOption"
                           :key="item.id"
                           :label="item.customerName"
                           :value="item.id">
                  {{ item.customerName + "——" + item.taxpayerIdentificationNumber }}
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="8" :lg="8">
            <el-form-item label="销售合同号:">
              <el-input v-model="searchForm.salesContractNo"
                        placeholder="请输入"
                        clearable
                        prefix-icon="Search"
                        style="width: 100%"
                        @change="handleQuery" />
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="8" :lg="8">
            <el-form-item label="项目名称:">
              <el-input v-model="searchForm.projectName"
                        placeholder="请输入"
                        clearable
                        prefix-icon="Search"
                        style="width: 100%"
                        @change="handleQuery" />
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="8" :lg="8">
            <el-form-item label="录入日期:">
              <el-date-picker v-model="searchForm.entryDate"
                              value-format="YYYY-MM-DD"
                              format="YYYY-MM-DD"
                              type="daterange"
                              placeholder="请选择"
                              clearable
                              style="width: 100%"
                              @change="changeDaterange" />
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="8" :lg="8">
            <el-form-item label="产品宽(mm):">
              <el-input v-model="searchForm.width"
                        placeholder="请输入"
                        clearable
                        prefix-icon="Search"
                        style="width: 100%"
                        @input="val => searchForm.width = val.replace(/[^\d.]/g, '')"
                        @change="handleQuery" />
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="8" :lg="8">
            <el-form-item label="产品高(mm):">
              <el-input v-model="searchForm.height"
                        placeholder="请输入"
                        clearable
                        prefix-icon="Search"
                        style="width: 100%"
                        @input="val => searchForm.height = val.replace(/[^\d.]/g, '')"
                        @change="handleQuery" />
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="8" :lg="8">
            <el-form-item label="发货状态:">
              <el-select v-model="searchForm.deliveryStatus"
                         placeholder="请选择"
                         clearable
                         style="width: 100%">
                <el-option label="未发货" :value="1" />
                <el-option label="审批中" :value="2" />
                <el-option label="审批不通过" :value="3" />
                <el-option label="审批通过" :value="4" />
                <el-option label="已发货" :value="5" />
                <el-option label="部分发货" :value="6" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="8" :lg="8">
            <el-form-item label="入库状态:">
              <el-select v-model="searchForm.stockStatus"
                         placeholder="请选择"
                         clearable
                         style="width: 100%">
                <el-option label="未入库" :value="0" />
                <el-option label="部分入库" :value="1" />
                <el-option label="已入库" :value="2" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="12" :md="8" :lg="8">
            <el-form-item label="订单状态:">
              <el-select v-model="searchForm.orderStatus"
                         placeholder="请选择"
                         clearable
                         style="width: 100%">
                <el-option label="进行中" :value="0" />
                <el-option label="已完成" :value="1" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label=" ">
              <div style="width: 100%; text-align: right;">
                <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
              </div>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </div>
    <div class="table_list">
      <div class="actions">
        <div>
      <div class="actions sales-ledger-toolbar">
        <div class="sales-ledger-toolbar-group">
          <OtherAmountMaintenanceButton />
          <ProcessFlowMaintenanceButton />
        </div>
        <ProcessFlowConfigSelectDialog v-model:visible="processFlowSelectDialogVisible"
                                       :default-route-id="processFlowSelectDefaultRouteId"
                                       :default-record-list="processFlowSelectDefaultRecordList"
                                       :bound-route-name="processFlowSelectBoundRouteName"
                                       @confirm="handleProcessFlowSelectConfirm" />
        <el-space wrap>
          <el-button type="primary"
                     @click="handleSalesStock">入库</el-button>
          <el-button type="primary"
                     @click="openForm('add')">新增台账</el-button>
          <el-button type="primary"
                     @click="handleBulkDelivery">发货</el-button>
          <el-button type="primary"
                     plain
                     @click="handleImport">导入</el-button>
          <el-dropdown @command="handleHistoryImportCommand">
        <div class="sales-ledger-toolbar-actions">
          <el-space v-if="activeStatusTab === 'pendingReview'"
                    wrap
                    class="sales-ledger-toolbar-group">
            <el-button type="primary"
                       plain>
              历史迁移<el-icon class="el-icon--right">
                <ArrowDown />
              </el-icon>
            </el-button>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item command="notShipped">未发货</el-dropdown-item>
                <el-dropdown-item command="shipped">已发货</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
          <el-button @click="handleOut">导出</el-button>
          <el-button type="danger"
                     plain
                     @click="handleDelete">删除</el-button>
          <el-dropdown @command="handlePrintCommand">
                       @click="handleAudit"
                       :disabled="isBatchButtonDisabled('audit')">审核</el-button>
            <el-button type="danger"
                       plain
                       @click="handleDelete"
                       :disabled="isBatchButtonDisabled('delete')">删除</el-button>
            <el-button type="primary"
                       plain>
              打印单据<el-icon class="el-icon--right">
                <ArrowDown />
              </el-icon>
            </el-button>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item command="finishedProcessCard">生产流程卡(成品)</el-dropdown-item>
                <el-dropdown-item command="salesOrder">销售订单</el-dropdown-item>
                <el-dropdown-item command="salesDeliveryNote">销售发货单</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
          <el-button type="primary"
                     plain
                     @click="handlePrintLabel">打印标签</el-button>
        </el-space>
                       @click="openForm('add')">新增台账</el-button>
            <el-button type="primary"
                       plain
                       @click="handleImport">导入</el-button>
            <el-button @click="handleOut">导出</el-button>
          </el-space>
          <el-space v-else-if="activeStatusTab === 'reviewed'"
                    wrap
                    class="sales-ledger-toolbar-group">
            <el-button type="primary"
                       @click="handleReverseAudit"
                       :disabled="isBatchButtonDisabled('reverseAudit')">反审</el-button>
            <el-button type="warning"
                       @click="handleMarkCompleted"
                       :disabled="isBatchButtonDisabled('markCompleted')">标记完成</el-button>
            <el-button type="primary"
                       @click="handleSalesStock"
                       :disabled="isBatchButtonDisabled('stock')">入库</el-button>
            <el-button type="primary"
                       @click="handleBulkDelivery"
                       :disabled="isBatchButtonDisabled('delivery')">发货</el-button>
            <el-button @click="handleOut">导出</el-button>
            <el-button @click="handleExportProcessRoute"
                       :disabled="isBatchButtonDisabled('export')">导出工艺路线</el-button>
          </el-space>
          <el-space v-else-if="activeStatusTab === 'stocked'"
                    wrap
                    class="sales-ledger-toolbar-group">
            <el-button type="primary"
                       @click="handleReverseAudit"
                       :disabled="isBatchButtonDisabled('reverseAudit')">反审</el-button>
            <el-button type="warning"
                       @click="handleMarkCompleted"
                       :disabled="isBatchButtonDisabled('markCompleted')">标记完成</el-button>
            <el-button type="primary"
                       @click="handleBulkDelivery"
                       :disabled="isBatchButtonDisabled('delivery')">发货</el-button>
            <el-button @click="handleOut">导出</el-button>
          </el-space>
          <el-space v-else-if="activeStatusTab === 'delivered'"
                    wrap
                    class="sales-ledger-toolbar-group">
            <el-button type="warning"
                       @click="handleMarkCompleted"
                       :disabled="isBatchButtonDisabled('markCompleted')">标记完成</el-button>
            <el-button type="primary"
                       @click="handleReverseAudit"
                       :disabled="isBatchButtonDisabled('reverseAudit')">反审</el-button>
            <el-button @click="handleOut">导出</el-button>
          </el-space>
          <el-space v-else-if="activeStatusTab === 'completed'"
                    wrap
                    class="sales-ledger-toolbar-group">
            <el-button @click="handleOut">导出</el-button>
            <el-button type="primary"
                       plain
                       @click="handlePrintCommand('salesOrder')"
                       :disabled="isBatchButtonDisabled('print')">打印单据</el-button>
            <el-button type="primary"
                       plain
                       @click="handlePrintLabel"
                       :disabled="isBatchButtonDisabled('print')">打印标签</el-button>
          </el-space>
          <el-space v-else-if="activeStatusTab === 'all'"
                    wrap
                    class="sales-ledger-toolbar-group">
            <el-button type="primary"
                       @click="openForm('add')">新增台账</el-button>
            <el-button @click="handleOut">导出</el-button>
          </el-space>
          <el-space wrap class="sales-ledger-toolbar-group sales-ledger-toolbar-group--muted">
            <el-dropdown @command="handleHistoryImportCommand">
              <el-button type="primary"
                         plain>
                历史迁移<el-icon class="el-icon--right">
                  <ArrowDown />
                </el-icon>
              </el-button>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item command="notShipped">未出库</el-dropdown-item>
                  <el-dropdown-item command="shipped">已出库</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </el-space>
          <el-space wrap class="sales-ledger-toolbar-group sales-ledger-toolbar-group--muted">
            <el-dropdown @command="handlePrintCommand">
              <el-button type="primary"
                         plain
                         :disabled="isBatchButtonDisabled('print')">
                打印单据<el-icon class="el-icon--right">
                  <ArrowDown />
                </el-icon>
              </el-button>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item command="finishedProcessCard">生产流程卡(成品)</el-dropdown-item>
                  <el-dropdown-item command="salesOrder">销售订单</el-dropdown-item>
                  <el-dropdown-item command="salesDeliveryNote">销售发货单</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
            <el-button type="primary"
                       plain
                       @click="handlePrintLabel"
                       :disabled="isBatchButtonDisabled('print')">打印标签</el-button>
          </el-space>
        </div>
      </div>
      <el-table :data="tableData"
                border
                v-loading="tableLoading"
                @selection-change="handleSelectionChange"
                :expand-row-keys="expandedRowKeys"
                :row-key="(row) => row.id"
                :row-class-name="tableRowClassName"
                show-summary
                style="width: 100%"
                :summary-method="summarizeMainTable"
                @expand-change="expandChange"
                height="calc(100vh - 18.5em)">
                height="calc(100vh - 23em)"
                :summary-method="summarizeMainTable">
        <el-table-column align="center"
                         type="selection"
                         width="55"
                         fixed="left" />
        <el-table-column type="expand"
                         width="60"
                         fixed="left">
          <template #default="props">
            <el-table :data="props.row.children"
                      border
                      show-summary
                      :summary-method="summarizeChildrenTable">
              <el-table-column align="center"
                               label="序号"
                               type="index" />
              <el-table-column label="楼层编号"
                               prop="floorCode"
                               min-width="100"
                               show-overflow-tooltip />
              <el-table-column label="产品大类"
                               prop="productCategory" />
              <el-table-column label="规格型号"
                               prop="specificationModel" />
              <el-table-column label="厚度"
                               prop="thickness"
                               min-width="90">
                <template #default="scope">
                  {{ scope.row.thickness ?? "" }}
                </template>
              </el-table-column>
              <el-table-column label="宽(mm)"
                               prop="width"
                               min-width="80">
                <template #default="scope">
                  {{ scope.row.width ?? "" }}
                </template>
              </el-table-column>
              <el-table-column label="高(mm)"
                               prop="height"
                               min-width="80">
                <template #default="scope">
                  {{ scope.row.height ?? "" }}
                </template>
              </el-table-column>
              <el-table-column label="周长(cm)"
                               prop="perimeter"
                               min-width="90">
                <template #default="scope">
                  {{ scope.row.perimeter ?? "" }}
                </template>
              </el-table-column>
              <el-table-column label="总面积(m²)"
                               prop="actualTotalArea"
                               min-width="100">
                <template #default="scope">
                  {{ scope.row.actualTotalArea ?? "" }}
                </template>
              </el-table-column>
              <el-table-column label="加工要求"
                               prop="processRequirement"
                               min-width="120"
                               show-overflow-tooltip />
              <el-table-column label="备注"
                               prop="remark"
                               min-width="120"
                               show-overflow-tooltip />
              <el-table-column label="重箱"
                               prop="heavyBox"
                               min-width="80">
                <template #default="scope">
                  {{ scope.row.heavyBox ?? "" }}
                </template>
              </el-table-column>
              <el-table-column label="产品状态"
                               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-else
                          type="danger">不足</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="入库状态"
                               width="100px"
                               align="center">
                <template #default="scope">
                  <el-tag v-if="scope.row.productStockStatus == 1"
                  type="warning">部分入库</el-tag>
                  <el-tag v-else-if="scope.row.productStockStatus == 2"
                          type="success">已入库</el-tag>
                  <el-tag v-else-if="scope.row.productStockStatus == 0"
                          type="info">未入库</el-tag>
                  <el-tag v-else
                          type="danger">未入库</el-tag>
                </template>
              </el-table-column>
              <!-- <el-table-column label="发货状态" width="140" align="center">
                        <template #default="scope">
                           <el-tag :type="getShippingStatusType(scope.row)" size="small">
                              {{ getShippingStatusText(scope.row) }}
                           </el-tag>
                        </template>
                     </el-table-column> -->
              <el-table-column label="快递公司"
                               prop="expressCompany"
                               show-overflow-tooltip />
              <el-table-column label="快递单号"
                               prop="expressNumber"
                               show-overflow-tooltip />
              <el-table-column label="发货车牌"
                               minWidth="100px"
                               align="center">
                <template #default="scope">
                  <div>
                    <el-tag type="success"
                            v-if="scope.row.shippingCarNumber">{{ scope.row.shippingCarNumber }}</el-tag>
                    <el-tag v-else
                            type="info">-</el-tag>
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="发货日期"
                               minWidth="100px"
                               align="center">
                <template #default="scope">
                  <div>
                    <div v-if="scope.row.shippingDate">{{ scope.row.shippingDate }}</div>
                    <el-tag v-else
                            type="info">-</el-tag>
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="数量"
                               prop="quantity" />
              <el-table-column label="税率(%)"
                               prop="taxRate" />
              <el-table-column label="含税单价(元)"
                               prop="taxInclusiveUnitPrice"
                               :formatter="formattedNumber" />
              <el-table-column label="含税总价(元)"
                               prop="taxInclusiveTotalPrice"
                               :formatter="formattedNumber" />
              <el-table-column label="不含税总价(元)"
                               prop="taxExclusiveTotalPrice"
                               :formatter="formattedNumber" />
              <!--操作-->
              <!-- <el-table-column Width="60px" label="操作" align="center">
                <template #default="scope">
                  <el-button
                    link
                    type="primary"
                    :disabled="!canShip(scope.row)"
                    @click="openDeliveryForm(scope.row)">
                    发货
                  </el-button>
                </template>
              </el-table-column> -->
            </el-table>
          </template>
        </el-table-column>
        <el-table-column align="center"
                         label="序号"
                         type="index"
                         width="60" />
        <el-table-column label="销售合同号"
        <el-table-column label="订单号"
                         prop="salesContractNo"
                         width="180"
                         show-overflow-tooltip />
                         min-width="160"
                         show-overflow-tooltip>
          <template #default="scope">
            <el-button link
                       type="primary"
                       @click="openForm('view', scope.row)">{{ scope.row.salesContractNo || "-" }}</el-button>
          </template>
        </el-table-column>
        <el-table-column label="客户名称"
                         prop="customerName"
                         width="300"
                         min-width="200"
                         show-overflow-tooltip />
        <el-table-column label="业务员"
                         prop="salesman"
                         width="100"
                         show-overflow-tooltip />
        <el-table-column label="项目名称"
                         prop="projectName"
                         width="180"
                         min-width="80"
                         show-overflow-tooltip />
        <el-table-column label="合同金额(元)"
                         prop="contractAmount"
                         width="220"
                         min-width="120"
                         show-overflow-tooltip
                         :formatter="formattedNumber" />
        <el-table-column label="面积"
                         prop="productTotalArea"
                         width="120"
                         min-width="80"
                         show-overflow-tooltip />
        <el-table-column label="数量"
                         prop="productTotalQuantity"
                         width="120"
                         min-width="80"
                         show-overflow-tooltip />
        <el-table-column label="发货状态"
                         width="140"
                         min-width="100"
                         align="center">
          <template #default="scope">
            <el-tag v-if="Number(scope.row.deliveryStatus) === 1"
@@ -369,12 +1035,28 @@
                    type="primary">审批通过</el-tag>
            <el-tag v-else-if="Number(scope.row.deliveryStatus) === 5"
                    type="success">已发货</el-tag>
            <el-tag v-else-if="Number(scope.row.deliveryStatus) === 6"
                    type="warning">部分发货</el-tag>
            <el-tag v-else
                    type="info">-</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="审核状态"
                         min-width="90"
                         align="center">
          <template #default="scope">
            <el-tag v-if="Number(scope.row.reviewStatus) === 0"
                    type="warning">待审核</el-tag>
            <el-tag v-else-if="Number(scope.row.reviewStatus) === 1"
                    type="success">已审核</el-tag>
            <el-tag v-else-if="Number(scope.row.reviewStatus) === 2"
                    type="danger">已反审</el-tag>
            <el-tag v-else
                    type="info">待审核</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="入库状态"
                         width="120"
                         min-width="90"
                         align="center">
          <template #default="scope">
            <el-tag v-if="Number(scope.row.stockStatus) === 0"
@@ -383,53 +1065,76 @@
                    type="success">部分入库</el-tag>
            <el-tag v-else-if="Number(scope.row.stockStatus) === 2"
                    type="success">已入库</el-tag>
            <el-tag v-else-if="Number(scope.row.stockStatus) === 3"
                    type="warning">审批中</el-tag>
            <el-tag v-else
                    type="info">-</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="订单状态"
                         min-width="90"
                         align="center">
          <template #default="scope">
            <el-tag v-if="Number(scope.row.orderStatus) === 1"
                    type="success">已完成</el-tag>
            <el-tag v-else
                    type="info">进行中</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="标签打印"
                         min-width="90"
                         align="center">
          <template #default="scope">
            <span>{{ scope.row.labelPrintCount ?? 0 }}</span>
          </template>
        </el-table-column>
        <el-table-column label="单据打印"
                         min-width="90"
                         align="center">
          <template #default="scope">
            <span>{{ scope.row.documentPrintCount ?? 0 }}</span>
          </template>
        </el-table-column>
        <el-table-column label="录入人"
                         prop="entryPersonName"
                         width="100"
                         min-width="80"
                         show-overflow-tooltip />
        <el-table-column label="录入日期"
                         prop="entryDate"
                         width="120"
                         show-overflow-tooltip />
        <el-table-column label="签订日期"
                         prop="executionDate"
                         width="120"
                         min-width="110"
                         show-overflow-tooltip />
        <el-table-column label="交付日期"
                         prop="deliveryDate"
                         width="120"
                         min-width="110"
                         show-overflow-tooltip />
        <el-table-column label="备注"
                         prop="remarks"
                         width="200"
                         min-width="120"
                         show-overflow-tooltip />
        <el-table-column label="客户备注"
                         prop="customerRemarks"
                         width="200"
                         min-width="120"
                         show-overflow-tooltip />
        <el-table-column fixed="right"
                         label="操作"
                         width="280"
                         width="250"
                         align="center">
          <template #default="scope">
            <el-button link
                       type="primary"
                       @click="openForm('edit', scope.row)"
                       :disabled="!scope.row.isEdit">编辑</el-button>
                       :disabled="Number(scope.row.orderStatus) === 1">编辑</el-button>
            <el-button link
                       type="primary"
                       @click="openProcessFlowSelect(scope.row)"
                       :disabled="!scope.row.isEdit">工艺路线</el-button>
                       :disabled="Number(scope.row.reviewStatus) !== 1 || Number(scope.row.orderStatus) === 1">工艺路线</el-button>
            <el-button link
                       type="primary"
                       @click="downLoadFile(scope.row)">附件</el-button>
            <el-button link
                       type="primary"
                       @click="openLedgerQrDialog(scope.row)">二维码</el-button>
                       @click="openLedgerQrDialog(scope.row)"
                       :disabled="Number(scope.row.orderStatus) === 1">二维码</el-button>
          </template>
        </el-table-column>
      </el-table>
@@ -440,10 +1145,38 @@
                  :limit="page.size"
                  @pagination="paginationChange" />
    </div>
    <FormDialog v-model="dialogFormVisible"
                :title="operationType === 'add' ? '新增销售台账页面' : '编辑销售台账页面'"
    </div>
    <!-- 导出工艺路线 弹窗 -->
    <el-dialog title="选择导出时间范围"
               v-model="exportProcessRouteDialogVisible"
               width="450px"
               append-to-body>
      <el-form>
        <el-form-item label="完成时间:">
          <el-date-picker v-model="processRouteExportDateRange"
                          type="datetimerange"
                          range-separator="至"
                          start-placeholder="开始时间"
                          end-placeholder="结束时间"
                          value-format="YYYY-MM-DD HH:mm:ss"
                          format="YYYY-MM-DD HH:mm:ss"
                          clearable
                          style="width: 100%;" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div style="text-align: right">
          <el-button @click="exportProcessRouteDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmExportProcessRoute">确认导出</el-button>
        </div>
      </template>
    </el-dialog>
    </template>
    <FormDialog v-if="!isFormPageMode"
                v-model="dialogFormVisible"
                :title="isCompletedOrder ? '查看销售台账页面(已完成)' : operationType === 'add' ? '新增销售台账页面' : operationType === 'view' ? '查看销售台账页面' : '编辑销售台账页面'"
                :width="'70%'"
                :operation-type="operationType"
                :operation-type="isCompletedOrder || operationType === 'view' ? 'detail' : operationType"
                @close="closeDia"
                @confirm="submitForm"
                @cancel="closeDia">
@@ -481,7 +1214,7 @@
              <el-select v-model="form.salesman"
                         placeholder="请选择"
                         clearable
                         :disabled="operationType === 'view'">
                         :disabled="operationType === 'view' || isReviewedEdit">
                <el-option v-for="item in userList"
                           :key="item.nickName"
                           :label="item.nickName"
@@ -498,7 +1231,7 @@
                         filterable
                         placeholder="请选择"
                         clearable
                         :disabled="operationType === 'view'">
                         :disabled="operationType === 'view' || isReviewedEdit">
                <el-option v-for="item in customerOption"
                           :key="item.id"
                           :label="item.customerName"
@@ -514,7 +1247,7 @@
              <el-input v-model="form.projectName"
                        placeholder="请输入"
                        clearable
                        :disabled="operationType === 'view'" />
                        :disabled="operationType === 'view' || isReviewedEdit" />
            </el-form-item>
          </el-col>
        </el-row>
@@ -529,7 +1262,7 @@
                              type="date"
                              placeholder="请选择"
                              clearable
                              :disabled="operationType === 'view'" />
                              :disabled="operationType === 'view' || isReviewedEdit" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
@@ -541,7 +1274,8 @@
                              format="YYYY-MM-DD"
                              type="date"
                              placeholder="请选择"
                              clearable />
                              clearable
                              :disabled="operationType === 'view' || isReviewedEdit" />
            </el-form-item>
          </el-col>
        </el-row>
@@ -555,7 +1289,8 @@
                         :reserve-keyword="false"
                         placeholder="请选择"
                         clearable
                         @change="changs">
                         @change="changs"
                         :disabled="operationType === 'view' || isReviewedEdit">
                <el-option v-for="item in userList"
                           :key="item.userId"
                           :label="item.nickName"
@@ -572,7 +1307,8 @@
                              format="YYYY-MM-DD"
                              type="date"
                              placeholder="请选择"
                              clearable />
                              clearable
                              :disabled="operationType === 'view' || isReviewedEdit" />
            </el-form-item>
          </el-col>
        </el-row>
@@ -580,22 +1316,23 @@
          <el-form-item label="产品信息:"
                        prop="entryDate">
            <el-button v-if="operationType !== 'view'"
                       type="primary"
                       :disabled="hasEditingProductRow()"
                       @click="addProductInline">
              添加
            </el-button>
            <el-button v-if="operationType !== 'view'"
                       plain
                       type="danger"
                       :disabled="isReviewedEdit"
                       @click="deleteProduct">删除</el-button>
            <el-button v-if="operationType !== 'view'"
                       plain
                       type="primary"
                       :disabled="isReviewedEdit"
                       @click="pinSelectedProductRow">固定</el-button>
          </el-form-item>
        </el-row>
        <el-table :data="productData"
                  border
                  class="compact-product-table"
                  @selection-change="productSelected"
                  show-summary
                  :summary-method="summarizeMainTable">
                  :summary-method="summarizeProductTable">
          <el-table-column align="center"
                           type="selection"
                           width="55"
@@ -607,7 +1344,7 @@
                           width="60" />
          <el-table-column label="产品大类"
                           prop="productCategory"
                           min-width="160">
                           min-width="120">
            <template #default="scope">
              <el-tree-select v-if="scope.row.__editing"
                              v-model="scope.row.__productCategoryId"
@@ -619,13 +1356,14 @@
                              :render-after-expand="false"
                              style="width: 100%"
                              :filter-node-method="filterProductCategoryNode"
                              @change="(val) => handleInlineProductCategoryChange(scope.row, val)" />
                              @change="(val) => handleInlineProductCategoryChange(scope.row, val)"
                              :disabled="isReviewedEdit" />
              <span v-else>{{ scope.row.productCategory ?? "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="规格型号"
                           prop="specificationModel"
                           min-width="200">
                           min-width="140">
            <template #default="scope">
              <el-select v-if="scope.row.__editing"
                         v-model="scope.row.productModelId"
@@ -633,7 +1371,8 @@
                         clearable
                         filterable
                         style="width: 100%"
                         @change="(val) => handleInlineProductModelChange(scope.row, val)">
                         @change="(val) => handleInlineProductModelChange(scope.row, val)"
                         :disabled="isReviewedEdit">
                <el-option v-for="item in modelOptions"
                           :key="item.id"
                           :label="item.model"
@@ -644,111 +1383,39 @@
          </el-table-column>
          <el-table-column label="厚度(mm)"
                           prop="thickness"
                           min-width="160">
                           min-width="95">
            <template #default="scope">
              <el-input-number v-if="scope.row.__editing"
                               controls-position="right"
              <el-input-number :controls="false" v-if="scope.row.__editing"
                               v-model="scope.row.thickness"
                               :min="0"
                               :step="1"
                               :precision="2"
                               style="width: 100%"
                               placeholder="请输入"
                               clearable />
                               clearable
                               :disabled="isReviewedEdit" />
              <span v-else>{{ scope.row.thickness ?? "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="宽(mm)"
                           prop="width"
                           min-width="160">
          <el-table-column label="楼层编号"
                           prop="floorCode"
                           min-width="120"
                           show-overflow-tooltip>
            <template #default="scope">
              <el-input-number v-if="scope.row.__editing"
                               controls-position="right"
                               v-model="scope.row.width"
                               :min="0"
                               :step="1"
                               :precision="2"
                               style="width:100%"
                               placeholder="请输入"
                               clearable
                               @change="() => handleInlineSizeChange(scope.row)"
                               @input="() => handleInlineSizeChange(scope.row)" />
              <span v-else>{{ scope.row.width ?? "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="高(mm)"
                           prop="height"
                           min-width="160">
            <template #default="scope">
              <el-input-number v-if="scope.row.__editing"
                               controls-position="right"
                               v-model="scope.row.height"
                               :min="0"
                               :step="1"
                               :precision="2"
                               style="width: 100%"
                               placeholder="请输入"
                               clearable
                               @change="() => handleInlineSizeChange(scope.row)"
                               @input="() => handleInlineSizeChange(scope.row)" />
              <span v-else>{{ scope.row.height ?? "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="结算单片面积(㎡)"
                           prop="settlePieceArea"
                           min-width="200">
            <template #default="scope">
              <el-input-number v-if="scope.row.__editing"
                               controls-position="right"
                               v-model="scope.row.settlePieceArea"
                               :min="0"
                               :step="1"
                               :precision="4"
                               style="width: 100%"
                               placeholder="请输入"
                               clearable
                               @change="() => handleInlineSettleAreaChange(scope.row)" />
              <span v-else>{{ scope.row.settlePieceArea ? Number(scope.row.settlePieceArea).toFixed(4) : "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="数量"
                           prop="quantity"
                           min-width="150">
            <template #default="scope">
              <el-input-number v-if="scope.row.__editing"
                               controls-position="right"
                               v-model="scope.row.quantity"
                               :step="1"
                               :min="0"
                               :precision="0"
                               style="width: 100%"
                               placeholder="请输入"
                               clearable
                               @change="() => handleInlineQuantityChange(scope.row)"
                               @input="() => handleInlineQuantityChange(scope.row)" />
              <span v-else>{{ scope.row.quantity ?? "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="面积(m²)"
                           prop="actualTotalArea"
                           min-width="200">
            <template #default="scope">
              <el-input-number v-if="scope.row.__editing"
                               controls-position="right"
                               v-model="scope.row.actualTotalArea"
                               :min="0"
                               :step="1"
                               :precision="4"
                               style="width: 100%"
                               placeholder="自动计算" />
              <span v-else>{{ scope.row.actualTotalArea ? Number(scope.row.actualTotalArea).toFixed(4) : "" }}</span>
              <el-input v-if="scope.row.__editing"
                        v-model="scope.row.floorCode"
                        placeholder="请输入"
                        clearable
                        style="width: 100%"
                        :disabled="isReviewedEdit" />
              <span v-else>{{ scope.row.floorCode ?? "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="含税单价(元)"
                           prop="taxInclusiveUnitPrice"
                           min-width="160">
                           min-width="105">
            <template #default="scope">
              <el-input-number v-if="scope.row.__editing"
              <el-input-number :controls="false" v-if="scope.row.__editing"
                               :step="0.01"
                               :min="0"
                               :precision="2"
@@ -761,16 +1428,103 @@
              <span v-else>{{ formattedNumber(null, null, scope.row.taxInclusiveUnitPrice) }}</span>
            </template>
          </el-table-column>
          <el-table-column label="宽(mm)"
                           prop="width"
                           min-width="85">
            <template #default="scope">
              <el-input-number :controls="false" v-if="scope.row.__editing"
                               v-model="scope.row.width"
                               :min="0"
                               :step="1"
                               :precision="2"
                               style="width:100%"
                               placeholder="请输入"
                               clearable
                               @change="() => handleInlineSizeChange(scope.row)"
                               @input="() => handleInlineSizeChange(scope.row)"
                               :disabled="isReviewedEdit" />
              <span v-else>{{ scope.row.width ?? "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="高(mm)"
                           prop="height"
                           min-width="85">
            <template #default="scope">
              <el-input-number :controls="false" v-if="scope.row.__editing"
                               v-model="scope.row.height"
                               :min="0"
                               :step="1"
                               :precision="2"
                               style="width: 100%"
                               placeholder="请输入"
                               clearable
                               @change="() => handleInlineSizeChange(scope.row)"
                               @input="() => handleInlineSizeChange(scope.row)"
                               :disabled="isReviewedEdit" />
              <span v-else>{{ scope.row.height ?? "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="数量"
                           prop="quantity"
                           min-width="85">
            <template #default="scope">
              <el-input-number :controls="false" v-if="scope.row.__editing"
                               v-model="scope.row.quantity"
                               :step="1"
                               :min="0"
                               :precision="0"
                               style="width: 100%"
                               placeholder="请输入"
                               clearable
                               @change="() => handleInlineQuantityChange(scope.row)"
                               @input="() => handleInlineQuantityChange(scope.row)"
                               :disabled="isReviewedEdit" />
              <span v-else>{{ scope.row.quantity ?? "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="结算单片面积(㎡)"
                           prop="settlePieceArea"
                           min-width="120">
            <template #default="scope">
              <el-input-number :controls="false" v-if="scope.row.__editing"
                               v-model="scope.row.settlePieceArea"
                               :min="0"
                               :step="1"
                               :precision="4"
                               style="width: 100%"
                               placeholder="请输入"
                               clearable
                               @change="() => handleInlineSettleAreaChange(scope.row)"
                               :disabled="isReviewedEdit" />
              <span v-else>{{ scope.row.settlePieceArea ? Number(scope.row.settlePieceArea).toFixed(4) : "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="面积(m²)"
                           prop="actualTotalArea"
                           min-width="110">
            <template #default="scope">
              <el-input-number :controls="false" v-if="scope.row.__editing"
                               v-model="scope.row.actualTotalArea"
                               :min="0"
                               :step="1"
                               :precision="4"
                               style="width: 100%"
                               placeholder="自动计算"
                               :disabled="isReviewedEdit" />
              <span v-else>{{ scope.row.actualTotalArea ? Number(scope.row.actualTotalArea).toFixed(4) : "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="税率(%)"
                           prop="taxRate"
                           min-width="120">
                           min-width="80">
            <template #default="scope">
              <el-select v-if="scope.row.__editing"
                         v-model="scope.row.taxRate"
                         placeholder="请选择"
                         clearable
                         style="width: 100%"
                         @change="() => handleInlineTaxRateChange(scope.row)">
                         @change="() => handleInlineTaxRateChange(scope.row)"
                         :disabled="isReviewedEdit">
                <el-option label="1"
                           value="1" />
                <el-option label="3"
@@ -788,20 +1542,35 @@
          <el-table-column label="含税总价(元)"
                           prop="taxInclusiveTotalPrice"
                           :formatter="formattedNumber"
                           min-width="120" />
                           min-width="100" />
          <el-table-column label="不含税总价(元)"
                           prop="taxExclusiveTotalPrice"
                           :formatter="formattedNumber"
                           min-width="120" />
                           min-width="100" />
          <el-table-column label="加工要求"
                           prop="processRequirement"
                           min-width="100"
                           show-overflow-tooltip>
            <template #default="scope">
              <el-input v-if="scope.row.__editing"
                        v-model="scope.row.processRequirement"
                        placeholder="请输入"
                        clearable
                        style="width: 100%"
                        :disabled="isReviewedEdit" />
              <span v-else>{{ scope.row.processRequirement ?? "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="发票类型"
                           prop="invoiceType"
                           min-width="120">
                           min-width="90">
            <template #default="scope">
              <el-select v-if="scope.row.__editing"
                         v-model="scope.row.invoiceType"
                         placeholder="请选择"
                         clearable
                         style="width: 100%">
                         style="width: 100%"
                         :disabled="isReviewedEdit">
                <el-option label="增普票"
                           value="增普票" />
                <el-option label="增专票"
@@ -810,60 +1579,36 @@
              <span v-else>{{ scope.row.invoiceType ?? "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="加工要求"
                           prop="processRequirement"
                           min-width="160"
                           show-overflow-tooltip>
            <template #default="scope">
              <el-input v-if="scope.row.__editing"
                        v-model="scope.row.processRequirement"
                        placeholder="请输入"
                        clearable
                        style="width: 100%" />
              <span v-else>{{ scope.row.processRequirement ?? "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="备注"
                           prop="remark"
                           min-width="140"
                           min-width="100"
                           show-overflow-tooltip>
            <template #default="scope">
              <el-input v-if="scope.row.__editing"
                        v-model="scope.row.remark"
                        placeholder="请输入"
                        clearable
                        style="width: 100%" />
                        style="width: 100%"
                        :disabled="isReviewedEdit" />
              <span v-else>{{ scope.row.remark ?? "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="楼层编号"
                           prop="floorCode"
                           min-width="250"
                           show-overflow-tooltip>
            <template #default="scope">
              <el-input v-if="scope.row.__editing"
                        v-model="scope.row.floorCode"
                        placeholder="请输入"
                        clearable
                        style="width: 100%" />
              <span v-else>{{ scope.row.floorCode ?? "" }}</span>
            </template>
          </el-table-column>
          <el-table-column label="重箱"
                           prop="heavyBox"
                           min-width="100">
                           min-width="80">
            <template #default="scope">
              <el-input v-if="scope.row.__editing"
                        v-model="scope.row.heavyBox"
                        placeholder="请输入"
                        clearable
                        style="width: 100%" />
                        style="width: 100%"
                        :disabled="isReviewedEdit" />
              <span v-else>{{ scope.row.heavyBox ?? "" }}</span>
            </template>
          </el-table-column>
          <el-table-column fixed="right"
                           label="操作"
                           min-width="220"
                           min-width="150"
                           align="center"
                           v-if="operationType !== 'view'">
            <template #default="scope">
@@ -935,7 +1680,7 @@
                              style="max-width: 170px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">
                        {{ item.processName }}
                      </el-tag>
                      <el-input-number v-model="item.quantity"
                      <el-input-number :controls="false" v-model="item.quantity"
                                       :min="0"
                                       :step="1"
                                       :precision="0"
@@ -958,20 +1703,32 @@
                </el-popover>
              </template>
              <template v-else>
                <el-button link
                <!-- 已审核模式:只能修改单价 -->
                <el-button v-if="isReviewedEdit"
                           link
                           type="primary"
                           size="small"
                           :disabled="isProductShipped(scope.row)"
                           @click="editProductInline(scope.row, scope.$index)">
                  编辑
                           @click="editPriceOnly(scope.row)">
                  修改单价
                </el-button>
                <el-button link
                           type="primary"
                           size="small"
                           :disabled="isProductShipped(scope.row) || hasEditingProductRow()"
                           @click="copyProductInline(scope.row, scope.$index)">
                  复制新建
                </el-button>
                <!-- 未审核模式:完整编辑 -->
                <template v-if="!isReviewedEdit">
                  <el-button link
                             type="primary"
                             size="small"
                             :disabled="isProductShipped(scope.row)"
                             @click="editProductInline(scope.row, scope.$index)">
                    编辑
                  </el-button>
                  <el-button link
                             type="primary"
                             size="small"
                             :disabled="isProductShipped(scope.row)"
                             @click="copyProductInline(scope.row, scope.$index)">
                    复制
                  </el-button>
                </template>
                <el-popover :width="560"
                            trigger="click"
                            :hide-after="0"
@@ -993,7 +1750,7 @@
                    <el-button type="primary"
                               plain
                               size="small"
                               :disabled="isProductShipped(scope.row)"
                               :disabled="isProductShipped(scope.row) || isReviewedEdit"
                               @click="startAddOtherAmountForRow(scope.row)">
                      新增
                    </el-button>
@@ -1006,7 +1763,7 @@
                               clearable
                               placeholder="请选择额外加工项目"
                               style="width: 100%;"
                               :disabled="isProductShipped(scope.row)">
                               :disabled="isProductShipped(scope.row) || isReviewedEdit">
                      <el-option v-for="item in otherAmountSelectOptions"
                                 :key="item.id"
                                 :label="item.processName"
@@ -1014,13 +1771,13 @@
                    </el-select>
                    <div style="display:flex; justify-content:flex-end; gap: 8px;">
                      <el-button size="small"
                                 :disabled="isProductShipped(scope.row)"
                                 :disabled="isProductShipped(scope.row) || isReviewedEdit"
                                 @click="scope.row.__inlineOtherAmountAdding = false; scope.row.__inlineOtherAmountAddId = null">
                        取消
                      </el-button>
                      <el-button type="primary"
                                 size="small"
                                 :disabled="isProductShipped(scope.row) || scope.row.__inlineOtherAmountAddId === null || scope.row.__inlineOtherAmountAddId === undefined || scope.row.__inlineOtherAmountAddId === ''"
                                 :disabled="isProductShipped(scope.row) || isReviewedEdit || scope.row.__inlineOtherAmountAddId === null || scope.row.__inlineOtherAmountAddId === undefined || scope.row.__inlineOtherAmountAddId === ''"
                                 @click="confirmAddOtherAmountForRow(scope.row)">
                        确认添加
                      </el-button>
@@ -1035,18 +1792,18 @@
                              style="max-width: 170px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">
                        {{ item.processName }}
                      </el-tag>
                      <el-input-number v-model="item.quantity"
                      <el-input-number :controls="false" v-model="item.quantity"
                                       :min="0"
                                       :step="1"
                                       :precision="0"
                                       style="width: 120px;"
                                       placeholder="数量"
                                       :disabled="operationType === 'view' || isProductShipped(scope.row)"
                                       :disabled="operationType === 'view' || isProductShipped(scope.row) || isReviewedEdit"
                                       @change="handleOtherAmountQuantityChange(scope.row)" />
                      <el-button type="danger"
                                 link
                                 size="small"
                                 :disabled="isProductShipped(scope.row)"
                                 :disabled="isProductShipped(scope.row) || isReviewedEdit"
                                 @click="removeOtherAmountAtForRow(scope.row, idx)">
                        删除
                      </el-button>
@@ -1070,7 +1827,7 @@
                        clearable
                        type="textarea"
                        :rows="2"
                        :disabled="operationType === 'view'" />
                        :disabled="operationType === 'view' || isReviewedEdit" />
            </el-form-item>
          </el-col>
        </el-row>
@@ -1083,7 +1840,7 @@
                        clearable
                        type="textarea"
                        :rows="2"
                        :disabled="operationType === 'view'" />
                        :disabled="operationType === 'view' || isReviewedEdit" />
            </el-form-item>
          </el-col>
        </el-row>
@@ -1102,9 +1859,9 @@
                         :on-success="handleUploadSuccess"
                         :on-remove="handleRemove">
                <el-button type="primary"
                           v-if="operationType !== 'view'">上传</el-button>
                           v-if="operationType !== 'view' || isCompletedOrder">上传</el-button>
                <template #tip
                          v-if="operationType !== 'view'">
                          v-if="operationType !== 'view' || isCompletedOrder">
                  <div class="el-upload__tip">
                    文件格式支持
                    doc,docx,xls,xlsx,ppt,pptx,pdf,txt,xml,jpg,jpeg,png,gif,bmp,rar,zip,7z
@@ -1241,7 +1998,7 @@
          <el-col :span="8">
            <el-form-item label="厚度:"
                          prop="thickness">
              <el-input-number v-model="productForm.thickness"
              <el-input-number :controls="false" v-model="productForm.thickness"
                               :min="0"
                               :step="0.000000000000001"
                               :precision="15"
@@ -1256,7 +2013,7 @@
          <el-col :span="8">
            <el-form-item label="含税单价(元):"
                          prop="taxInclusiveUnitPrice">
              <el-input-number :step="0.01"
              <el-input-number :controls="false" :step="0.01"
                               :min="0"
                               v-model="productForm.taxInclusiveUnitPrice"
                               style="width: 100%"
@@ -1290,7 +2047,7 @@
          <el-col :span="8">
            <el-form-item label="数量:"
                          prop="quantity">
              <el-input-number :step="0.1"
              <el-input-number :controls="false" :step="0.1"
                               :min="0"
                               v-model="productForm.quantity"
                               placeholder="请输入"
@@ -1341,7 +2098,7 @@
          <el-col :span="8">
            <el-form-item label="宽(mm):"
                          prop="width">
              <el-input-number v-model="productForm.width"
              <el-input-number :controls="false" v-model="productForm.width"
                               :min="0"
                               :step="1"
                               :precision="2"
@@ -1354,7 +2111,7 @@
          <el-col :span="8">
            <el-form-item label="高(mm):"
                          prop="height">
              <el-input-number v-model="productForm.height"
              <el-input-number :controls="false" v-model="productForm.height"
                               :min="0"
                               :step="1"
                               :precision="2"
@@ -1367,7 +2124,7 @@
          <el-col :span="8">
            <el-form-item label="周长(cm):"
                          prop="perimeter">
              <el-input-number v-model="productForm.perimeter"
              <el-input-number :controls="false" v-model="productForm.perimeter"
                               :min="0"
                               :step="0.01"
                               :precision="2"
@@ -1383,7 +2140,7 @@
          <el-col :span="8">
            <el-form-item label="实际单片面积(㎡):"
                          prop="actualPieceArea">
              <el-input-number v-model="productForm.actualPieceArea"
              <el-input-number :controls="false" v-model="productForm.actualPieceArea"
                               :min="0"
                               :step="0.0001"
                               :precision="4"
@@ -1396,7 +2153,7 @@
          <el-col :span="8">
            <el-form-item label="实际总面积(㎡):"
                          prop="actualTotalArea">
              <el-input-number v-model="productForm.actualTotalArea"
              <el-input-number :controls="false" v-model="productForm.actualTotalArea"
                               :min="0"
                               :step="0.0001"
                               :precision="4"
@@ -1408,7 +2165,7 @@
          <el-col :span="8">
            <el-form-item label="结算单片面积(㎡):"
                          prop="settlePieceArea">
              <el-input-number v-model="productForm.settlePieceArea"
              <el-input-number :controls="false" v-model="productForm.settlePieceArea"
                               :min="0"
                               :step="0.0001"
                               :precision="4"
@@ -1421,7 +2178,7 @@
          <el-col :span="8">
            <el-form-item label="结算总面积(㎡):"
                          prop="settleTotalArea">
              <el-input-number v-model="productForm.settleTotalArea"
              <el-input-number :controls="false" v-model="productForm.settleTotalArea"
                               :min="0"
                               :step="0.0001"
                               :precision="4"
@@ -1433,7 +2190,7 @@
          <el-col :span="8">
            <el-form-item label="结算总面积(㎡):"
                          prop="settleTotalArea">
              <el-input-number v-model="productForm.settleTotalArea"
              <el-input-number :controls="false" v-model="productForm.settleTotalArea"
                               :min="0"
                               :step="0.0001"
                               :precision="4"
@@ -1516,7 +2273,7 @@
                      </el-tag>
                    </div>
                    <div style="flex: 1;">
                      <el-input-number v-model="item.quantity"
                      <el-input-number :controls="false" v-model="item.quantity"
                                       :min="0"
                                       :step="1"
                                       :precision="0"
@@ -1787,17 +2544,56 @@
        </el-button>
      </div>
    </el-dialog>
    <!-- 反审核弹窗 -->
    <el-dialog v-model="reverseAuditDialogVisible"
               title="反审核确认"
               width="500px"
               :close-on-click-modal="false"
               class="reverse-audit-dialog">
      <el-form label-width="110px"
               label-position="left">
        <el-form-item label="反审核类型">
          <el-radio-group v-model="reverseAuditForm.counterReviewType">
            <el-radio :label="1">
              <span>作废订单</span>
              <span style="color: #909399; font-size: 12px; margin-left: 4px;">(不生成新订单)</span>
            </el-radio>
            <el-radio :label="2">
              <span>重新生成</span>
              <span style="color: #909399; font-size: 12px; margin-left: 4px;">(跳转到新增页面编辑)</span>
            </el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="反审核原因">
          <el-input v-model="reverseAuditForm.counterReviewDesc"
                    type="textarea"
                    :rows="4"
                    placeholder="请输入反审核原因" />
        </el-form-item>
      </el-form>
      <div class="reverse-audit-warning">
        <el-icon style="color: #E6A23C; margin-right: 4px;"><WarningFilled /></el-icon>
        注意:反审核将自动作废该订单对应的所有入库、出库、发货单据
      </div>
      <template #footer>
        <el-button @click="reverseAuditDialogVisible = false">取消</el-button>
        <el-button type="danger"
                   @click="confirmReverseAudit"
                   :disabled="!reverseAuditForm.counterReviewType || !reverseAuditForm.counterReviewDesc.trim()">确认反审核</el-button>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
  import { getToken } from "@/utils/auth";
  import pagination from "@/components/PIMTable/Pagination.vue";
  import { onMounted, ref, getCurrentInstance, watch, nextTick } from "vue";
  import { onMounted, ref, reactive, getCurrentInstance, watch, nextTick, computed } from "vue";
  import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
  import { ElMessageBox, ElMessage } from "element-plus";
  import { ArrowDown } from "@element-plus/icons-vue";
  import { ArrowDown, WarningFilled } from "@element-plus/icons-vue";
  import useUserStore from "@/store/modules/user";
  import useAppStore from "@/store/modules/app";
  import { approveUserList } from "@/api/collaborativeApproval/approvalProcess.js";
  import { userListNoPage } from "@/api/system/user.js";
  import FileListDialog from "@/components/Dialog/FileListDialog.vue";
@@ -1805,6 +2601,7 @@
  import OtherAmountMaintenanceButton from "./components/OtherAmountMaintenanceButton.vue";
  import ProcessFlowMaintenanceButton from "./components/ProcessFlowMaintenanceButton.vue";
  import ProcessFlowConfigSelectDialog from "./components/ProcessFlowConfigSelectDialog.vue";
  import ReverseAuditHistory from "../reverseAuditHistory/index.vue";
  import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
  import {
    ledgerListPage,
@@ -1825,6 +2622,9 @@
    getSalesInvoices,
    getSalesLabel,
    salesStock,
    counterReview,
    markOrderCompleted,
    incrementPrintCount,
  } from "@/api/salesManagement/salesLedger.js";
  import { modelList, productTreeList } from "@/api/basicData/product.js";
  import useFormData from "@/hooks/useFormData.js";
@@ -1835,14 +2635,18 @@
  import { printSalesDeliveryNote } from "./components/salesDeliveryPrint.js";
  import { printSalesLabel } from "./components/salesLabelPrint.js";
  import QRCode from "qrcode";
  import { useRoute, useRouter } from "vue-router";
  // import { salesLedgerProductSetProcessFlowConfig } from "@/api/salesManagement/salesProcessFlowConfig.js";
  const userStore = useUserStore();
  const { proxy } = getCurrentInstance();
  const route = useRoute();
  const router = useRouter();
  const tableData = ref([]);
  const productData = ref([]);
  const selectedRows = ref([]);
  const productSelectedRows = ref([]);
  const pinnedProductTemplate = ref(null);
  const userList = ref([]);
  const userListApprove = ref([]);
  const customerOption = ref([]);
@@ -1855,11 +2659,13 @@
  });
  const total = ref(0);
  const fileList = ref([]);
  const processRouteExportDateRange = ref([]);
  // 工艺路线配置选择弹窗(绑定到台账产品)
  const processFlowSelectDialogVisible = ref(false);
  const processFlowSelectLedgerRow = ref(null);
  const processFlowSelectDefaultRouteId = ref(null);
  const processFlowSelectDefaultRecordList = ref([]);
  const processFlowSelectBoundRouteId = ref(null);
  const processFlowSelectBoundRouteName = ref("");
@@ -1882,6 +2688,41 @@
  const ledgerQrDialogVisible = ref(false);
  const ledgerQrCompositeUrl = ref("");
  const ledgerQrDownloadBaseName = ref("");
  const pendingAddPrefillDetail = ref(null);
  const pageMode = computed(() => String(route.query.mode || ""));
  const isFormPageMode = computed(() =>
    pageMode.value === "add" || pageMode.value === "edit"
  );
  const pageFormTitle = computed(() =>
    pageMode.value === "edit" ? "编辑销售台账" : "新增销售台账"
  );
  const pageFormSubtitle = computed(() =>
    pageMode.value === "edit"
      ? "编辑完成后将自动返回销售台账列表"
      : "新增完成后将自动返回销售台账列表"
  );
  const appStore = useAppStore();
  watch(isFormPageMode, (val) => {
    if (val) {
      appStore.closeSideBar({ withoutAnimation: false });
    } else {
      if (!appStore.sidebar.opened) {
        appStore.toggleSideBar(false);
      }
    }
  });
  onMounted(() => {
    if (isFormPageMode.value) {
      appStore.closeSideBar({ withoutAnimation: false });
    }
  });
  import { onUnmounted } from "vue";
  onUnmounted(() => {
    if (!appStore.sidebar.opened) {
      appStore.toggleSideBar(false);
    }
  });
  const sanitizeLedgerQrFilename = s =>
    String(s)
@@ -1931,9 +2772,14 @@
            const ctx = canvas.getContext("2d");
            canvas.width = Math.max(QR_SIZE + horizontalPad * 2, 280);
            ctx.font = `${fontSize}px "Microsoft YaHei", "PingFang SC", sans-serif`;
            const lines = wrapLedgerQrTextLines(ctx, label, canvas.width - horizontalPad * 2);
            const lines = wrapLedgerQrTextLines(
              ctx,
              label,
              canvas.width - horizontalPad * 2
            );
            const textBlockHeight = lines.length * lineHeight;
            canvas.height = padTop + QR_SIZE + gapAfterQr + textBlockHeight + bottomPad;
            canvas.height =
              padTop + QR_SIZE + gapAfterQr + textBlockHeight + bottomPad;
            ctx.fillStyle = "#ffffff";
            ctx.fillRect(0, 0, canvas.width, canvas.height);
@@ -1989,6 +2835,10 @@
  // 用户信息表单弹框数据
  const operationType = ref("");
  const dialogFormVisible = ref(false);
  // 已完成订单标记:view 模式但附件上传仍可用
  const isCompletedOrder = ref(false);
  // 已审核订单编辑模式:只能修改单价,其他字段禁用
  const isReviewedEdit = ref(false);
  const data = reactive({
    searchForm: {
      customerName: "", // 客户名称
@@ -1999,8 +2849,10 @@
      entryDate: null, // 录入日期
      entryDateStart: undefined,
      entryDateEnd: undefined,
      deliveryStatus: undefined, // 发货状态:1未发货 2审批中 3审批失败 4已发货
      deliveryStatus: undefined, // 发货状态:1未发货 2审批中 3审批不通过 4审批通过 5已发货 6部分发货
      stockStatus: undefined, // 入库状态:0未入库 1部分入库 2已入库
      reviewStatus: undefined, // 审核状态:0待审核 1已审核 2已反审
      orderStatus: undefined, // 订单状态:0进行中 1已完成
    },
    form: {
      salesContractNo: "",
@@ -2012,6 +2864,8 @@
      maintenanceTime: "",
      productData: [],
      executionDate: "",
      reviewStatus: undefined,
      stockStatus: undefined,
    },
    rules: {
      salesman: [{ required: true, message: "请选择", trigger: "change" }],
@@ -2140,16 +2994,56 @@
    return (productData.value || []).some(r => r && r.__editing);
  };
  const buildEmptyInlineProductRow = () => ({
  const isPlaceholderRowDirty = row => {
    if (!row || !row.__placeholder) return false;
    const fieldsToCheck = [
      "width",
      "height",
      "quantity",
      "settlePieceArea",
      "taxInclusiveUnitPrice",
      "taxRate",
      "invoiceType",
      "floorCode",
      "processRequirement",
      "remark",
      "heavyBox",
    ];
    return fieldsToCheck.some(key => {
      const value = row[key];
      return value !== null && value !== undefined && value !== "";
    });
  };
  const getPlaceholderRowIndex = () =>
    (productData.value || []).findIndex(r => r && r.__placeholder);
  const discardPlaceholderRowIfPristine = () => {
    const index = getPlaceholderRowIndex();
    if (index === -1) return true;
    const row = productData.value[index];
    if (isPlaceholderRowDirty(row)) {
      proxy.$modal.msgWarning("请先保存或取消当前待录入行");
      return false;
    }
    productData.value.splice(index, 1);
    if (editingProductRow.value === row) {
      editingProductRow.value = null;
    }
    return true;
  };
  const buildEmptyInlineProductRow = (prefill = {}) => ({
    id: null,
    __tempKey: `__temp_${Date.now()}_${Math.random().toString(16).slice(2)}`,
    __editing: true,
    __isNew: true,
    __productCategoryId: null,
    productCategory: "",
    productModelId: null,
    specificationModel: "",
    thickness: null,
    __placeholder: true,
    __productCategoryId: prefill.__productCategoryId ?? null,
    productCategory: prefill.productCategory ?? "",
    productModelId: prefill.productModelId ?? null,
    specificationModel: prefill.specificationModel ?? "",
    thickness: prefill.thickness ?? null,
    quantity: null,
    taxInclusiveUnitPrice: null,
    taxRate: "",
@@ -2171,19 +3065,96 @@
    heavyBox: "",
  });
  const getPinnedProductPrefill = async () => {
    await getProductOptions();
    if (!pinnedProductTemplate.value) {
      const models = await modelList({});
      modelOptions.value = models || [];
      return {};
    }
    if (pinnedProductTemplate.value.__productCategoryId) {
      const models = await modelList({
        id: pinnedProductTemplate.value.__productCategoryId,
      });
      modelOptions.value = models || [];
    } else {
      const models = await modelList({});
      modelOptions.value = models || [];
    }
    return { ...pinnedProductTemplate.value };
  };
  const appendEditablePlaceholderRow = async () => {
    if (operationType.value === "view" || isReviewedEdit.value) return;
    const existingPlaceholder = (productData.value || []).find(
      r => r && r.__placeholder
    );
    if (existingPlaceholder) {
      if (!existingPlaceholder.__editing) existingPlaceholder.__editing = true;
      editingProductRow.value = existingPlaceholder;
      productForm.value = existingPlaceholder;
      return;
    }
    if (hasEditingProductRow()) return;
    await getProductOptions();
    await fetchOtherAmountSelectOptions(true);
    const prefill = await getPinnedProductPrefill();
    const row = buildEmptyInlineProductRow(prefill);
    productData.value.push(row);
    editingProductRow.value = row;
    productForm.value = row;
  };
  const pinSelectedProductRow = async () => {
    if (operationType.value === "view" || isReviewedEdit.value) return;
    if (!productSelectedRows.value || productSelectedRows.value.length !== 1) {
      proxy.$modal.msgWarning("请选择一条产品数据进行固定");
      return;
    }
    const selectedRow = productSelectedRows.value[0];
    const categoryId =
      selectedRow.__productCategoryId ??
      findNodeIdByLabel(productOptions.value, selectedRow.productCategory) ??
      null;
    if (!selectedRow.productCategory || !selectedRow.specificationModel) {
      proxy.$modal.msgWarning("请先选择完整的产品大类和规格型号再固定");
      return;
    }
    if (!categoryId || !selectedRow.productModelId) {
      proxy.$modal.msgWarning("请先保存当前产品后再固定");
      return;
    }
    pinnedProductTemplate.value = {
      __productCategoryId: categoryId,
      productCategory: selectedRow.productCategory ?? "",
      productModelId: selectedRow.productModelId ?? null,
      specificationModel: selectedRow.specificationModel ?? "",
      thickness:
        selectedRow.thickness !== null &&
        selectedRow.thickness !== undefined &&
        selectedRow.thickness !== ""
          ? Number(selectedRow.thickness)
          : null,
    };
    proxy.$modal.msgSuccess("固定成功,后续会自动带出该产品和规格型号");
    const editingRow = (productData.value || []).find(r => r?.__editing);
    if (
      editingRow &&
      !editingRow.productCategory &&
      !editingRow.productModelId &&
      !editingRow.specificationModel
    ) {
      Object.assign(editingRow, await getPinnedProductPrefill());
    }
  };
  const addProductInline = async () => {
    if (operationType.value === "view") return;
    if (hasEditingProductRow()) {
      proxy.$modal.msgWarning("请先保存或取消当前编辑行");
      return;
    }
    await getProductOptions();
    await fetchOtherAmountSelectOptions(true);
    const row = buildEmptyInlineProductRow();
    productData.value.push(row);
    editingProductRow.value = row;
    // 让现有的计算/其他金额逻辑复用当前行
    productForm.value = row;
    await appendEditablePlaceholderRow();
  };
  const copyProductInline = async row => {
@@ -2193,14 +3164,19 @@
      proxy.$modal.msgWarning("已发货或审核通过的产品不能复制");
      return;
    }
    if (hasEditingProductRow()) {
    const hasBlockingEditingRow = (productData.value || []).some(
      item => item && item.__editing && !item.__placeholder
    );
    if (hasBlockingEditingRow) {
      proxy.$modal.msgWarning("请先保存或取消当前编辑行");
      return;
    }
    if (!discardPlaceholderRowIfPristine()) return;
    await getProductOptions();
    await fetchOtherAmountSelectOptions(true);
    const copied = buildEmptyInlineProductRow();
    copied.__placeholder = false;
    copied.__productCategoryId =
      row.__productCategoryId ??
      findNodeIdByLabel(productOptions.value, row.productCategory) ??
@@ -2209,13 +3185,22 @@
    copied.productModelId = row.productModelId ?? null;
    copied.specificationModel = row.specificationModel ?? "";
    copied.thickness =
      row.thickness !== null && row.thickness !== undefined && row.thickness !== ""
      row.thickness !== null &&
      row.thickness !== undefined &&
      row.thickness !== ""
        ? Number(row.thickness)
        : null;
    copied.floorCode = row?.floorCode ?? row?.floor_code ?? "";
    // 复制新建仅带出产品大类与规格型号,其他数字字段全部留空,避免出现 0.00
    const srcUnit = row?.taxInclusiveUnitPrice;
    const unitNum =
      srcUnit !== null && srcUnit !== undefined && srcUnit !== ""
        ? Number(srcUnit)
        : NaN;
    copied.taxInclusiveUnitPrice = Number.isFinite(unitNum) ? unitNum : null;
    // 复制新建带出:产品大类、规格型号、厚度、楼层编号、单价;其余数量/面积/总价等留空,避免出现 0.00
    copied.quantity = null;
    copied.taxInclusiveUnitPrice = null;
    copied.taxInclusiveTotalPrice = null;
    copied.taxExclusiveTotalPrice = null;
    copied.width = null;
@@ -2245,6 +3230,15 @@
    productForm.value = copied;
  };
  /** 已审核订单:仅修改含税单价 */
  const editPriceOnly = (row) => {
    if (operationType.value === "view") return;
    if (!row) return;
    stopOtherEditingRows();
    row.__editing = true;
    row.__priceOnly = true; // 标记只修改单价
  };
  const editProductInline = async (row, index) => {
    if (operationType.value === "view") return;
    if (!row) return;
@@ -2252,6 +3246,7 @@
      proxy.$modal.msgWarning("已发货或审核通过的产品不能编辑");
      return;
    }
    if (!discardPlaceholderRowIfPristine()) return;
    stopOtherEditingRows();
    await getProductOptions();
    await fetchOtherAmountSelectOptions(true);
@@ -2339,10 +3334,6 @@
      proxy.$modal.msgWarning("面积必须大于0");
      return false;
    }
    if (row.taxInclusiveUnitPrice <= 0) {
      proxy.$modal.msgWarning("含税单价必须大于0");
      return false;
    }
    if (!row.productModelId) {
      proxy.$modal.msgWarning("请选择规格型号");
      return false;
@@ -2399,11 +3390,13 @@
    if (model?.model) row.specificationModel = model.model;
    if (operationType.value === "edit") {
      row.__placeholder = false;
      // 台账已存在:走原接口保存到后端,再回拉刷新
      const payload = { ...row, salesLedgerId: currentId.value, type: 1 };
      delete payload.__backup;
      delete payload.__editing;
      delete payload.__isNew;
      delete payload.__placeholder;
      delete payload.__productCategoryId;
      delete payload.__tempKey;
      await addOrUpdateSalesLedgerProduct(payload);
@@ -2413,19 +3406,22 @@
          productData.value = res.productData;
        }
      );
      stopOtherEditingRows();
      await appendEditablePlaceholderRow();
    } else {
      // 新增台账:仅在本地 productData 生效,最终随台账一起提交
      row.__isNew = false;
      row.__placeholder = false;
      row.__editing = false;
      delete row.__backup;
      stopOtherEditingRows();
      await appendEditablePlaceholderRow();
    }
    stopOtherEditingRows();
  };
  const cancelProductInline = (row, index) => {
  const cancelProductInline = async (row, index) => {
    if (!row) return;
    if (row.__isNew) {
    if (row.__placeholder) {
      productData.value.splice(index, 1);
    } else if (row.__backup) {
      const restored = JSON.parse(JSON.stringify(row.__backup));
@@ -2435,9 +3431,11 @@
      Object.assign(row, restored);
      row.id = keepId;
      row.__editing = false;
      row.__placeholder = false;
      delete row.__backup;
    }
    stopOtherEditingRows();
    await appendEditablePlaceholderRow();
  };
  const openOtherAmountInline = async row => {
@@ -2908,7 +3906,62 @@
    notShipped: "/sales/ledger/salesHistory/notShippingImport",
    shipped: "/sales/ledger/salesHistory/shippingImport",
  };
  const HISTORY_IMPORT_TEMPLATE_URL_MAP = {
    notShipped: "/sales/ledger/salesHistory/notShippingImportTemplate",
    shipped: "/sales/ledger/salesHistory/shippingImportTemplate",
  };
  const HISTORY_IMPORT_TEMPLATE_FILE_NAME_MAP = {
    notShipped: "销售发货历史数据导入模板-未发货.xlsx",
    shipped: "销售发货历史数据导入模板-已发货.xlsx",
  };
  const currentImportCommand = ref("default");
  const activeStatusTab = ref("all");
  const salesLedgerStatusTabs = [
    { key: "all", label: "全部" },
    { key: "pendingReview", label: "未审核" },
    { key: "reviewed", label: "已审核" },
    { key: "reverseReviewed", label: "反审核" },
    { key: "stocked", label: "已入库" },
    { key: "delivered", label: "已发货" },
    { key: "completed", label: "已完成" },
  ];
  const resetStatusFilters = () => {
    searchForm.reviewStatus = undefined;
    searchForm.stockStatus = undefined;
    searchForm.deliveryStatus = undefined;
    searchForm.orderStatus = undefined;
  };
  const handleStatusTabChange = tabKey => {
    activeStatusTab.value = tabKey;
    resetStatusFilters();
    switch (tabKey) {
      case "all":
        break;
      case "pendingReview":
        searchForm.reviewStatus = 0;
        break;
      case "reviewed":
        searchForm.reviewStatus = 1;
        break;
      case "reverseReviewed":
        searchForm.reviewStatus = 2;
        break;
      case "stocked":
        searchForm.stockStatus = 2;
        break;
      case "delivered":
        searchForm.deliveryStatus = 5;
        break;
      case "completed":
        searchForm.orderStatus = 1;
        break;
      default:
        break;
    }
    handleQuery();
  };
  const changeDaterange = value => {
    if (value) {
      searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
@@ -2918,6 +3971,43 @@
      searchForm.entryDateEnd = undefined;
    }
    handleQuery();
  };
  /** 批量按钮禁用判断:根据选中行的审核状态和订单状态控制按钮可用性
   *  未审核(0):只能审核、删除、编辑
   *  已审核(1):可以反审、入库、发货、导出、打印、工艺路线
   *  已完成(orderStatus=1):所有操作按钮禁用
   *  未选中任何行时所有批量按钮禁用
   */
  const isBatchButtonDisabled = (action) => {
    if (selectedRows.value.length === 0) return true;
    const hasCompleted = selectedRows.value.some(r => Number(r.orderStatus) === 1);
    // 已完成订单:所有操作按钮禁用
    if (hasCompleted && action !== 'markCompleted') return true;
    const statuses = selectedRows.value.map(r => Number(r.reviewStatus));
    const allUnreviewed = statuses.every(s => s === 0);
    const allReviewed = statuses.every(s => s === 1);
    switch (action) {
      case 'audit':
        return !allUnreviewed;
      case 'reverseAudit':
        return !allReviewed;
      case 'stock':
        return !allReviewed;
      case 'delivery':
        return !allReviewed;
      case 'export':
        return !allReviewed;
      case 'delete':
        return !allUnreviewed;
      case 'print':
        return !allReviewed;
      case 'markCompleted':
        // 只有已审核且未完成的订单才能标记完成
        return !allReviewed || hasCompleted;
      default:
        return false;
    }
  };
  // 查询列表
@@ -2931,6 +4021,168 @@
    expandedRowKeys.value = [];
    getList();
  };
  /** 审核按钮操作 */
  const handleAudit = async () => {
    if (selectedRows.value.length === 0) {
      proxy.$modal.msgWarning("请选择要审核的数据");
      return;
    }
    const canNotAudit = selectedRows.value.filter(
      row => Number(row.reviewStatus) !== 0
    );
    if (canNotAudit.length > 0) {
      proxy.$modal.msgWarning("选中的数据中包含非待审核项,请重新选择");
      return;
    }
    // 录入人不能审核该条数据
    const isEntryPerson = selectedRows.value.some(
      row => String(row.entryPerson) === String(userStore.id)
    );
    if (isEntryPerson) {
      proxy.$modal.msgWarning("录入人不能审核自己提交的数据");
      return;
    }
    try {
      await ElMessageBox.confirm("是否确认审核选中的销售台账?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      });
      for (const row of selectedRows.value) {
        await addOrUpdateSalesLedger({ ...row, reviewStatus: 1 });
      }
      proxy.$modal.msgSuccess("审核成功");
      getList();
    } catch (error) {
      console.log(error);
    }
  };
  /** 反审核弹窗状态 */
  const reverseAuditDialogVisible = ref(false);
  const reverseAuditForm = reactive({
    counterReviewType: null,
    counterReviewDesc: "",
  });
  /** 反审按钮操作 — 打开弹窗 */
  const handleReverseAudit = () => {
    if (selectedRows.value.length === 0) {
      proxy.$modal.msgWarning("请选择要反审核的数据");
      return;
    }
    const canNotReverse = selectedRows.value.filter(
      row => Number(row.reviewStatus) !== 1
    );
    if (canNotReverse.length > 0) {
      proxy.$modal.msgWarning("选中的数据中包含非已审核项,请重新选择");
      return;
    }
    // 重置弹窗表单
    reverseAuditForm.counterReviewType = null;
    reverseAuditForm.counterReviewDesc = "";
    reverseAuditDialogVisible.value = true;
  };
  /** 反审核确认操作 */
  const confirmReverseAudit = async () => {
    if (!reverseAuditForm.counterReviewType) {
      proxy.$modal.msgWarning("请选择反审核类型");
      return;
    }
    if (!reverseAuditForm.counterReviewDesc.trim()) {
      proxy.$modal.msgWarning("请输入反审核原因");
      return;
    }
    try {
      const ids = selectedRows.value.map(row => row.id);
      const res = await counterReview({
        ids,
        counterReviewType: reverseAuditForm.counterReviewType,
        counterReviewDesc: reverseAuditForm.counterReviewDesc,
      });
      reverseAuditDialogVisible.value = false;
      proxy.$modal.msgSuccess("反审核成功");
      // 重新生成类型:跳转到新增台账页面(预填数据)
      if (reverseAuditForm.counterReviewType === 2 && res.newLedgerIds && res.newLedgerIds.length > 0) {
        // 单条反审时跳转到新增页面编辑新台账
        if (res.newLedgerIds.length === 1) {
          const newId = res.newLedgerIds[0];
          getSalesLedgerWithProducts({ id: newId, type: 1 }).then(detail => {
            enterAddPage(detail);
          });
        }
      }
      getList();
    } catch (error) {
      console.log(error);
    }
  };
  /** 标记完成操作 */
  const handleMarkCompleted = async () => {
    if (selectedRows.value.length === 0) {
      proxy.$modal.msgWarning("请选择要标记完成的数据");
      return;
    }
    const cannotComplete = selectedRows.value.filter(
      row => Number(row.reviewStatus) !== 1 || Number(row.orderStatus) === 1
    );
    if (cannotComplete.length > 0) {
      proxy.$modal.msgWarning("选中的数据中包含非已审核或已完成的项,请重新选择");
      return;
    }
    try {
      await ElMessageBox.confirm(
        "标记完成后订单将变为只读,只能查看和上传下载附件,不可撤销。是否确认?",
        "提示",
        { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning" }
      );
      const ids = selectedRows.value.map(row => row.id);
      await markOrderCompleted({ ids });
      proxy.$modal.msgSuccess("标记完成成功");
      getList();
    } catch {
      // 用户取消
    }
  };
  /** 用预填数据打开新增台账页面(重新生成场景) */
  const openFormWithPreFill = async (detail, keepPageMode = false) => {
    operationType.value = "add";
    form.value = {};
    productData.value = [];
    selectedQuotation.value = null;
    fileList.value = [];
    pinnedProductTemplate.value = null;
    let userLists = await userListNoPage();
    userList.value = userLists.data;
    customerList().then(res => {
      customerOption.value = res;
    });
    // 预填原台账数据到新增表单
    form.value.customerId = detail.customerId;
    form.value.customerName = detail.customerName;
    form.value.projectName = detail.projectName;
    form.value.salesman = detail.salesman;
    form.value.entryPerson = Number(userStore.id);
    form.value.entryDate = getCurrentDate();
    form.value.executionDate = detail.executionDate || getCurrentDate();
    form.value.deliveryDate = detail.deliveryDate;
    form.value.paymentMethod = detail.paymentMethod;
    form.value.contractAmount = detail.contractAmount;
    form.value.remarks = detail.remarks;
    form.value.customerRemarks = detail.customerRemarks ?? detail.customer_remarks ?? "";
    productData.value = detail.productData || [];
    form.value.deliveryDate = dayjs(form.value.entryDate).add(7, "day").format("YYYY-MM-DD");
    await appendEditablePlaceholderRow();
    dialogFormVisible.value = !keepPageMode;
  };
  const paginationChange = obj => {
    page.current = obj.page;
    page.size = obj.limit;
@@ -2940,7 +4192,7 @@
    tableLoading.value = true;
    const { entryDate, ...rest } = searchForm;
    // 将范围日期字段传递给后端
    const params = { ...rest, ...page };
    const params = { ...rest, ...page, reviewStatusList: [0, 1, 2] };
    // 移除录入日期的默认值设置,只保留范围日期字段
    delete params.entryDate;
    // 查询客户名称与新增保持一致:先选 customerId,再映射为 customerName 查询
@@ -2958,15 +4210,13 @@
        delete params.customerName;
      }
    }
    const widthValue =
      params.width != null ? String(params.width).trim() : "";
    const widthValue = params.width != null ? String(params.width).trim() : "";
    if (widthValue) {
      params.width = widthValue;
    } else {
      delete params.width;
    }
    const heightValue =
      params.height != null ? String(params.height).trim() : "";
    const heightValue = params.height != null ? String(params.height).trim() : "";
    if (heightValue) {
      params.height = heightValue;
    } else {
@@ -3011,6 +4261,10 @@
      return;
    }
    const row = selectedRows.value[0] || {};
    if (Number(row.reviewStatus) !== 1) {
      ElMessage.warning("只有已审核的台账才能进行入库操作");
      return;
    }
    const id = row?.id;
    if (!id) {
      ElMessage.warning("所选数据缺少id,无法入库");
@@ -3040,7 +4294,9 @@
      const res = await productList({ salesLedgerId: id, type: 1 });
      stockProductList.value = [];
      stockProductList.value =
        res.data.filter(item => item.productStockStatus == 0 || item.productStockStatus == 1) || [];
        res.data.filter(
          item => item.productStockStatus == 0 || item.productStockStatus == 1
        ) || [];
    } catch (e) {
      proxy?.$modal?.msgError?.("获取产品或审批人失败");
    } finally {
@@ -3071,9 +4327,16 @@
    proxy?.$modal?.loading?.("正在入库,请稍候...");
    try {
      const approveUserIds = stockApproverNodes.value.map(node => node.userId).join(",");
      const approveUserIds = stockApproverNodes.value
        .map(node => node.userId)
        .join(",");
      const approveUserName = stockApproverNodes.value
        .map(node => stockApproverOptions.value.find(item => String(item.userId) === String(node.userId))?.userName)
        .map(
          node =>
            stockApproverOptions.value.find(
              item => String(item.userId) === String(node.userId)
            )?.userName
        )
        .filter(Boolean)
        .join(",");
      await salesStock({
@@ -3095,10 +4358,15 @@
  // 打开“工艺路线配置”选择弹窗(必须显式选择)
  const openProcessFlowSelect = async ledgerRow => {
    if (!ledgerRow) return;
    if (!ledgerRow.isEdit) return;
    if (Number(ledgerRow.reviewStatus) !== 1) {
      proxy.$modal.msgWarning("只有已审核的台账才能选择工艺路线");
      return;
    }
    // if (!ledgerRow.isEdit) return;
    processFlowSelectLedgerRow.value = ledgerRow;
    processFlowSelectDefaultRouteId.value = null;
    processFlowSelectDefaultRecordList.value = [];
    processFlowSelectBoundRouteId.value = null;
    processFlowSelectBoundRouteName.value = "";
@@ -3108,25 +4376,29 @@
      const boundId = info?.processRouteId ?? info?.routeId ?? info?.id ?? null;
      const boundName =
        info?.processRouteName ?? info?.routeName ?? info?.name ?? "";
      const recordList = Array.isArray(info?.recordList) ? info.recordList : [];
      processFlowSelectBoundRouteId.value = boundId;
      processFlowSelectBoundRouteName.value = boundName;
      processFlowSelectDefaultRouteId.value = boundId;
      processFlowSelectDefaultRecordList.value = recordList;
    } catch (e) {
      // 查询失败时按未绑定处理,不阻塞弹窗
      processFlowSelectBoundRouteId.value = null;
      processFlowSelectBoundRouteName.value = "";
      processFlowSelectDefaultRouteId.value = null;
      processFlowSelectDefaultRecordList.value = [];
    }
    processFlowSelectDialogVisible.value = true;
  };
  // 绑定工艺路线到当前台账数据
  const handleProcessFlowSelectConfirm = async routeId => {
  const handleProcessFlowSelectConfirm = async payload => {
    const ledgerRow = processFlowSelectLedgerRow.value;
    if (!ledgerRow?.id) return;
    const finalRouteId = routeId ?? null;
    const finalRouteId = payload?.routeId ?? payload ?? null;
    const recordList = Array.isArray(payload?.recordList) ? payload.recordList : [];
    if (!finalRouteId) return;
    const oldRouteId = processFlowSelectBoundRouteId.value;
@@ -3156,6 +4428,7 @@
      await saleProcessBind({
        salesLedgerId: ledgerRow.id,
        processRouteId: finalRouteId,
        recordList,
      });
      proxy?.$modal?.msgSuccess?.("工艺路线绑定成功");
@@ -3238,20 +4511,30 @@
  };
  // 获取tree子数据
  const getModels = value => {
    // 产品大类变化时,重置规格型号与厚度,避免旧值残留
    productForm.value.productModelId = null;
    productForm.value.specificationModel = "";
    productForm.value.thickness = null;
    if (!value) {
      productForm.value.productCategory = "";
      modelOptions.value = [];
      modelList({}).then(res => {
        modelOptions.value = res || [];
      });
      return;
    }
    productForm.value.productCategory = findNodeById(productOptions.value, value);
    modelList({ id: value }).then(res => {
      modelOptions.value = res || [];
      const currentModelId = productForm.value.productModelId;
      if (currentModelId) {
        const isValid = modelOptions.value.some(item => item.id === currentModelId);
        if (!isValid) {
          productForm.value.productModelId = null;
          productForm.value.specificationModel = "";
          productForm.value.thickness = null;
        }
      } else {
        productForm.value.productModelId = null;
        productForm.value.specificationModel = "";
        productForm.value.thickness = null;
      }
    });
  };
  const getProductModel = value => {
@@ -3270,6 +4553,12 @@
        modelThickness === ""
          ? null
          : Number(modelThickness);
      const categoryId = selectedModel?.productId;
      if (categoryId && productForm.value.__productCategoryId !== categoryId) {
        productForm.value.__productCategoryId = categoryId;
        productForm.value.productCategory = findNodeById(productOptions.value, categoryId);
      }
    } else {
      productForm.value.specificationModel = null;
      productForm.value.thickness = null;
@@ -3389,12 +4678,130 @@
      "taxExclusiveTotalPrice",
    ]);
  };
  const summarizeProductTable = param => {
    return proxy.summarizeTable(param, [
      "quantity",
      "settlePieceArea",
      "actualTotalArea",
      "taxInclusiveTotalPrice",
      "taxExclusiveTotalPrice",
    ]);
  };
  const initAddFormState = async () => {
    operationType.value = "add";
    isCompletedOrder.value = false;
    isReviewedEdit.value = false;
    form.value = {};
    productData.value = [];
    fileList.value = [];
    selectedQuotation.value = null;
    pinnedProductTemplate.value = null;
    const userLists = await userListNoPage();
    userList.value = userLists.data;
    customerList().then(res => {
      customerOption.value = res;
    });
    form.value.entryPerson = userStore.id;
    form.value.entryDate = getCurrentDate();
    form.value.executionDate = getCurrentDate();
    form.value.customerRemarks = "";
    form.value.deliveryDate = dayjs(form.value.entryDate)
      .add(7, "day")
      .format("YYYY-MM-DD");
    await appendEditablePlaceholderRow();
  };
  const initEditFormState = async rowId => {
    operationType.value = "edit";
    isCompletedOrder.value = false;
    form.value = {};
    productData.value = [];
    fileList.value = [];
    selectedQuotation.value = null;
    pinnedProductTemplate.value = null;
    const userLists = await userListNoPage();
    userList.value = userLists.data;
    customerList().then(res => {
      customerOption.value = res;
    });
    currentId.value = rowId;
    const res = await getSalesLedgerWithProducts({ id: rowId, type: 1 });
    form.value = { ...res };
    form.value.entryPerson = Number(res.entryPerson);
    form.value.customerRemarks =
      res?.customerRemarks ?? res?.customer_remarks ?? "";
    productData.value = form.value.productData || [];
    fileList.value = form.value.salesLedgerFiles || [];
    isReviewedEdit.value = Number(res?.reviewStatus) === 1;
    await appendEditablePlaceholderRow();
  };
  const enterAddPage = async detail => {
    pendingAddPrefillDetail.value = detail || null;
    const query = { ...route.query, mode: "add" };
    await router.push({ path: route.path, query });
  };
  const enterEditPage = async row => {
    const query = { ...route.query, mode: "edit", id: row?.id };
    await router.push({ path: route.path, query });
  };
  const exitFormPage = async (shouldRefresh = false) => {
    const query = { ...route.query };
    delete query.mode;
    delete query.id;
    pendingAddPrefillDetail.value = null;
    await router.push({ path: route.path, query });
    closeDia(false);
    if (shouldRefresh) {
      getList();
    }
  };
  watch(
    pageMode,
    async enabled => {
      if (enabled === "add") {
        await initAddFormState();
        if (pendingAddPrefillDetail.value) {
          await openFormWithPreFill(pendingAddPrefillDetail.value, true);
          pendingAddPrefillDetail.value = null;
        }
        return;
      }
      if (enabled === "edit" && route.query.id) {
        await initEditFormState(route.query.id);
      }
    },
    { immediate: true }
  );
  // 打开弹框
  const openForm = async (type, row) => {
    operationType.value = type;
    if (type === "add") {
      await enterAddPage();
      return;
    }
    if (type === "edit") {
      await enterEditPage(row);
      return;
    }
    // 已完成订单强制为只读模式,但附件上传仍可用
    const isCompleted = Number(row?.orderStatus) === 1;
    const effectiveType = isCompleted ? 'view' : type;
    operationType.value = effectiveType;
    isCompletedOrder.value = isCompleted;
    form.value = {};
    productData.value = [];
    selectedQuotation.value = null;
    // 已审核订单编辑时,标记只能修改单价(已完成订单已强制view,此处不会再命中)
    isReviewedEdit.value = effectiveType === "edit" && Number(row?.reviewStatus) === 1;
    let userLists = await userListNoPage();
    userList.value = userLists.data;
    customerList().then(res => {
@@ -3598,18 +5005,21 @@
        console.log("productData.value--", productData.value);
        // 行内编辑未保存时不允许提交,避免脏数据/临时字段进入后端
        const hasEditingRow = (productData.value || []).some(
          r => r && r.__editing
          r => r && r.__editing && !r.__placeholder
        );
        if (hasEditingRow) {
          proxy.$modal.msgWarning("产品信息存在未保存的编辑行,请先保存或取消");
          return;
        }
        if (productData.value !== null && productData.value.length > 0) {
          const cleanedProducts = (productData.value || []).map(p => {
          const cleanedProducts = (productData.value || [])
            .filter(p => p && !p.__placeholder)
            .map(p => {
            if (!p || typeof p !== "object") return p;
            const {
              __editing,
              __isNew,
              __placeholder,
              __backup,
              __productCategoryId,
              __tempKey,
@@ -3620,6 +5030,10 @@
            rest.quantity = Number(rest.quantity ?? 0) || 0;
            return rest;
          });
          if (cleanedProducts.length === 0) {
            proxy.$modal.msgWarning("请添加产品信息");
            return;
          }
          form.value.productData = proxy.HaveJson(cleanedProducts);
        } else {
          proxy.$modal.msgWarning("请添加产品信息");
@@ -3631,10 +5045,16 @@
        }
        form.value.tempFileIds = tempFileIds;
        form.value.type = 1;
        form.value.reviewStatus = form.value.reviewStatus ?? 0; // 默认审核状态为待审核
        form.value.stockStatus = 0; // 默认入库状态为未入库
        const submitPayload = { ...form.value };
        delete submitPayload.paymentMethod;
        addOrUpdateSalesLedger(submitPayload).then(res => {
          proxy.$modal.msgSuccess("提交成功");
          if (isFormPageMode.value) {
            exitFormPage(true);
            return;
          }
          closeDia();
          getList();
        });
@@ -3642,9 +5062,16 @@
    });
  };
  // 关闭弹框
  const closeDia = () => {
    proxy.resetForm("formRef");
  const closeDia = (resetFormRef = true) => {
    if (resetFormRef) {
      proxy.resetForm("formRef");
    }
    dialogFormVisible.value = false;
    isCompletedOrder.value = false;
    isReviewedEdit.value = false;
    if (!isFormPageMode.value) {
      fileList.value = [];
    }
  };
  const productIndex = ref(0);
@@ -3831,10 +5258,35 @@
          productData.value.splice(index, 1);
        }
      });
      appendEditablePlaceholderRow();
    } else {
      const placeholderRows = productSelectedRows.value.filter(
        item => item?.__placeholder
      );
      if (placeholderRows.length > 0) {
        placeholderRows.forEach(selectedRow => {
          const index = productData.value.findIndex(product => {
            if (!product || !selectedRow) return false;
            return (
              product.__tempKey &&
              selectedRow.__tempKey &&
              String(product.__tempKey) === String(selectedRow.__tempKey)
            );
          });
          if (index !== -1) {
            productData.value.splice(index, 1);
          }
        });
        appendEditablePlaceholderRow();
      }
      let ids = [];
      if (productSelectedRows.value.length > 0) {
        ids = productSelectedRows.value.map(item => item.id);
      const persistedRows = productSelectedRows.value.filter(
        item => !item?.__placeholder && item?.id !== null && item?.id !== undefined
      );
      if (persistedRows.length > 0) {
        ids = persistedRows.map(item => item.id);
      } else {
        return;
      }
      ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", {
        confirmButtonText: "确认",
@@ -3875,18 +5327,33 @@
  };
  // 导入
  const handleImport = () => {
    currentImportCommand.value = "default";
    openImportDialog("导入销售台账", "/sales/ledger/import");
  };
  // 历史迁移
  const handleHistoryImportCommand = command => {
    const url = HISTORY_IMPORT_URL_MAP[command];
    if (!url) return;
    const title = command === "shipped" ? "历史迁移-已发货" : "历史迁移-未发货";
    currentImportCommand.value = command;
    const title = command === "shipped" ? "历史迁移-已出库" : "历史迁移-未出库";
    openImportDialog(title, url);
  };
  // 下载导入模板
  const downloadTemplate = () => {
    const command = currentImportCommand.value;
    if (command && command !== "default") {
      const templateUrl = HISTORY_IMPORT_TEMPLATE_URL_MAP[command];
      const fileName = HISTORY_IMPORT_TEMPLATE_FILE_NAME_MAP[command];
      if (templateUrl) {
        proxy.download(
          templateUrl,
          {},
          fileName || "销售发货历史数据导入模板.xlsx"
        );
        return;
      }
    }
    proxy.download("/sales/ledger/exportTemplate", {}, "销售台账导入模板.xlsx");
  };
  const onClose = () => {
@@ -3902,19 +5369,75 @@
    proxy.$refs["importUploadRef"].submit();
  };
  // 导出
  // 导出(按当前查询条件导出)
  const handleOut = () => {
    ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        proxy.download("/sales/ledger/export", {}, "销售台账.xlsx");
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
    // 构建查询参数(与 getList 保持一致)
    const { entryDate, ...rest } = searchForm;
    const params = { ...rest };
    // 处理录入日期范围
    if (entryDate && entryDate.length === 2) {
      params.entryDateStart = entryDate[0];
      params.entryDateEnd = entryDate[1];
    }
    // 处理客户名称查询
    const selectedCustomer = (customerOption.value || []).find(
      item => String(item?.id ?? "") === String(params.customerId ?? "")
    );
    if (selectedCustomer?.customerName) {
      params.customerName = String(selectedCustomer.customerName).trim();
    }
    delete params.customerId;
    // 处理产品宽高查询参数
    const widthValue = params.width != null ? String(params.width).trim() : "";
    const heightValue = params.height != null ? String(params.height).trim() : "";
    if (!widthValue) delete params.width;
    if (!heightValue) delete params.height;
    proxy.download("/sales/ledger/exportWithProducts", params, "销售台账.xlsx");
  };
  const exportProcessRouteDialogVisible = ref(false);
  const handleExportProcessRoute = () => {
    if (selectedRows.value.length === 0) {
      proxy?.$modal?.msgWarning?.("请选择要导出的销售台账");
      return;
    }
    const salesLedgerIds = selectedRows.value
      .map(item => item.id)
      .filter(id => id !== null && id !== undefined && id !== "");
    if (salesLedgerIds.length === 0) {
      proxy?.$modal?.msgWarning?.("请选择要导出的销售台账");
      return;
    }
    exportProcessRouteDialogVisible.value = true;
  };
  const confirmExportProcessRoute = () => {
    const salesLedgerIds = selectedRows.value
      .map(item => item.id)
      .filter(id => id !== null && id !== undefined && id !== "");
    const params = {
      salesLedgerIds: salesLedgerIds.join(","),
    };
    if (
      Array.isArray(processRouteExportDateRange.value) &&
      processRouteExportDateRange.value.length === 2
    ) {
      params.completedTimeStart = processRouteExportDateRange.value[0];
      params.completedTimeEnd = processRouteExportDateRange.value[1];
    }
    proxy.download(
      "/sales/ledger/exportProcessRoute",
      params,
      "销售台账工艺路线导出.xlsx"
    );
    exportProcessRouteDialogVisible.value = false;
  };
  /** 判断单个产品是否已发货(根据shippingStatus判断,已发货或审核通过不可编辑和删除) */
  const isProductShipped = product => {
@@ -3945,6 +5468,15 @@
      return;
    }
    const ids = selectedRows.value.map(item => item.id);
    // 检查是否有已审核的台账
    const audited = selectedRows.value.filter(
      row => Number(row.reviewStatus) === 1
    );
    if (audited.length > 0) {
      proxy.$modal.msgWarning("选中的数据中包含已审核项,不能删除");
      return;
    }
    // 检查是否有已进行发货或发货完成的销售订单,若有则不允许删除
    const cannotDeleteNames = [];
@@ -3993,11 +5525,20 @@
      command !== "salesDeliveryNote"
    )
      return;
    if (selectedRows.value.length === 0) {
      proxy.$modal.msgWarning("请至少选择一条销售台账数据进行打印");
      return;
    }
    const hasUnapproved = selectedRows.value.some(
      row => Number(row.reviewStatus) !== 1
    );
    if (hasUnapproved) {
      proxy.$modal.msgWarning("选中的数据中包含未审核项,无法打印");
      return;
    }
    if (command === "salesDeliveryNote") {
      if (selectedRows.value.length === 0) {
        proxy.$modal.msgWarning("请至少选择一条销售台账数据进行打印");
        return;
      }
      const customerNames = Array.from(
        new Set(
          selectedRows.value.map(item => String(item?.customerName ?? "").trim())
@@ -4033,6 +5574,10 @@
        const res = await getSalesInvoices(selectedIds);
        const salesInvoiceData = res?.data ?? {};
        await printSalesDeliveryNote(salesInvoiceData, selectedRow, selectedIds);
        // 打印成功后递增单据打印次数
        selectedIds.forEach(id => {
          incrementPrintCount({ id, printType: 'document' }).catch(() => {});
        });
      } catch (error) {
        console.error("打印销售发货单失败:", error);
        proxy.$modal.msgError("打印失败,请稍后重试");
@@ -4058,12 +5603,15 @@
        const res = await getSalesOrder(selectedId);
        const salesOrderData = res?.data ?? {};
        printSalesOrder(salesOrderData);
        // 打印成功后递增单据打印次数
        incrementPrintCount({ id: selectedId, printType: 'document' }).catch(() => {});
      } else {
        const res = await getProcessCard(selectedId);
        const processCardData = res?.data ?? {};
        // 补齐二维码所需的台账标识(后端数据有时不带 id)
        if (processCardData && typeof processCardData === "object") {
          processCardData.salesLedgerId = processCardData.salesLedgerId ?? selectedId;
          processCardData.salesLedgerId =
            processCardData.salesLedgerId ?? selectedId;
          processCardData.salesContractNo =
            (processCardData.salesContractNo ?? "").trim() ||
            String(selectedRow?.salesContractNo ?? "").trim();
@@ -4087,8 +5635,12 @@
            return;
          }
          await printFinishedProcessCard(processCardData);
          // 打印成功后递增单据打印次数
          incrementPrintCount({ id: selectedId, printType: 'document' }).catch(() => {});
        } else {
          await printFinishedProcessCard(processCardData);
          // 打印成功后递增单据打印次数
          incrementPrintCount({ id: selectedId, printType: 'document' }).catch(() => {});
        }
      }
    } catch (error) {
@@ -4112,7 +5664,12 @@
      return;
    }
    const selectedId = selectedRows.value[0]?.id;
    const selectedRow = selectedRows.value[0];
    if (Number(selectedRow?.reviewStatus) !== 1) {
      proxy.$modal.msgWarning("只有已审核的台账才能进行标签打印");
      return;
    }
    const selectedId = selectedRow?.id;
    if (!selectedId) {
      proxy.$modal.msgWarning("当前选择数据缺少ID,无法打印标签");
      return;
@@ -4127,6 +5684,8 @@
        return;
      }
      printSalesLabel(labelList);
      // 打印成功后递增标签打印次数
      incrementPrintCount({ id: selectedId, printType: 'label' }).catch(() => {});
    } catch (error) {
      console.error("打印标签失败:", error);
      proxy.$modal.msgError("打印标签失败,请稍后重试");
@@ -4481,15 +6040,15 @@
      return false;
    }
    // 如果后端返回了台账级发货状态(deliveryStatus)
    // 1=已发货,则禁止再次发货
    // 台账级发货状态(deliveryStatus):2审批中、5已发货 时不可再发起本行发货;6部分发货仍可按明细继续发
    const deliveryStatus = row.deliveryStatus;
    if (
      deliveryStatus !== null &&
      deliveryStatus !== undefined &&
      String(deliveryStatus).trim() !== ""
    ) {
      if (Number(deliveryStatus) === 1) return false;
      const ds = Number(deliveryStatus);
      if (ds === 2 || ds === 5) return false;
    }
    // 获取发货状态
@@ -4545,12 +6104,15 @@
      return;
    }
    // 只允许【未发货/审批失败】进入发货流程
    // 允许:1未发货、3审批不通过、4审批通过、6部分发货;不允许:2审批中、5已发货
    const statusItem = selectedRows.value[0].deliveryStatus;
    const ledgerAllowsDelivery = s => [1, 3, 4, 6].includes(Number(s));
    let isTrue = true;
    selectedRows.value.forEach(row => {
      if (row.deliveryStatus != 1 && row.deliveryStatus != 3) {
        proxy.$modal.msgWarning("仅未发货或审批失败的台账可以发货");
      if (!ledgerAllowsDelivery(row.deliveryStatus)) {
        proxy.$modal.msgWarning(
          "仅未发货、审批不通过、审批通过或部分发货的台账可以发货"
        );
        isTrue = false;
        return;
      }
@@ -4587,9 +6149,9 @@
      return;
    }
    // 已发货台账:弹窗提醒,不能再次发货(4 视为已发货)
    // 已全部发货(5)的台账:弹窗提醒,不能再次发货
    const shippedLedgers = selectedRows.value.filter(
      r => Number(r.deliveryStatus) === 4
      r => Number(r.deliveryStatus) === 5
    );
    if (shippedLedgers.length === selectedRows.value.length) {
      try {
@@ -4646,9 +6208,9 @@
    try {
      const targets = [];
      for (const ledger of selectedRows.value) {
        //如果已经是“审批中(2)”或“已发货(4)”,则跳过,不允许重复操作
        // 审批中(2)、已全部发货(5) 跳过;部分发货(6) 等仍收集可发明细
        const status = Number(ledger.deliveryStatus);
        if (status === 2 || status === 4) {
        if (status === 2 || status === 5) {
          console.warn(
            `台账编号 ${ledger.salesContractNo} 状态为 ${status},跳过发货`
          );
@@ -4704,10 +6266,11 @@
  // 打开发货弹框(单条)
  const openDeliveryForm = async row => {
    // 只允许【未发货/审批失败】发货;已发货/审批中不允许
    const status = Number(row.deliveryStatus);
    if (status !== 1 && status !== 3) {
      proxy.$modal.msgWarning("只有发货状态为未发货或审批失败的记录才可以发货");
    if (![1, 3, 4, 6].includes(status)) {
      proxy.$modal.msgWarning(
        "只有发货状态为未发货、审批不通过、审批通过或部分发货的记录才可以发货"
      );
      return;
    }
@@ -4770,6 +6333,7 @@
        const run = async () => {
          for (const salesLedgerId of uniqueLedgerIds) {
            await addShippingInfo({
              scanOutbound: false,
              salesLedgerId,
              type: deliveryForm.value.type,
              approveUserIds,
@@ -4822,7 +6386,7 @@
    currentFactoryName.value = res.user.currentFactoryName;
  };
  onMounted(() => {
    getList();
    handleStatusTabChange(activeStatusTab.value);
    customerList().then(res => {
      customerOption.value = res;
    });
@@ -4872,10 +6436,163 @@
    margin-top: unset;
  }
  .sales-ledger-status-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 12px 14px;
    margin-bottom: 14px;
    background: linear-gradient(180deg, #f9fbff 0%, #f2f6ff 100%);
    border: 1px solid #dbe6ff;
    border-radius: 12px;
  }
  .sales-ledger-status-tab {
    min-width: 88px;
    height: 34px;
    padding: 0 14px;
    border: 1px solid #d7def0;
    border-radius: 9px;
    background: #fff;
    color: #4b5567;
    font-size: 13px;
    cursor: pointer;
    transition: all 0.18s ease;
  }
  .sales-ledger-status-tab:hover {
    border-color: #8fb3ff;
    color: #1d4ed8;
  }
  .sales-ledger-status-tab.is-active {
    border-color: #1d4ed8;
    background: linear-gradient(135deg, #2f67f6 0%, #1d4ed8 100%);
    color: #fff;
    box-shadow: 0 8px 18px rgba(29, 78, 216, 0.16);
  }
  .actions {
    display: flex;
    justify-content: space-between;
    margin-bottom: 10px;
  }
  .sales-ledger-toolbar {
    align-items: flex-start;
    gap: 14px;
    padding: 10px 12px;
    background: #fff;
    border: 1px solid #e7edf7;
    border-radius: 12px;
  }
  .sales-ledger-toolbar-actions {
    display: flex;
    flex: 1;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 10px;
  }
  .sales-ledger-toolbar-group {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 4px;
    background: #f7f9fc;
    border: 1px solid #edf1f7;
    border-radius: 10px;
  }
  .sales-ledger-toolbar-group--muted {
    background: #fbfcfe;
  }
  .sales-ledger-page-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
    margin-bottom: 16px;
  }
  .sales-ledger-page-header-content {
    flex: 1;
  }
  .sales-ledger-page-title {
    font-size: 22px;
    font-weight: 600;
    color: #303133;
    line-height: 1.3;
  }
  .sales-ledger-page-back {
    flex-shrink: 0;
  }
  .sales-ledger-page-subtitle {
    margin-top: 6px;
    font-size: 13px;
    color: #909399;
  }
  .sales-ledger-page-form {
    padding: 20px;
    background: #fff;
    border-radius: 8px;
  }
  .sales-ledger-page-actions {
    display: flex;
    justify-content: center;
    gap: 16px;
    margin-top: 24px;
  }
  .compact-product-table {
    :deep(.el-table__cell) {
      padding: 4px 0;
      font-size: 12px;
    }
    :deep(.cell) {
      line-height: 1.2;
    }
    :deep(.el-input__wrapper) {
      padding: 0 8px;
    }
    :deep(.el-input-number .el-input__wrapper) {
      padding-left: 8px;
      padding-right: 8px;
    }
    :deep(.el-input-number),
    :deep(.el-select),
    :deep(.el-input),
    :deep(.el-tree-select) {
      font-size: 12px;
    }
    :deep(.el-input-number .el-input__inner) {
      height: 28px;
      font-size: 12px;
      text-align: left;
    }
    :deep(.el-select .el-input__inner),
    :deep(.el-input .el-input__inner) {
      height: 28px;
    }
    :deep(.el-button--small),
    :deep(.el-button.is-link) {
      font-size: 12px;
      padding: 2px 4px;
    }
  }
  .ledger-qr-dialog {
@@ -4939,8 +6656,45 @@
  }
  @media (max-width: 768px) {
    .sales-ledger-status-tab {
      min-width: unset;
      flex: 1 1 calc(50% - 8px);
    }
    .sales-ledger-toolbar,
    .sales-ledger-page-header {
      flex-direction: column;
      align-items: stretch;
    }
    .sales-ledger-toolbar-actions {
      width: 100%;
      justify-content: flex-start;
    }
    .approver-node-item {
      flex: 0 0 100%;
    }
  }
  .reverse-audit-warning {
    display: flex;
    align-items: flex-start;
    padding: 10px 12px;
    margin-top: 8px;
    background-color: #fdf6ec;
    border: 1px solid #faecd8;
    border-radius: 4px;
    color: #e6a23c;
    font-size: 13px;
    line-height: 1.6;
  }
  .reverse-audit-dialog .el-radio {
    display: flex;
    align-items: center;
    height: 36px;
    margin-right: 0;
    margin-bottom: 8px;
  }
</style>